SO - Alto nivel.

Para "abobrinhas" use o " Boteco"

Moderadores: andre_luis, 51, guest2003, Renie

SO - Alto nivel.

Mensagempor fabim » 04 Fev 2011 07:09

Pessoal. Comprei o livro sobre linux que me foi indicado aqui no forum, e ja estou na pagina 93.
Entrando nos sites indicados, lendo sobre outras coisas, e dislumbrado sobre coisas que eu nem sonhava que existiam.
Me aprofundei em um site que encontrei e comecei a ler sobre SO LINUX,e BINARIO.

Em um uC, se eu fizer um programa para uma dada aplicação. Onde este eu sei que pelo pragma eu disse que rom começava no endereço 0x00ff. O montador vai assimilar e gerar o asm/hex substituindo labels e tals, por endereços baseando que o ofset é 0x00ff....
Se eu por acaso gravar este hex no endereço 0x00f0, ja fodeu todo o sistema.

Agora em um sistema operativo, como o SO ou no caso o kernel do linux trava um bin ? lembrando que o local onde ele carrega os bins de programas é dinamico.

Eu imagino que.: Existe um disassembly, este mesmo disassembly faz uma conversão de endereços nas chamadas e labels conhecidas, ja que este kernel ou SO ja sabe onde vai começar o programa na memoria RAM.

Eu imagino 2.: Que os bins são como se fossem rotinas, e no final da dita existe o comando return. O que é passado então para o SO ou o task mananger é apenas um endereço desta rotina, onde esta não possui CALL´S apenas execução em maquina de estados.

Eu imagino 3.: Que só disse m****, e não tem nada haver o que eu disse com o que realmente acontece !!

Se alguém puder me dar mais este impurrão sobre como funciona isto, eu juro que não solto mais nenhum peido aqui na sala;
Mano, ve só.
Sou responsável pelo que escrevo!!! E não pelo que você entende !!!
fabim
Dword
 
Mensagens: 5001
Registrado em: 16 Out 2006 10:18
Localização: aqui uái!!!?

Mensagempor polesapart » 04 Fev 2011 08:50

Seguinte:


O processo de linkedição de um binário *dinâmico* (o padrão no linux) é um processo complicadinho.

Em primeiro lugar, o formato do executável do linux é o ELF. O ELF é um formato bastante versátil, cheio de cabeçalhos, não é simplesmente um arquivo binário que o sistema carrega pra memória e manda ver.

A linkedição de um binário dinâmico ocorre em duas etapas: quando você compila um programa e faz a linkedição final pra gerar o arquivo elf, o que na verdade ocorre é que o linker agrupa os arquivos objeto e gera o arquivo binário, mas não coloca junto as bibliotecas. Ao invés disto, ele cria uma secção no arquivo ELF contendo os nomes dos símbolos não resolvidos e cria as chamadas tabelas de relocação, que podemos pensar que são tabelas de ponteiros para símbolos, que fazem referência aquela outra tabela de nomes.

Feito isto tudo e mais umas coisinhas, está completa a primeira etapa da linkedição, e você tem o seu executável com todo o código compilado, exceto as dependências dinâmicas, que via de regra são as bibliotecas (a própria libc é uma). Nada te impediria também de linkar bibliotecas estáticas, neste caso elas são agregadas ao executável, normalmente, como ocorreria em qualquer linker que você já trabalhou antes. Dá até pra passar a opção -static para o linker, e aí ele degenera em um linker burrinho que não faz nenhuma dessas mágicas e gera um arquivo ELF que pra todos os efeitos é quase tão tapado quanto um .bin (ok, tou exagerando, mas só um pouco).

A segunda etapa ocorre em tempo de execução: quando você decide executar o arquivo elf que você criou, o que acaba ocorrendo é que o shell (ou outro processo qualquer ao qual voce deu a ordem para que execute o programa) faz um fork() de si mesmo, criando um processo filho, e este processo filho faz um exec() contra o executável que você forneceu (isto tem a ver com o fato de, no unix, todo processo ter um processo pai, a excessão do init, mas isto está fora do contexto aqui. No ruindows é diferente, no ruindows um processo manda o kernel criar um novo processo e ele faz isso sozinho).

O que ocorre é que a chamada de sistema exec() faz com que o processo filho seja "limpo", ou seja, na prática é como se fosse um novo processo, e então o kernel substitui a imagem do processo por aquela do arquivo executável que foi passado como parametro pro exec.

Pra fazer esta última etapa, o kernel, que é espertinho, olha o cabeçalho do arquivo e descobre que é um arquivo ELF dinâmico. O kernel não sabe carregar um arquivo ELF dinâmico sozinho, então no próprio arquivo ELF existe um secção que aponta para um programa auxiliar, o dynamic linker. É um simples texto com o caminho do executável, geramente /lib/ld-linux.so.2 ou algo que o valha.

O kernel então carrega este /lib/ld-linux.so.2 , que é um executável ELF estático, para uma área de memória que é sempre alocada inicialmente.

Mas onde fica esta área de memória? Fisicamente, não importa: cada processo no linux usa endereçamento virtual de memória, então o processo pensa que tem (quase) todo o espaço de endereçamento de 4GB (32 bits) pra ele.

O kernel então executa o código nesta área de memória. O dynamic linker então começa a sua brincadeira: ele começa a escarafunchar os cabeçalhos do arquivo ELF e a carregar secções para a memória. Como existe apenas uma área de memória inicialmente alocada pelo kernel, o que o dynamic linker faz é criar novas, e setar suas propriedades, usando a chamada de sistema mmap() (neste ponto, se fosse um executável estático, o kernel estaria fazendo esta etapa sozinho).

Então quando ele achou uma secção de dados somente leitura, ele a carrega para a memória e marca seus atributos como área com permissão apenas de leitura. Quando acha uma secção de código executável, ele marca como permissão para leitura e execução, e assim por diante, sendo que certas áreas de dados terão permissão pra gravação. Se o teu programa, quando for executar, desrespeitar estas permissões, o kernel dará um chute no traseiro dele, mandando um sinal SIGSEGV ou equivalente, e terminando o processo.

Mas teu programa não tá pronto pra executar ainda. O dynamic linker descobre que existem dependências para bibliotecas dinamicas, entao o que ele faz é ir atrás do arquivo mencionado no cabeçalho do teu arquivo ELF, por exemplo, procurando o nome libc.so.6 num pequeno banco de dados que ele possui, e achando o arquivo /lib/libc-2.3.2.so como sendo o responsavel por prover este nome, e então o dynamic linker faz a carga desta biblioteca para uma área da memória, e aí descobre que esta biblioteca tem dependencias para outras, e vai fazendo o processo recursivamente, até resolver todas as pendencias.

Durante este processo, ele analisa o teu programa, consultando a secção de relocações não resolvidas, e descobre que os símbolos que o teu programa precisa são providos por certas bibliotecas, e assim sucessivamente, colocando nas tabelas de relocações ponteiros para os endereços onde ele carregou os símbolos das bibliotecas.

Basicamente, ele fez boa parte do que o linker estático varia em tempo de linkedição, e tem que fazer tudo isso pra cada ELF dinâmico que for carregado.

Mas em que endereço da memória virtual ele carregas as bibliotecas? geralmente, ele vai alocando os endereços a medida em que carrega as bibliotecas, sendo que eles podem até ser de certa forma randomizados.

O mapa de endereços alocados ao teu executável costuma ser fixo, mas as bibliotecas podem ir parar em faixas de memória diferentes, razão pela qual em certas arquiteturas, elas precisam ser compiladas com a opção PIC (position-independent code), de modo que endereços absolutos não sejam usados diretamente.

Existem algumas sutilezas neste processo, mas em linhas gerais, é isso.
Warning: time of day goes back (-163479us), taking countermeasures. :)
Avatar do usuário
polesapart
Byte
 
Mensagens: 477
Registrado em: 19 Nov 2007 12:56
Localização: Curitiba

Mensagempor xultz » 04 Fev 2011 10:27

Se alguém por acaso se assustou com o tamanho do texto que o Alex escreveu acima, é normal ele fazer esse tipo de explicação e com esse tamanho... no MSN.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor polesapart » 04 Fev 2011 10:43

xultz escreveu:Se alguém por acaso se assustou com o tamanho do texto que o Alex escreveu acima, é normal ele fazer esse tipo de explicação e com esse tamanho... no MSN.


:oops:
Warning: time of day goes back (-163479us), taking countermeasures. :)
Avatar do usuário
polesapart
Byte
 
Mensagens: 477
Registrado em: 19 Nov 2007 12:56
Localização: Curitiba

Mensagempor polesapart » 04 Fev 2011 10:48

Xultz, OFF-TOPIC: Tou indo pro salto morato amanhã, bora? :P
Warning: time of day goes back (-163479us), taking countermeasures. :)
Avatar do usuário
polesapart
Byte
 
Mensagens: 477
Registrado em: 19 Nov 2007 12:56
Localização: Curitiba

Mensagempor xultz » 04 Fev 2011 12:00

Poha, amanhã? Eu vou domingo! Amanhã tenho curso o dia inteiro e não posso faltar, dá prá remarcar prá domingo não?
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor polesapart » 04 Fev 2011 12:39

Vou mandar uma mensagem particular pra matar esse off-topic, lê aí..
Warning: time of day goes back (-163479us), taking countermeasures. :)
Avatar do usuário
polesapart
Byte
 
Mensagens: 477
Registrado em: 19 Nov 2007 12:56
Localização: Curitiba

Mensagempor mastk » 04 Fev 2011 12:53

polesapart, um cara F*****, caga grosso :shock:
Avatar do usuário
mastk
Dword
 
Mensagens: 4407
Registrado em: 14 Out 2006 20:43

Mensagempor polesapart » 04 Fev 2011 14:14

mastk, eu sei (sei?) que isso é um elogio, mas dói só de pensar hahahaha :D
Warning: time of day goes back (-163479us), taking countermeasures. :)
Avatar do usuário
polesapart
Byte
 
Mensagens: 477
Registrado em: 19 Nov 2007 12:56
Localização: Curitiba

Mensagempor msamsoniuk » 04 Fev 2011 17:11

o alex resumiu em poucas palavras o que eu iria passar o fim de semana escrevendo! :D
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor polesapart » 04 Fev 2011 22:25

Dá pra acrescentar mais umas coisinhas ...

Quando eu disse que ele carrega pra memória, na verdade ele faz o mmap() do arquivo, as páginas ("pedaços") de todos os arquivos ELF, até mesmo do próprio executável, só vão realmente ser carregados pra memória quando forem lidos ou executados pela primeira vez (afinal, quem gosta de trabalhar a toa são os vírus do windows!). Por padrão a página tem tamanho de 4kbytes, mas isto varia de arquitetura pra arquitetura.

Tendo dito isto, podemos entrar no "por que ele faz essa putaria toda? não seria mais fácil linkeditar tudo estaticamente"?

Seria, mas não seria tão eficiente, do ponto de vista do uso de recursos: não é a toa que no unix as bibliotecas dinâmicas são apelidadas de DSOs, que é a sigla pra Dynamic *shared* objects: quando a libc por exemplo é carregada, as páginas de memória fisica que efetivamente forem carregadas pra memória poderão ser compartilhadas por todos os processos: se vc tem 1000 processos, ao invés de ter mil cópias de printf(), getpid(), fork(), exec(), motherfucker() (ok essa última eu inventei), etc., você acaba tendo só uma.

Isto ocorre pq supersimplificando, o sistema de memória virtual consiste numa tabela que faz a translação entre endereços físicos e virtuais. Um endereço virtual num processo pode ser bem diferente do outro, e apontar pra mesma página de memória física. O linux inclusive implementa um mecanismo chamado copy-on-write: se dois processos fizeram mmap() da mesma origem (um arquivo por exemplo), as páginas na memória que se referem a esta origem serão compartilhadas (leia-se: serão a mesma página de memória física efetivamente alocada) até que um dos processo "suje" a página, tentando gravar nela: quando isto ocorre, o kernel recebe uma excessão (como se fosse um aviso: tem um mané tentando gravar nesta página ae meu!), cria uma nova página, copia o conteúdo da original nela, e muda o mapeamento fisico <-> virtual de modo que o processo que tentou gravar agora enxerga, transparentemente, a nova página. Então o kernel libera a permissão de gravação na nova página e tudo acontece transparentemente: o processo que gravou enxerga a página alterada, os demais continuam enxergando a página original, antiga.

Isto é bastante eficiente pois minimiza o uso de memória física (já que a memória virtual, como o próprio nome diz, não existe efetivamente), e otimiza uma série de procedimentos que precisam ler dados com muito mais frequencia do que gravar, e ainda assim, a sobrecarga de gravação (edição, na verdade, quando a página já contem dados), é bem pequena.

Existem alguns mais avançados, por exemplo, páginas somente-leitura mapeadas de algum arquivo (inclusive os trechos de código dos programas executáveis) podem ser descartadas se o sistema estiver com pouca memória, e recarregadas mais tarde quando houver uma tentativa de ler/executar, etc.
Warning: time of day goes back (-163479us), taking countermeasures. :)
Avatar do usuário
polesapart
Byte
 
Mensagens: 477
Registrado em: 19 Nov 2007 12:56
Localização: Curitiba

Mensagempor Renie » 04 Fev 2011 23:35

Olá pessoALL,

Depois da aula do Alex (poleapart), penso que este tópico poderia
ficar fixo, se os participantes não se opuserem, vou consultar a
"cúpula do trovão", e as palavras de baixo calão serão editadas, ok?

[]'s
Renie
Renie
Word
 
Mensagens: 732
Registrado em: 11 Out 2006 22:35
Localização: RJ - Niterói - Brasil

Mensagempor enigmabox » 05 Fev 2011 06:43

Pra mim tá ótimo, este conhecimento não pode ser disperdiçado, já já o Alex (poleapart) vai estar escrevendo aqui um livro.....mas eu vou estar lendo!!! :D
enigmabox
 

Mensagempor polesapart » 05 Fev 2011 09:17

Renie escreveu:e as palavras de baixo calão serão editadas, ok?



**** que pariu! Nem vi que tinha falado palavrões! Sem problemas! :D
Warning: time of day goes back (-163479us), taking countermeasures. :)
Avatar do usuário
polesapart
Byte
 
Mensagens: 477
Registrado em: 19 Nov 2007 12:56
Localização: Curitiba

Mensagempor msamsoniuk » 05 Fev 2011 12:43

fabim: recomendo voce ler os cinco livros do tanenbaum:

http://www.few.vu.nl/~ast/

ateh o linus torvalds leu os livros dele para fazer o linux! :D
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Próximo

Voltar para Assuntos Gerais

Quem está online

Usuários navegando neste fórum: Google [Bot] e 1 visitante

x