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

mem.c

Go to the documentation of this file.
00001 /*!     \file arch/i386/kernel/mem.c
00002  *      \brief Low level (i386) memory manager.
00003  *      \author Andrea Righi <drizzt@inwind.it>
00004  *      \date Last update: 2004-01-20
00005  *      \note Copyright (&copy;) 2003 Andrea Righi
00006  *
00007  *      \n
00008  *      For a complete documentation about GDT and descriptors
00009  *      you can see the "IA-32 Intel® Architecture Software Developer's
00010  *      Manual - Volume 3: System Programming Guide"
00011  *      (http://www.intel.com/design/pentium4/manuals).
00012  *      \n
00013  *      For an intalian documentation you can download the
00014  *      "Minirighi32 - Documentazione Ufficiale"
00015  *      (http://sourceforge.net/project/showfiles.php?group_id=80923&release_id=180542).
00016  *
00017  */
00018 
00019 #include <const.h>
00020 
00021 #include <arch/i386.h>
00022 #include <arch/paging.h>
00023 
00024 #include <kernel/console.h>
00025 #include <kernel/kernel.h>
00026 #include <kernel/task.h>
00027 
00028 #include <arch/mem.h>
00029 
00030 //! Global Descriptor Table (GDT).
00031 volatile gdt_entry_t gdt[GDT_DIM];
00032 //! GDT pointer.
00033 static gdt_reg gdt_ptr;
00034 
00035 //! \brief Initialize a GDT entry.
00036 //! \param limit The size of the memory segment.
00037 //! \param base The starting linear address of the memory segment.
00038 //! \param attribs0_7
00039 //!             The first 8-bit of the segment descriptor attributes.
00040 //! \param attribs8_15
00041 //!             The last 8-bit of the segment descriptor attributes.
00042 //! \return
00043 //!     The selector of the new GDT entry.
00044 word setup_GDT_entry(word limit, dword base, byte attribs0_7, byte attribs8_15)
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 }
00071 
00072 //! \brief Remove a GDT entry.
00073 //! \param sel The selector to remove from the GDT.
00074 void remove_GDT_entry(word sel)
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 }
00089 
00090 //! \brief
00091 //!     Initialize the Global Descriptor Table with the default
00092 //!     selectors and update the segment registers.
00093 void install_GDT()
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 }

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