2011

Sistemi operativi Lez.19 Protected mode in Minix A.A. 2010/2011 1 Corso: Sistemi Operativi © Danilo Bruschi http://www.raspberryginger.com/jbaile...
Author: Elizabeth Blake
2 downloads 2 Views 388KB Size
Sistemi operativi Lez.19 Protected mode in Minix

A.A. 2010/2011

1

Corso: Sistemi Operativi © Danilo Bruschi

http://www.raspberryginger.com/jbailey/minix/ html/index.html

A.A. 2010/2011

2

Corso: Sistemi Operativi © Danilo Bruschi

Introduzione •  Dopo un avvio hw il processore è in real mode •  Per poter passare alla modalità protected è necessario che il sw di inizializzazione provveda a predisporre una serie di strutture dati e codice necessarie per poter operare correttamente in protected mode

A.A. 2010/2011

3

Corso: Sistemi Operativi © Danilo Bruschi

Strutture dati •  •  •  •  • 

IDT GDT Un TSS Una LDT (opzionale) Un segmento codice che contiene il codice da eseguire quando il processore entra in modalità protetta

• 

Uno o più segmenti in cui sono caricati i gestori di interrupt ed eccezioni

A.A. 2010/2011

4

Corso: Sistemi Operativi © Danilo Bruschi

Registri •  Vanno inoltre inizializzati i seguenti registri: •  GDTR •  IDTR: va inizializzato a interrupt disabilitati, prima della loro riabilitazione •  I registri di controllo CR1 … CR4

A.A. 2010/2011

5

Corso: Sistemi Operativi © Danilo Bruschi

Switching a protected mode •  Le istruzioni per lo switching a protected mode sono: ! enter protected mode! PE_BIT EQU 1B! MOV EBX,CR0! OR EBX,PE_BIT! MOV CR0,EBX!

A.A. 2010/2011

6

Corso: Sistemi Operativi © Danilo Bruschi

CR0

A.A. 2010/2011

7

Corso: Sistemi Operativi © Danilo Bruschi

Per questa parte di lezione fare riferimento al file Minix kernel/protect.c

GDT

A.A. 2010/2011

8

Corso: Sistemi Operativi © Danilo Bruschi

Boot file ! Call C startup code to set up a proper environment to run main(). ! push edx ! push ebx ! push SS_SELECTOR ! push MON_CS_SELECTOR ! push DS_SELECTOR ! push CS_SELECTOR ! call _cstart

! Procedura che prevede al caricamento di GDT, IDT e TSS!

add esp, 6*4! ! ! Reload gdtr, idtr and the segment registers to global descriptor !! ! table set

up by prot_init().!

lgdt (_gdt+GDT_SELECTOR) ! lidt (_gdt+IDT_SELECTOR)!

A.A. 2010/2011

9

Corso: Sistemi Operativi © Danilo Bruschi

GDT e LDT

A.A. 2010/2011

10

Corso: Sistemi Operativi © Danilo Bruschi

Layout Segment Descritpor

A.A. 2010/2011

11

Corso: Sistemi Operativi © Danilo Bruschi

Descrittore e GDT in C Minix 00081 struct segdesc_s {/* segment descriptor for protected ! ! ! ! ! ! ! !mode */! 00082 u16_t limit_low;! 00083 u16_t base_low;! 00084 u8_t base_middle;! 00085 u8_t access; /* |P|DL|1|X|E|R|A| */! 00086 u8_t granularity; /* |G|X|0|A|LIMT| */! 00087 u8_t base_high;! 00088 };!

00068 PUBLIC struct segdesc_s gdt[GDT_SIZE]!

A.A. 2010/2011

12

Corso: Sistemi Operativi © Danilo Bruschi

Costanti usate per costruire GDT 00003 /* Table sizes. */! 00004 #define GDT_SIZE (FIRST_LDT_INDEX + NR_TASKS + NR_PROCS) ! 00005

/* spec. and LDT's */!

00006 #define IDT_SIZE (IRQ8_VECTOR + 8)

/* only up to the highest vector */!

00007 #define LDT_SIZE (2 + NR_REMOTE_SEGS)

/* CS, DS and remote segments */!

00008 ! 00009 /* Fixed global descriptors.

1 to 7 are prescribed by the BIOS. */!

00010 #define GDT_INDEX

1

/* GDT descriptor */!

00011 #define IDT_INDEX

2

/* IDT descriptor */!

00012 #define DS_INDEX

3

/* kernel DS */!

00013 #define ES_INDEX

4

/* kernel ES (386: flag 4 Gb at startup) */!

00014 #define SS_INDEX

5

/* kernel SS (386: monitor SS at startup) */!

00015 #define CS_INDEX

6

/* kernel CS */!

00016 #define MON_CS_INDEX

7

/* temp for BIOS (386: monitor CS at startup) */!

00017 #define TSS_INDEX

8

/* kernel TSS */!

00018 #define DS_286_INDEX

9

/* scratch 16-bit source segment */!

00019 #define ES_286_INDEX

10

/* scratch 16-bit destination segment */!

00020 #define A_INDEX

11

/* 64K memory segment at A0000 */!

00021 #define B_INDEX

12

/* 64K memory segment at B0000 */!

A.A. 2010/2011

13

Corso: Sistemi Operativi © Danilo Bruschi

Costanti usate per costruire GDT 00022 #define C_INDEX

13

/* 64K memory segment at C0000 */!

00023 #define D_INDEX

14

/* 64K memory segment at D0000 */!

00024 #define FIRST_LDT_INDEX

15

/* rest of descriptors are LDT's */!

00025 ! 00026 #define GDT_SELECTOR

0x08

/* (GDT_INDEX * DESC_SIZE) bad for asld */!

00027 #define IDT_SELECTOR

0x10

/* (IDT_INDEX * DESC_SIZE) */!

00028 #define DS_SELECTOR

0x18

/* (DS_INDEX * DESC_SIZE) */!

00029 #define ES_SELECTOR

0x20

/* (ES_INDEX * DESC_SIZE) */!

00030 #define FLAT_DS_SELECTOR

0x21

/* less privileged ES */!

00031 #define SS_SELECTOR

0x28

/* (SS_INDEX * DESC_SIZE) */!

00032 #define CS_SELECTOR

0x30

/* (CS_INDEX * DESC_SIZE) */!

00033 #define MON_CS_SELECTOR

0x38

/* (MON_CS_INDEX * DESC_SIZE) */!

00034 #define TSS_SELECTOR

0x40

/* (TSS_INDEX * DESC_SIZE) */!

00035 #define DS_286_SELECTOR

0x49

/* (DS_286_INDEX*DESC_SIZE+TASK_PRIVILEGE) */!

00036 #define ES_286_SELECTOR

0x51

/* (ES_286_INDEX*DESC_SIZE+TASK_PRIVILEGE) */!

00037 ! 00038 /* Fixed local descriptors. */! 00039 #define CS_LDT_INDEX

0

/* process CS */!

00040 #define DS_LDT_INDEX

1

/* process DS=ES=FS=GS=SS */!

00041 #define EXTRA_LDT_INDEX

2

/* first of the extra LDT entries */!

A.A. 2010/2011

14

Corso: Sistemi Operativi © Danilo Bruschi

0043 /* Privileges. */! 00044 #define INTR_PRIVILEGE

0

/* kernel and interrupt handlers */!

00045 #define TASK_PRIVILEGE

1

/* kernel tasks */!

00046 #define USER_PRIVILEGE

3

/* servers and user !processes */!

00074 /* Access-byte and type-byte bits. */! 00075 #define PRESENT

0x80

/* set for descriptor present */!

00076 #define DPL

0x60

/* descriptor privilege level mask */!

00077 #define DPL_SHIFT

5!

00078 #define SEGMENT

0x10

/* set for segment-type descriptors */!

00081 #define EXECUTABLE

0x08

/* set for executable segment */!

00082 #define CONFORMING ! ! ! ! ! !

!

0x04 ! !

/* set for conforming segment if !executable */!

00083 #define EXPAND_DOWN ! ! ! ! ! ! !

0x04 ! !

/* set for expand-down segment if ! ! !executable*/!

00080 /* Access-byte bits. */!

00084 #define READABLE 00085 #define WRITEABLE ! ! ! ! ! !

0x02 /* set for readable segment if executable */! !

0x02 ! !

/* set for writeable segment if ! ! !executable */!

00086 #define TSS_BUSY

0x02

/* set if TSS descriptor is busy */!

00087 #define ACCESSED

0x01

/* set if segment accessed */!

A.A. 2010/2011

15

Corso: Sistemi Operativi © Danilo Bruschi

Caricamento primi elementi di GDT /* Build gdt and idt pointers in GDT where the BIOS expects them. */! ! 00139 dtp= (struct desctableptr_s *) &gdt[GDT_INDEX];! 00140 * (u16_t *) dtp->limit = (sizeof gdt) - 1;! 00141 * (u32_t *) dtp->base = vir2phys(gdt);! 00142 ! 00143 dtp= (struct desctableptr_s *) &gdt[IDT_INDEX];! 00144 * (u16_t *) dtp->limit = (sizeof idt) - 1;! 00145 * (u32_t *) dtp->base = vir2phys(idt);! 00146 ! ! /* Build segment descriptors for tasks and interrupt handlers. */! ! 00148 init_codeseg(&gdt[CS_INDEX],! 00149 kinfo.code_base, kinfo.code_size, INTR_PRIVILEGE);! 00150 init_dataseg(&gdt[DS_INDEX],! 00151 kinfo.data_base, kinfo.data_size, INTR_PRIVILEGE);! 00152 init_dataseg(&gdt[ES_INDEX], 0L, 0, TASK_PRIVILEGE);! A.A. 2010/2011

16

Corso: Sistemi Operativi © Danilo Bruschi

Procedura per il caricamento dei segmenti codice dal file protect.c *==================================================================*! 00195 * init_codeseg *! 00196 *============================================================*/! 00197 PUBLIC void init_codeseg(segdp, base, size, privilege)! 00198 register struct segdesc_s *segdp;! 00199 phys_bytes base;! 00200 vir_bytes size;! 00201 int privilege;! 00202 {! 00203 /* Build descriptor for a code segment. */! 00204 sdesc(segdp, base, size);! 00205 segdp->access = (privilege vec_nr, (vir_bytes) gtp->gate, PRESENT| INT_GATE_TYPE| (gtp->privilege offset_low = offset; 00318 idp->selector = CS_SELECTOR; 00319 idp->p_dpl_type = dpl_type; 00320 #if _WORD_SIZE == 4 00321 idp->offset_high = offset >> OFFSET_HIGH_SHIFT; 00322 #endif 00323 }

A.A. 2010/2011

30

Corso: Sistemi Operativi © Danilo Bruschi

TSS

A.A. 2010/2011

31

Corso: Sistemi Operativi © Danilo Bruschi

TSS

A.A. 2010/2011

32

Corso: Sistemi Operativi © Danilo Bruschi

TSS in C 00031 struct tss_s {! 00032

reg_t backlink;!

00033

reg_t sp0;

/* stack pointer to use during interrupt */!

00034

reg_t ss0;

/*

00035

reg_t sp1;!

00036

reg_t ss1;!

00037

reg_t sp2;!

00038

reg_t ss2;!

"

segment

"

"

"

"

*/!

00039 #if _WORD_SIZE == 4! 00040

reg_t cr3;!

00041 #endif! 00042

reg_t ip;!

00043

reg_t flags;!

00044

reg_t ax;!

00045

reg_t cx;!

00046

reg_t dx;!

00047

reg_t bx;!

00048

reg_t sp;!

A.A. 2010/2011

33

Corso: Sistemi Operativi © Danilo Bruschi

TSS in C 00049

reg_t bp;!

00050

reg_t si;!

00051

reg_t di;!

00052

reg_t es;!

00053

reg_t cs;!

00054

reg_t ss;!

00055

reg_t ds;!

00056 #if _WORD_SIZE == 4! 00057

reg_t fs;!

00058

reg_t gs;!

00059 #endif! 00060

reg_t ldt;!

00061 #if _WORD_SIZE == 4! 00062

u16_t trap;!

00063

u16_t iobase;!

00064 /* u8_t iomap[0]; */! 00065 #endif! 00066 };!

A.A. 2010/2011

34

Corso: Sistemi Operativi © Danilo Bruschi

TSS (protect.c) /* Build main TSS. This is used only to record the stack * ! pointer to be used after an interrupt. The pointer is set up ! so that an interrupt automatically saves the ! current process's registers ip:cs:f:sp:ss in the correct slots in the process table. */ ! ! tss.ss0 = DS_SELECTOR;! init_dataseg(&gdt[TSS_INDEX], vir2phys(&tss), sizeof(tss), INTR_PRIVILEGE); ! gdt[TSS_INDEX].access = PRESENT | (INTR_PRIVILEGE access = (privilege