1 / 22

Laboratório de Organização e Arquitetura de Computadores

Laboratório de Organização e Arquitetura de Computadores. Segmentação (Conceitos Básicos). PROFESSORES: Elmar Uwe Kurt Melcher Joseana Macêdo Fechine.

yoko-moran
Download Presentation

Laboratório de Organização e Arquitetura de Computadores

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Laboratório de Organização e Arquitetura de Computadores Segmentação (Conceitos Básicos) PROFESSORES: Elmar Uwe Kurt Melcher Joseana Macêdo Fechine

  2. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ #define VIDEOSEL 0x1000 /*** struct and type declarations ***/ typedef unsigned char byte; typedef unsigned short word; typedef unsigned int dword; /* endereco segmentado (endereco logico) */ struct segaddr { void *addr; word selector; }; typedef struct segaddr *segaddr_ptr; // tornar um seletor um indice da tabela de descritores de segmentos #define segidx(selector) (selector>>3)

  3. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ /* descritor de segmento. Cada sub-estrutura serve para preencher uma parte dos campos do descritor. Devem ser usados na sequencia a, b, c.*/ union segment { /* Nenhum dos itens na, nb deve ser usado. */ struct { // COLOCO BASE E LIMITE OS DEMAIS FICAM ERRADO dword limit; dword base; } a; struct { word na; dword base; } b;

  4. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ struct { //CONSERTA O TYPE E O BIT SIZE dword na; byte nb; byte type; byte bitsize; } c; }; typedef union segment *segment_ptr;

  5. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ /* IDTR e GDTR */ struct dtr { word length; union { gate_ptr g; segment_ptr s; } base; };

  6. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ // Tem quase tudo que tem dentro do do processador //FUNCAO: salvar o contexto do processador struct tss { /* itens na ate nk sao reservados */ word link, na; dword esp0; word ss0, nb; dword esp1; word ss1, nc; dword esp2; word ss2, nd; dword cr3; //da paginacao dword eip; //PC dword eflags; //PSW dword eax, ecx, edx, ebx; dword esp, ebp; dword esi, edi;

  7. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ word es, ne; //Descritores word cs, nf; word ss, ng; word ds, nh; word fs, ni; word gs, nj; word ldtr, nk; word t; word iopb; }; typedef struct tss *tss_ptr;

  8. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ /*** declaracoes de variaveis globais ***/ /* interrupt table e global descriptor table */ struct dtr idtr, gdtr; /* rotina especial para prencher o segmento de video */ void descVideo() { dword *desc = (dword *)(gdtr.base.s + segidx(VIDEOSEL)); desc[1] = 0xE04BF200; // base = 0xE0000000, limit=BFFFFh=1024*768-1<>1M desc[0] = 0x0000FFFF; // tipo = 0xF2, dpl=3, read/write }

  9. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ /* carregar um arquivo executavel */ void carregar(char *exename) { FILE *exefile; // cabecalho do execut vel static struct { dword datasize, codesize, varsize, stacksize; } header; if((exefile=fopen(exename,"rb"))==NULL) { fprintf(stderr,"Executavel %s ausente.\n", exename); exit(1); } if(fread(&header, sizeof(header), 1, exefile)!=1) { fprintf(stderr,"Nao consigo ler o cabecalho do executavel.\n"); exit(1); }

  10. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ //Preenchendo o descritor(seletor) de dados constantes gdtr.base.s[segidx(0x1048)].a.limit = header.datasize-1; //o limite esta  no cabecalho -1 pois comeca em 0 gdtr.base.s[segidx(0x1048)].a.base = 0x01989866; //a base do segmento a, um endereco gostoso gdtr.base.s[segidx(0x1048)].b.base = 0x01989866; //a base do segmento a, um endereco gostoso gdtr.base.s[segidx(0x1048)].c.type = 0xF0; // dpl=usuario, permite so leitura gdtr.base.s[segidx(0x1048)].c.bitsize = 0x40; // do descritor 32 bits

  11. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ //Preenchendo o descritor(seletor) de codigo gdtr.base.s[segidx(0x1050)].a.limit = header.codesize-1; //o codesize est  no cabecalho, -1 pois comeca em 0 gdtr.base.s[segidx(0x1050)].a.base = 0x01AA9866; //a base do segmento a, o max ‚ FFFFFFF... gdtr.base.s[segidx(0x1050)].b.base = 0x01AA9866; //a base do segmento a, o max ‚ FFFFFFF... gdtr.base.s[segidx(0x1050)].c.type = // 0x98; // dpl = S.O., permite execucao 0xF8; // dpl=usuario, permite execucao gdtr.base.s[segidx(0x1050)].c.bitsize = 0x40;

  12. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ //Preenchendo o descritor(seletor) de variaveis gdtr.base.s[segidx(0x1058)].a.limit = header.varsize-1; //o limite est  no cabecalho, -1 pois comeca em 0 gdtr.base.s[segidx(0x1058)].a.base = 0x01BB9866; //a base do segmento a, o max ‚ FFFFFFF... gdtr.base.s[segidx(0x1058)].b.base = 0x01BB9866; //a base do segmento a, o max ‚ FFFFFFF... gdtr.base.s[segidx(0x1058)].c.type = 0xF2; // dpl=usuario, permite ler e escrever gdtr.base.s[segidx(0x1058)].c.bitsize = 0x40;

  13. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ //Preenchendo o descritor(seletor) de pilha gdtr.base.s[segidx(0x1060)].a.limit = header.stacksize-1; //o limite est  no cabecalho, -1 pois comeca em 0 gdtr.base.s[segidx(0x1060)].a.base = 0x01CC9866; //a base do segmento a, o max ‚ FFFFFFF... gdtr.base.s[segidx(0x1060)].b.base = 0x01CC9866; //a base do segmento a, o max ‚ FFFFFFF... gdtr.base.s[segidx(0x1060)].c.type = 0xF2; // dpl=usuario, permite ler e escrever gdtr.base.s[segidx(0x1060)].c.bitsize = 0x40;

  14. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ //Colocando os dados depois de carregar o cabecalho if(fread(&0x01989866, header.datasize, 1, exefile)!=1) { // fread(end da base, quantidade de dados,= ) fprintf(stderr,"Nao consigo ler os dados.\n"); exit(1); } //Colocando o codigo depois de carregar o cabecalho if(fread(&0x01AA9866, header.codesize, 1, exefile)!=1) { fprintf(stderr,"Nao consigo ler o codigo.\n"); exit(1); } fclose(exefile); }

  15. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ void criaTss() { static struct tss estado; //Descritor de Segmento para o TSS gdtr.base.s[segidx(0x1068)].a.limit = sizeof(estado); //o limite do segmento de pilha gdtr.base.s[segidx(0x1068)].a.base = &estado; // gdtr.base.s[segidx(0x1068)].b.base = &estado; // gdtr.base.s[segidx(0x1068)].c.type = 0x89; //tipo do segmento. no descriptor do segmento (p=1,dpl=00,s=0), onde o s tem que ser 8. gdtr.base.s[segidx(0x1068)].c.bitsize = 0x40; //0/0 do descrittor 32 bist?

  16. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ // preenchimento da TSS estado.eflags = 0x202; // PSW estado.ldtr = 0x828; // eh assim mesmo estado.iopb = sizeof(struct tss); // todos os seletores com rpl=3=usuario estado.cs = 0x1050+3; //codigo estado.ds = 0x1048+3; //dados estado.es = 0x1058+3; //variaveis estado.gs = 0x1000+3; //ram de video estado.ss = 0x1060+3; //Pilha

  17. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ // preenchimento da TSS asm mov eax,cr3; //recuperando o cr3 do SO estado.cr3 = _EAX ;//estrutura de paginacao, coloco igual ao do SO estado.eip = 0 ;//codigo do usuario comeca em zero estado.esp = (word)gdtr.base.s[segidx(0x1060)].a.limit + 1;//topo da pilha, no limite //para nao travar quando chegar uma interrupcao estado.esp0 = _ESP; asm mov ax,ss estado.ss0 = _EAX ;

  18. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ _far void sair(){ asm mov ax,0x930 // garantir espaco total para todos os segmentos asm mov ds,ax asm mov es,ax asm mov fs,ax exit(0); }

  19. /* -------------------------------------------------------------------------------------------- SOFTWARE BASICO - carregador -------------------------------------------------------------------------------------------*/ void criaCallGate() { static word so_cs; // seletor de codigo do S.O. // preenchendo o call gate // sair sera chamada pelo codigo do usuario gdtr.base.g[segidx(0x1070)].a.offset = &sair; gdtr.base.g[segidx(0x1070)].b.offset = &sair; asm mov ax,cs asm mov [so_cs],ax gdtr.base.g[segidx(0x1070)].b.selector = so_cs; gdtr.base.g[segidx(0x1070)].a.params = 0; gdtr.base.g[segidx(0x1070)].a.type = 0xEC; //no test.c (pode ser a 1a instrucao do main) temos que introduzir: asm call 0x1070:0 }

  20. int main() { cadastrar(20111011); /* Recupera alguns valores do S.O. para ficar em variaveis globais. */ asm sidt [idtr] // armazena inicio da IDT asm sgdt [gdtr] // armazena inicio da GDT /* Segmento de video */ descVideo(); initializar(5); carregar("test"); // carrega o processo de usuario criaTss(); criaCallGate(); // asm jmp 0x1050:0; // superjump: pula para outro segmento asm jmp 0x1068:0; // hiperjump: pula para outro contexto (TSS) return 0; // }

  21. /* -------------------------------------------------------------------------------------------- APLICATIVO – Test.c -------------------------------------------------------------------------------------------*/ // system call #define systemcall asm call 0x1070:0 dword dummy; // definição de uma variavel apenas para preecher o segmento correspondente (32 bits) // prototipos void desenhar_fractal(); void main() { // A primeira rotina do programa deve ser o main desenhar_fractal(); systemcall; // chamada ao S.O. }

  22. Segmentação - Passos • Observar a Tabela da GDT nos endereços 928, 930, .... E 810 (TR - Busy). • Observar na Tabela de memória os segmentos de dados e de código (Alt +D, Alt +C). • Executar descVideo() e observar na tabela da GDT a posição 1000. • Executar carregar(“test”) e observar o conteúdo da GDT em 1048, 1050, 1058, 1060. • Executar CriaTSS() e observar o conteúdo da GDT em 1068 (Available, Salva o contexto do aplicativo). • Executar CriaCallGate() e observar o conteúdo da GDT em 1070. • Executar JMP 0x1068:00 e observar a memória (tamanho do segmento-Aplicativo), 1068 da GDT (Busy) e 810 (Available) e o valor do EIP (0). • Executar no aplicativo o systemcall (call 0x1070:00).

More Related