Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

Low-Level Memory Manager
[Memory Manager]


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):
  • 0 => byte granularity;
  • 1 => page granularity (4096 bytes).


#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.
Note:
In this case a segment is considered as 65536(0x10000) bytes.


#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.
Parameters:
dest_ptr  The destination pointer.
val  The value to set.
count  How many bytes to set.


__inline__ void memsetw (void *dest_ptr, word val, dword count)
 Sets count words to val.
Parameters:
dest_ptr  The destination pointer.
val  The value to set.
count  How many words to set.


__inline__ void memsetl (void *dest_ptr, dword val, dword count)
 Sets count double words to val.
Parameters:
dest_ptr  The destination pointer.
val  The value to set.
count  How many double words to set.


__inline__ void * memset (void *s, unsigned long c, size_t count)
 Optimized version of memset.
Parameters:
s  The destination pointer.
c  The value to set.
count  How many bytes to set.
Returns:
The destination pointer.


__inline__ void memcpyb (void *dest_ptr, const void *org_ptr, dword count)
 Copy count bytes from org_ptr to dest_ptr.
Parameters:
dest_ptr  The destination pointer.
org_ptr  The source pointer.
count  How many bytes to copy.


__inline__ void memcpyw (void *dest_ptr, const void *org_ptr, dword count)
 Copy count words from org_ptr to dest_ptr.
Parameters:
dest_ptr  The destination pointer.
org_ptr  The source pointer.
count  How many words to copy.


__inline__ void memcpyl (void *dest_ptr, const void *org_ptr, dword count)
 Copy count double words from org_ptr to dest_ptr.
Parameters:
dest_ptr  The destination pointer.
org_ptr  The source pointer.
count  How many double words to copy.


__inline__ void * memcpy (void *to, const void *from, size_t n)
 Optimized version of memcpy.
Parameters:
to  The destination pointer.
from  The source pointer.
n  How many bytes to copy.
Returns:
The destination pointer.


__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.
Parameters:
s1  The first memory pointer of the area to compare.
s2  The second memory pointer of the area to compare.
n  How many words to compare.


__inline__ void * memchr (const void *cs, int c, size_t count)
 Find a byte into a memory area.
Parameters:
cs  The pointer of the memory area.
c  The character to find.
count  The size of the memory area.
Returns:
The address of the first occurrence or 0 if the char has not been found.


__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.
Parameters:
limit  The size of the memory segment.
base  The starting linear address of the memory segment.
attribs0_7  The first 8-bit of the segment descriptor attributes.
attribs8_15  The last 8-bit of the segment descriptor attributes.
Returns:
The selector of the new GDT entry.


void remove_GDT_entry (word sel)
 Remove a GDT entry.
Parameters:
sel  The selector to remove from the GDT.


void install_GDT ()
 Initialize the Global Descriptor Table with the default selectors and update the segment registers.


Detailed Description

The low level memory operators (based on i386-architecture).

Define Documentation

#define ATTR_32BIT   0x40
 

Default size of the istructions (for a code segment) or the stack alignment (for a stack segment).

Definition at line 65 of file mem.h.

#define ATTR_GRANUL   0x80
 

The granularity of the segment size (limit field):

  • 0 => byte granularity;
  • 1 => page granularity (4096 bytes).

Definition at line 69 of file mem.h.

#define BUSY_FLAG   0x02
 

The busy bit of the TSS descriptor (to avoid recursive tasks).

Definition at line 61 of file mem.h.

#define CODE   0x18
 

A code segment type.

Definition at line 29 of file mem.h.

#define CODE_SEG   (CODE | PRESENT | READABLE)
 

A standard code segment.

Definition at line 37 of file mem.h.

#define CONFORMING   0x04
 

A conforming code segment.

Definition at line 32 of file mem.h.

#define DATA   0x10
 

A data segment type.

Definition at line 30 of file mem.h.

#define DATA_SEG   (DATA | PRESENT | WRITEABLE)
 

A standard data segment.

Definition at line 39 of file mem.h.

#define DPL_0   0x00
 

Descriptor Privilege Level 0 (maximum privilege).

Definition at line 52 of file mem.h.

#define DPL_1   0x20
 

Descriptor Privilege Level 1.

Definition at line 54 of file mem.h.

#define DPL_2   0x40
 

Descriptor Privilege Level 2.

Definition at line 56 of file mem.h.

#define DPL_3   0x60
 

Descriptor Privilege Level 3 (minimum privilege).

Definition at line 58 of file mem.h.

#define EXP_DOWN   0x04
 

The segment grows downward.

Definition at line 31 of file mem.h.

#define FP_OFF fp       (((FARPTR) fp) & 0xffff)
 

(i386) Get the offset from the far pointer fp.

Definition at line 104 of file mem.h.

#define FP_SEG fp       (((FARPTR) fp) >> 16)
 

(i386) Get the segment from the far pointer fp.

Definition at line 102 of file mem.h.

#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.

Definition at line 107 of file mem.h.

#define GDT_DIM   8192
 

Number of entries in the GDT (Global Descriptor Table).

Definition at line 23 of file mem.h.

#define GDT_ENTRY_DIM   sizeof(gdt_entry_t)
 

GDT entry dimension in bytes.

Definition at line 25 of file mem.h.

#define INT_GATE   (PRESENT | 0x0E)
 

32-bit Interrupt Gate.

Definition at line 47 of file mem.h.

#define KERNEL_CODE   0x10
 

This is the code selector for the kernel.

Definition at line 77 of file mem.h.

#define KERNEL_DATA   0x08
 

This is the data selector for the kernel. REMEBER!!! It is defined also into irq.S!

Definition at line 73 of file mem.h.

#define KERNEL_STACK   0x08
 

This is the stack selector for the kernel.

Definition at line 75 of file mem.h.

#define LINEAR seg,
off       ( (dword)(((word)(seg) << 4) + (word)(off)) )
 

(real-mode) Make a linear address from a segment:offset address.

Definition at line 91 of file mem.h.

#define MK_FP seg,
off       ((FARPTR) (((uint32_t) (seg) << 16) | (uint16_t) (off)))
 

(i386) Make a far pointer from seg segment and off offset.

Note:
In this case a segment is considered as 65536(0x10000) bytes.

Definition at line 100 of file mem.h.

#define OFFSET linear       ( (word)((dword)(linear) & 0xFFFF) )
 

(real-mode) Extract the offset part of a linear address.

Definition at line 89 of file mem.h.

#define PRESENT   0x80
 

The segment is present.

Definition at line 28 of file mem.h.

#define READABLE   0x02
 

A readable segment.

Definition at line 33 of file mem.h.

#define REAL_SEG   (CODE | PRESENT | READABLE)
 

A real-mode area segment.

Definition at line 45 of file mem.h.

#define SEGMENT linear       ( (word)(((dword)(linear) & 0xFFFF0000) >> 4) )
 

(real-mode) Extract the segment part of a linear address.

Definition at line 87 of file mem.h.

#define STACK_SEG   DATA_SEG
 

A standard stack segment.

Definition at line 41 of file mem.h.

#define TASK_GATE   (PRESENT | 0x05)
 

Task Gate.

Definition at line 48 of file mem.h.

#define TRAP_GATE   (PRESENT | 0x0F)
 

32-bit Trap Gate.

Definition at line 49 of file mem.h.

#define TSS_SEG   (PRESENT | 0x09)
 

A standard TSS segment.

Definition at line 43 of file mem.h.

#define USER_CODE   0x20
 

This is the selector for the user code segment.

Definition at line 84 of file mem.h.

#define USER_DATA   0x18
 

This is the selector for the user data segment.

Definition at line 80 of file mem.h.

#define USER_STACK   0x18
 

This is the selector for the user stack segment.

Definition at line 82 of file mem.h.

#define WRITEABLE   0x02
 

A writeable segment.

Definition at line 34 of file mem.h.


Typedef Documentation

typedef uint32_t far
 

(i386) far pointer.

Definition at line 96 of file mem.h.

typedef uint32_t FARPTR
 

(i386) far pointer.

Definition at line 94 of file mem.h.

typedef struct gdt_entry gdt_entry_t
 

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.

typedef struct gdt_register gdt_reg
 

The GDT register format.


Function Documentation

void install_GDT  
 

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 }

__inline__ void k_update_segment_regs   [static]
 

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 }

__inline__ void* memchr const void *    cs,
int    c,
size_t    count
[static]
 

Find a byte into a memory area.

Parameters:
cs  The pointer of the memory area.
c  The character to find.
count  The size of the memory area.
Returns:
The address of the first occurrence or 0 if the char has not been found.

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 }

__inline__ int memcmp const void *    s1,
const void *    s2,
size_t    n
[static]
 

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.

Parameters:
s1  The first memory pointer of the area to compare.
s2  The second memory pointer of the area to compare.
n  How many words to compare.

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 }

__inline__ void* memcpy void *    to,
const void *    from,
size_t    n
[static]
 

Optimized version of memcpy.

Parameters:
to  The destination pointer.
from  The source pointer.
n  How many bytes to copy.
Returns:
The destination pointer.

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 }

__inline__ void memcpyb void *    dest_ptr,
const void *    org_ptr,
dword    count
[static]
 

Copy count bytes from org_ptr to dest_ptr.

Parameters:
dest_ptr  The destination pointer.
org_ptr  The source pointer.
count  How many bytes to 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 }

__inline__ void memcpyl void *    dest_ptr,
const void *    org_ptr,
dword    count
[static]
 

Copy count double words from org_ptr to dest_ptr.

Parameters:
dest_ptr  The destination pointer.
org_ptr  The source pointer.
count  How many double words to 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 }

__inline__ void memcpyw void *    dest_ptr,
const void *    org_ptr,
dword    count
[static]
 

Copy count words from org_ptr to dest_ptr.

Parameters:
dest_ptr  The destination pointer.
org_ptr  The source pointer.
count  How many words to 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 }

__inline__ void* memset void *    s,
unsigned long    c,
size_t    count
[static]
 

Optimized version of memset.

Parameters:
s  The destination pointer.
c  The value to set.
count  How many bytes to set.
Returns:
The destination pointer.

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 }

__inline__ void memsetb void *    dest_ptr,
int    val,
dword    count
[static]
 

Sets count bytes to val.

Parameters:
dest_ptr  The destination pointer.
val  The value to set.
count  How many bytes to set.

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 }

__inline__ void memsetl void *    dest_ptr,
dword    val,
dword    count
[static]
 

Sets count double words to val.

Parameters:
dest_ptr  The destination pointer.
val  The value to set.
count  How many double words to set.

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 }

__inline__ void memsetw void *    dest_ptr,
word    val,
dword    count
[static]
 

Sets count words to val.

Parameters:
dest_ptr  The destination pointer.
val  The value to set.
count  How many words to set.

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 }

void remove_GDT_entry word    sel
 

Remove a GDT entry.

Parameters:
sel  The selector to remove from the GDT.

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 }

word setup_GDT_entry word    limit,
dword    base,
byte    attribs0_7,
byte    attribs8_15
 

Initialize a GDT entry.

Parameters:
limit  The size of the memory segment.
base  The starting linear address of the memory segment.
attribs0_7  The first 8-bit of the segment descriptor attributes.
attribs8_15  The last 8-bit of the segment descriptor attributes.
Returns:
The selector of the new 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 }


Generated on Fri Feb 20 15:32:22 2004 for Minirighi by doxygen1.2.18