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 }
|
1.2.18