Data Structures | |||||||||
struct | gdt_entry | ||||||||
GDT structure. More... | |||||||||
struct | gdt_register | ||||||||
The GDT register format. More... | |||||||||
Defines | |||||||||
#define | GDT_DIM 8192 | ||||||||
Number of entries in the GDT (Global Descriptor Table). | |||||||||
#define | GDT_ENTRY_DIM sizeof(gdt_entry_t) | ||||||||
GDT entry dimension in bytes. | |||||||||
#define | PRESENT 0x80 | ||||||||
The segment is present. | |||||||||
#define | CODE 0x18 | ||||||||
A code segment type. | |||||||||
#define | DATA 0x10 | ||||||||
A data segment type. | |||||||||
#define | EXP_DOWN 0x04 | ||||||||
The segment grows downward. | |||||||||
#define | CONFORMING 0x04 | ||||||||
A conforming code segment. | |||||||||
#define | READABLE 0x02 | ||||||||
A readable segment. | |||||||||
#define | WRITEABLE 0x02 | ||||||||
A writeable segment. | |||||||||
#define | CODE_SEG (CODE | PRESENT | READABLE) | ||||||||
A standard code segment. | |||||||||
#define | DATA_SEG (DATA | PRESENT | WRITEABLE) | ||||||||
A standard data segment. | |||||||||
#define | STACK_SEG DATA_SEG | ||||||||
A standard stack segment. | |||||||||
#define | TSS_SEG (PRESENT | 0x09) | ||||||||
A standard TSS segment. | |||||||||
#define | REAL_SEG (CODE | PRESENT | READABLE) | ||||||||
A real-mode area segment. | |||||||||
#define | INT_GATE (PRESENT | 0x0E) | ||||||||
32-bit Interrupt Gate. | |||||||||
#define | TASK_GATE (PRESENT | 0x05) | ||||||||
Task Gate. | |||||||||
#define | TRAP_GATE (PRESENT | 0x0F) | ||||||||
32-bit Trap Gate. | |||||||||
#define | DPL_0 0x00 | ||||||||
Descriptor Privilege Level 0 (maximum privilege). | |||||||||
#define | DPL_1 0x20 | ||||||||
Descriptor Privilege Level 1. | |||||||||
#define | DPL_2 0x40 | ||||||||
Descriptor Privilege Level 2. | |||||||||
#define | DPL_3 0x60 | ||||||||
Descriptor Privilege Level 3 (minimum privilege). | |||||||||
#define | BUSY_FLAG 0x02 | ||||||||
The busy bit of the TSS descriptor (to avoid recursive tasks). | |||||||||
#define | ATTR_32BIT 0x40 | ||||||||
Default size of the istructions (for a code segment) or the stack alignment (for a stack segment). | |||||||||
#define | ATTR_GRANUL 0x80 | ||||||||
The granularity of the segment size (limit field):
| |||||||||
#define | KERNEL_DATA 0x08 | ||||||||
This is the data selector for the kernel. REMEBER!!! It is defined also into irq.S! | |||||||||
#define | KERNEL_STACK 0x08 | ||||||||
This is the stack selector for the kernel. | |||||||||
#define | KERNEL_CODE 0x10 | ||||||||
This is the code selector for the kernel. | |||||||||
#define | USER_DATA 0x18 | ||||||||
This is the selector for the user data segment. | |||||||||
#define | USER_STACK 0x18 | ||||||||
This is the selector for the user stack segment. | |||||||||
#define | USER_CODE 0x20 | ||||||||
This is the selector for the user code segment. | |||||||||
#define | SEGMENT(linear) ( (word)(((dword)(linear) & 0xFFFF0000) >> 4) ) | ||||||||
(real-mode) Extract the segment part of a linear address. | |||||||||
#define | OFFSET(linear) ( (word)((dword)(linear) & 0xFFFF) ) | ||||||||
(real-mode) Extract the offset part of a linear address. | |||||||||
#define | LINEAR(seg, off) ( (dword)(((word)(seg) << 4) + (word)(off)) ) | ||||||||
(real-mode) Make a linear address from a segment:offset address. | |||||||||
#define | MK_FP(seg, off) ((FARPTR) (((uint32_t) (seg) << 16) | (uint16_t) (off))) | ||||||||
(i386) Make a far pointer from seg segment and off offset.
| |||||||||
#define | FP_SEG(fp) (((FARPTR) fp) >> 16) | ||||||||
(i386) Get the segment from the far pointer fp . | |||||||||
#define | FP_OFF(fp) (((FARPTR) fp) & 0xffff) | ||||||||
(i386) Get the offset from the far pointer fp . | |||||||||
#define | FP_TO_LINEAR(seg, off) ((void*) ((((uint16_t) (seg)) << 4) + ((uint16_t) (off)))) | ||||||||
Translate a real-mode segment:offset address to the linear address. This macro is equivalent to LINEAR(seg, off) macro. | |||||||||
Typedefs | |||||||||
typedef uint32_t | FARPTR | ||||||||
(i386) far pointer. | |||||||||
typedef uint32_t | far | ||||||||
(i386) far pointer. | |||||||||
typedef gdt_entry | gdt_entry_t | ||||||||
GDT structure. | |||||||||
typedef gdt_register | gdt_reg | ||||||||
The GDT register format. | |||||||||
Functions | |||||||||
__inline__ void | memsetb (void *dest_ptr, int val, dword count) | ||||||||
Sets count bytes to val .
| |||||||||
__inline__ void | memsetw (void *dest_ptr, word val, dword count) | ||||||||
Sets count words to val .
| |||||||||
__inline__ void | memsetl (void *dest_ptr, dword val, dword count) | ||||||||
Sets count double words to val .
| |||||||||
__inline__ void * | memset (void *s, unsigned long c, size_t count) | ||||||||
Optimized version of memset.
| |||||||||
__inline__ void | memcpyb (void *dest_ptr, const void *org_ptr, dword count) | ||||||||
Copy count bytes from org_ptr to dest_ptr .
| |||||||||
__inline__ void | memcpyw (void *dest_ptr, const void *org_ptr, dword count) | ||||||||
Copy count words from org_ptr to dest_ptr .
| |||||||||
__inline__ void | memcpyl (void *dest_ptr, const void *org_ptr, dword count) | ||||||||
Copy count double words from org_ptr to dest_ptr .
| |||||||||
__inline__ void * | memcpy (void *to, const void *from, size_t n) | ||||||||
Optimized version of memcpy.
| |||||||||
__inline__ int | memcmp (const void *s1, const void *s2, size_t n) | ||||||||
Compares the first n bytes of memory areas s1 and s2 . It returns an integer less than, equal to, or greater than zero if s1 is found, respectively, to be less than, to match, or be greater than s2 .
| |||||||||
__inline__ void * | memchr (const void *cs, int c, size_t count) | ||||||||
Find a byte into a memory area.
| |||||||||
__inline__ void | k_update_segment_regs () | ||||||||
Update segment registers with kernel selectors. | |||||||||
word | setup_GDT_entry (word limit, dword base, byte attribs0_7, byte attribs8_15) | ||||||||
Initialize a GDT entry.
| |||||||||
void | remove_GDT_entry (word sel) | ||||||||
Remove a GDT entry.
| |||||||||
void | install_GDT () | ||||||||
Initialize the Global Descriptor Table with the default selectors and update the segment registers. |
|
Default size of the istructions (for a code segment) or the stack alignment (for a stack segment).
|
|
The granularity of the segment size (limit field):
|
|
The busy bit of the TSS descriptor (to avoid recursive tasks).
|
|
A code segment type.
|
|
A standard code segment.
|
|
A conforming code segment.
|
|
A data segment type.
|
|
A standard data segment.
|
|
Descriptor Privilege Level 0 (maximum privilege).
|
|
Descriptor Privilege Level 1.
|
|
Descriptor Privilege Level 2.
|
|
Descriptor Privilege Level 3 (minimum privilege).
|
|
The segment grows downward.
|
|
(i386) Get the offset from the far pointer
|
|
(i386) Get the segment from the far pointer
|
|
Translate a real-mode segment:offset address to the linear address. This macro is equivalent to LINEAR(seg, off) macro.
|
|
Number of entries in the GDT (Global Descriptor Table).
|
|
GDT entry dimension in bytes.
|
|
32-bit Interrupt Gate.
|
|
This is the code selector for the kernel.
|
|
This is the data selector for the kernel. REMEBER!!! It is defined also into irq.S!
|
|
This is the stack selector for the kernel.
|
|
(real-mode) Make a linear address from a segment:offset address.
|
|
(i386) Make a far pointer from
|
|
(real-mode) Extract the offset part of a linear address.
|
|
The segment is present.
|
|
A readable segment.
|
|
A real-mode area segment.
|
|
(real-mode) Extract the segment part of a linear address.
|
|
A standard stack segment.
|
|
Task Gate.
|
|
32-bit Trap Gate.
|
|
A standard TSS segment.
|
|
This is the selector for the user code segment.
|
|
This is the selector for the user data segment.
|
|
This is the selector for the user stack segment.
|
|
A writeable segment.
|
|
(i386) far pointer.
|
|
(i386) far pointer.
|
|
GDT structure. P=Present, DPL=Descriptor Privilege Level, S=Descriptor type (0=system; 1=code or data), Type=Segment type, G=Granularity, D/B=Default operation size(0=16bit; 1=32bit segment), AVL=Available for use by system software. |
|
The GDT register format.
|
|
Initialize the Global Descriptor Table with the default selectors and update the segment registers.
Definition at line 93 of file mem.c.
00094 { 00095 // First of all reset all entries in the GDT // 00096 memset(&gdt, 0, sizeof(gdt)); 00097 00098 // ------------- Reserved entries in the GDT ------------------ // 00099 00100 // Dummy descriptor// 00101 setup_GDT_entry(0, 0, 0, 0); 00102 // KERNEL_DATA descriptor 0x08 // 00103 setup_GDT_entry(0xFFFF, 0, DATA_SEG, (ATTR_GRANUL | ATTR_32BIT | 0xF)); 00104 // KERNEL_CODE descriptor 0x10 // 00105 setup_GDT_entry(0xFFFF, 0, CODE_SEG, (ATTR_GRANUL | ATTR_32BIT | 0xF)); 00106 // USER_DATA descriptor 0x18 // 00107 setup_GDT_entry(0xFFFF, 0, (DATA_SEG | DPL_3), (ATTR_GRANUL | ATTR_32BIT | 0xF)); 00108 // USER_CODE descriptor 0x20 // 00109 setup_GDT_entry(0xFFFF, 0, (CODE_SEG | DPL_3), (ATTR_GRANUL | ATTR_32BIT | 0xF)); 00110 00111 // --------- End of reserved entries in the GDT --------------- // 00112 00113 // Set up the GDT pointer // 00114 gdt_ptr.limit = (uint16_t)(GDT_DIM * GDT_ENTRY_DIM - 1); 00115 gdt_ptr.base = (size_t)gdt; 00116 00117 // Load info into GDTR // 00118 __asm__ __volatile__ ("lgdtl (%0)" : : "r"(&gdt_ptr)); 00119 00120 // Update segment registers // 00121 k_update_segment_regs(); 00122 } |
|
Update segment registers with kernel selectors.
Definition at line 307 of file mem.h.
00308 { 00309 __asm__ __volatile__( 00310 "ljmp %0, $1f\n" 00311 "nop\n" 00312 "1: mov %1, %%ds\n" 00313 "mov %1, %%es\n" 00314 "mov %1, %%ss\n" 00315 "nop\n" 00316 "mov %1, %%fs\n" 00317 "mov %1, %%gs\n" 00318 : : "i"(KERNEL_CODE), "r"(KERNEL_DATA) ); 00319 } |
|
Find a byte into a memory area.
Definition at line 289 of file mem.h.
00290 { 00291 int d0; 00292 register void * __res; 00293 if (!count) 00294 return( 0 ); 00295 __asm__ __volatile__( 00296 "cld\n\t" 00297 "repne\n\t" 00298 "scasb\n\t" 00299 "je 1f\n\t" 00300 "movl $1,%0\n" 00301 "1:\tdecl %0" 00302 :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count)); 00303 return( __res ); 00304 } |
|
Compares the first
Definition at line 265 of file mem.h.
00266 { 00267 int d0, d1, d2; 00268 register int __res; 00269 __asm__ __volatile__( 00270 "cld\n\t" 00271 "repe\n\t" 00272 "cmpsb\n\t" 00273 "je 1f\n\t" 00274 "sbbl %0,%0\n\t" 00275 "orb $1,%b0\n" 00276 "1:" 00277 :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) 00278 :"0" (0), "1" (s1), "2" (s2), "3" (n)); 00279 return( __res ); 00280 } |
|
Optimized version of memcpy.
Definition at line 238 of file mem.h.
00239 { 00240 int d0, d1, d2; 00241 __asm__ __volatile__( 00242 "cld\n\t" 00243 "rep ; movsl\n\t" 00244 "testb $2,%b4\n\t" 00245 "je 1f\n\t" 00246 "movsw\n" 00247 "1:\ttestb $1,%b4\n\t" 00248 "je 2f\n\t" 00249 "movsb\n" 00250 "2:" 00251 : "=&c" (d0), "=&D" (d1), "=&S" (d2) 00252 :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) 00253 : "memory"); 00254 return( to ); 00255 } |
|
Copy
Definition at line 198 of file mem.h.
00199 { 00200 __asm__ __volatile__ ( 00201 "cld\n" 00202 "rep movsb" 00203 : :"D"(dest_ptr), "S"(org_ptr), "c"(count)); 00204 __asm__("": : :"%ecx", "%edi", "%esi"); 00205 } |
|
Copy
Definition at line 224 of file mem.h.
00225 { 00226 __asm__ __volatile__ ( 00227 "cld\n" 00228 "rep movsl" 00229 : :"D"(dest_ptr), "S"(org_ptr), "c"(count)); 00230 __asm__("": : :"%ecx", "%edi", "%esi"); 00231 } |
|
Copy
Definition at line 211 of file mem.h.
00212 { 00213 __asm__ __volatile__ ( 00214 "cld\n" 00215 "rep movsw" 00216 : :"D"(dest_ptr), "S"(org_ptr), "c"(count)); 00217 __asm__("": : :"%ecx", "%edi", "%esi"); 00218 } |
|
Optimized version of memset.
Definition at line 175 of file mem.h.
00176 { 00177 int d0, d1; 00178 __asm__ __volatile__( 00179 "cld\n\t" 00180 "rep ; stosl\n\t" 00181 "testb $2,%b3\n\t" 00182 "je 1f\n\t" 00183 "stosw\n" 00184 "1:\ttestb $1,%b3\n\t" 00185 "je 2f\n\t" 00186 "stosb\n" 00187 "2:" 00188 : "=&c" (d0), "=&D" (d1) 00189 :"a" (c), "q" (count), "0" (count/4), "1" ((long)s) 00190 :"memory"); 00191 return( s ); 00192 } |
|
Sets
Definition at line 135 of file mem.h.
00136 { 00137 __asm__ __volatile__ ( 00138 "cld\n" 00139 "rep stosb" 00140 : :"D"(dest_ptr), "c"(count), "a"(val)); 00141 __asm__("": : :"%edi", "%ecx"); 00142 } |
|
Sets
Definition at line 161 of file mem.h.
00162 { 00163 __asm__ __volatile__ ( 00164 "cld\n" 00165 "rep stosl" 00166 : :"D"(dest_ptr), "c"(count), "a"(val)); 00167 __asm__("": : :"%edi", "%ecx"); 00168 } |
|
Sets
Definition at line 148 of file mem.h.
00149 { 00150 __asm__ __volatile__ ( 00151 "cld\n" 00152 "rep stosw" 00153 : :"D"(dest_ptr), "c"(count), "a"(val)); 00154 __asm__("": : :"%edi", "%ecx"); 00155 } |
|
Remove a GDT entry.
Definition at line 74 of file mem.c.
00075 { 00076 dword IF = GET_IF(); 00077 00078 disable(); 00079 00080 gdt[sel/GDT_ENTRY_DIM].limit = 0; 00081 gdt[sel/GDT_ENTRY_DIM].base0_15 = 0; 00082 gdt[sel/GDT_ENTRY_DIM].base16_23 = 0; 00083 gdt[sel/GDT_ENTRY_DIM].base24_31 = 0; 00084 gdt[sel/GDT_ENTRY_DIM].attribs0_7 = 0; 00085 gdt[sel/GDT_ENTRY_DIM].attribs8_15 = 0; 00086 00087 SET_IF(IF); 00088 } |
|
Initialize a GDT entry.
Definition at line 44 of file mem.c.
00045 { 00046 // Skip the dummy entry (#0). 00047 register unsigned short i=1; 00048 dword IF = GET_IF(); 00049 00050 disable(); 00051 for (; i<GDT_DIM; i++) 00052 { 00053 if (!(gdt[i].limit)) 00054 { 00055 gdt[i].limit = limit; 00056 gdt[i].base0_15 = base & 0xFFFF; 00057 gdt[i].base16_23 = (base >> 16) & 0xFF; 00058 gdt[i].base24_31 = (base >> 24) & 0xFF; 00059 gdt[i].attribs0_7 = attribs0_7; 00060 gdt[i].attribs8_15 = attribs8_15; 00061 00062 SET_IF(IF); 00063 00064 // Return the selector. 00065 return(i * GDT_ENTRY_DIM); 00066 } 00067 } 00068 error("Out of GDT entries!"); 00069 return( NULL ); 00070 } |