split mm_map() and mm_page_alloc() into regular and "early" versions (mm_early_map() and mm_early_page_alloc()); removed mm_use_virtual_offset flag
git-svn-id: svn://anubis/hos/trunk@67 5b3e749e-e535-0410-8002-a9bb6afbdfca
This commit is contained in:
parent
d7be0159c9
commit
ddd8c9fd71
@ -47,6 +47,7 @@ u32_t k_bootstrap(mb_info_t * mb_info, u32_t mb_magic)
|
||||
* before calling them.
|
||||
*/
|
||||
mm_bootstrap();
|
||||
stack_bootstrap();
|
||||
kio_bootstrap();
|
||||
|
||||
return 0;
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
#define MM_MAX_MMAP_ENTRIES 64
|
||||
|
||||
static bool mm_use_virtual_offset;
|
||||
|
||||
static pagedirectory_entry_t * page_directory;
|
||||
static mm_mem_range_t mm_mmap_entries[MM_MAX_MMAP_ENTRIES];
|
||||
static int mm_mmap_num_entries = 0;
|
||||
@ -48,7 +46,6 @@ void mm_record_mmap_entry(mb_mmap_t * mmap)
|
||||
void mm_bootstrap()
|
||||
{
|
||||
u32_t max_ram_address = KERNEL_PHYSICAL_ADDRESS + KERNEL_SIZE - 1;
|
||||
mm_use_virtual_offset = true;
|
||||
|
||||
if (mm_mmap_num_entries < 1)
|
||||
{
|
||||
@ -116,7 +113,7 @@ void mm_bootstrap()
|
||||
/* ok, now mm_page_alloc() should be functional */
|
||||
|
||||
/* allocate the page directory */
|
||||
u32_t page_directory_phys = mm_page_alloc();
|
||||
u32_t page_directory_phys = mm_early_page_alloc();
|
||||
page_directory = (pagedirectory_entry_t *) page_directory_phys;
|
||||
pagedirectory_entry_t * page_dir_virt =
|
||||
(pagedirectory_entry_t *) (page_directory_phys + KERNEL_OFFSET);
|
||||
@ -135,7 +132,7 @@ void mm_bootstrap()
|
||||
page_base < max_ram_address;
|
||||
page_base += PAGE_SIZE)
|
||||
{
|
||||
mm_map(page_base, page_base, 0, 1);
|
||||
mm_early_map(page_base, page_base, 0, 1);
|
||||
}
|
||||
|
||||
/* now map the kernel's virtual address space into RAM */
|
||||
@ -144,11 +141,11 @@ void mm_bootstrap()
|
||||
page_base += PAGE_SIZE)
|
||||
{
|
||||
/* map page_base to page_base - KERNEL_OFFSET */
|
||||
mm_map(page_base, page_base - KERNEL_OFFSET, 0, 1);
|
||||
mm_early_map(page_base, page_base - KERNEL_OFFSET, 0, 1);
|
||||
}
|
||||
|
||||
/* set up the global descriptor table */
|
||||
u32_t gdt_base = mm_page_alloc();
|
||||
u32_t gdt_base = mm_early_page_alloc();
|
||||
mm_gdt = (u64_t *) ((u32_t) gdt_base + (u32_t) KERNEL_OFFSET);
|
||||
mm_gdt[0] = 0x0ull;
|
||||
mm_gdt[1] = MAKE_DESCRIPTOR(0, 0xFFFFF, 1, 0, 1, 1);
|
||||
@ -158,10 +155,45 @@ void mm_bootstrap()
|
||||
|
||||
/* set the page directory base register */
|
||||
set_cr3(page_directory);
|
||||
}
|
||||
|
||||
stack_bootstrap();
|
||||
/**************************************************************************
|
||||
* Map virtual_address to physical_address. *
|
||||
* Both addresses should be page-aligned. *
|
||||
* This 'early' version can be used during segmented bootstrapping *
|
||||
*************************************************************************/
|
||||
int mm_early_map(u32_t virtual_address, u32_t physical_address,
|
||||
u32_t user_mode, u32_t writable)
|
||||
{
|
||||
u32_t directory_index = (virtual_address >> 22) & 0x3FF;
|
||||
u32_t table_index = (virtual_address >> 12) & 0x3FF;
|
||||
pagedirectory_entry_t * page_dir = page_directory;
|
||||
page_dir = (pagedirectory_entry_t *)((u32_t)page_dir + KERNEL_OFFSET);
|
||||
|
||||
mm_use_virtual_offset = false;
|
||||
if (page_dir[directory_index] == 0)
|
||||
{
|
||||
/* allocate a new page table */
|
||||
u32_t page_table_address = mm_early_page_alloc();
|
||||
if (page_table_address == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
page_dir[directory_index] = page_table_address
|
||||
| 0x1 << 2 /* PTs can be user mode */
|
||||
| 0x1 << 1 /* writable */
|
||||
| 0x1; /* present */
|
||||
}
|
||||
u32_t page_table_address = page_dir[directory_index] & PAGE_HIGH_MASK;
|
||||
|
||||
u32_t * page_table = (u32_t *) page_table_address;
|
||||
page_table = (u32_t *)((u32_t)page_table + (u32_t)KERNEL_OFFSET);
|
||||
|
||||
page_table[table_index] = (physical_address & PAGE_HIGH_MASK)
|
||||
| (user_mode & 0x1) << 2
|
||||
| (writable & 0x1) << 1
|
||||
| 0x1; /* present */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
@ -174,10 +206,6 @@ int mm_map(u32_t virtual_address, u32_t physical_address,
|
||||
u32_t directory_index = (virtual_address >> 22) & 0x3FF;
|
||||
u32_t table_index = (virtual_address >> 12) & 0x3FF;
|
||||
pagedirectory_entry_t * page_dir = page_directory;
|
||||
if (mm_use_virtual_offset)
|
||||
{
|
||||
page_dir = (pagedirectory_entry_t *)((u32_t)page_dir + KERNEL_OFFSET);
|
||||
}
|
||||
|
||||
if (page_dir[directory_index] == 0)
|
||||
{
|
||||
@ -195,10 +223,6 @@ int mm_map(u32_t virtual_address, u32_t physical_address,
|
||||
u32_t page_table_address = page_dir[directory_index] & PAGE_HIGH_MASK;
|
||||
|
||||
u32_t * page_table = (u32_t *) page_table_address;
|
||||
if (mm_use_virtual_offset)
|
||||
{
|
||||
page_table = (u32_t *)((u32_t)page_table + (u32_t)KERNEL_OFFSET);
|
||||
}
|
||||
|
||||
page_table[table_index] = (physical_address & PAGE_HIGH_MASK)
|
||||
| (user_mode & 0x1) << 2
|
||||
@ -211,22 +235,38 @@ int mm_map(u32_t virtual_address, u32_t physical_address,
|
||||
/**************************************************************************
|
||||
* Returns the physical base address of a page in RAM *
|
||||
* or 0 if no pages were available *
|
||||
* This 'early' version is to be called during segmented bootstrapping *
|
||||
*************************************************************************/
|
||||
u32_t mm_page_alloc()
|
||||
u32_t mm_early_page_alloc()
|
||||
{
|
||||
if (mm_free_page_ptr == NULL)
|
||||
u32_t page_address = 0;
|
||||
if (mm_free_page_ptr != NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
u32_t * page_ptr = mm_free_page_ptr;
|
||||
if (mm_use_virtual_offset)
|
||||
{
|
||||
page_ptr = (u32_t *) ((u32_t)page_ptr + (u32_t)KERNEL_OFFSET);
|
||||
}
|
||||
u32_t page_address = (u32_t) mm_free_page_ptr;
|
||||
page_address = (u32_t) mm_free_page_ptr;
|
||||
mm_free_page_ptr = (u32_t *) *page_ptr;
|
||||
mm_num_free_pages--;
|
||||
mm_num_used_pages++;
|
||||
}
|
||||
return page_address;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Returns the physical base address of a page in RAM *
|
||||
* or 0 if no pages were available *
|
||||
*************************************************************************/
|
||||
u32_t mm_page_alloc()
|
||||
{
|
||||
u32_t page_address = 0;
|
||||
if (mm_free_page_ptr != NULL)
|
||||
{
|
||||
u32_t * page_ptr = mm_free_page_ptr;
|
||||
page_address = (u32_t) mm_free_page_ptr;
|
||||
mm_free_page_ptr = (u32_t *) *page_ptr;
|
||||
mm_num_free_pages--;
|
||||
mm_num_used_pages++;
|
||||
}
|
||||
return page_address;
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,12 @@ typedef struct
|
||||
void mm_record_mmap_entry(mb_mmap_t * mmap);
|
||||
void mm_bootstrap();
|
||||
|
||||
int mm_early_map(u32_t virtual_address, u32_t physical_address,
|
||||
u32_t user_mode, u32_t writable);
|
||||
int mm_map(u32_t virtual_address, u32_t physical_address,
|
||||
u32_t user_mode, u32_t writable);
|
||||
|
||||
u32_t mm_early_page_alloc();
|
||||
u32_t mm_page_alloc();
|
||||
|
||||
typedef struct
|
||||
|
@ -9,6 +9,6 @@ void stack_bootstrap()
|
||||
* running from our temporary stack while segmentation is enabled,
|
||||
* set up the "permanent" stack for use while paging
|
||||
*/
|
||||
u32_t first_stack_page_base = mm_page_alloc();
|
||||
mm_map(KERNEL_STACK_TOP - PAGE_SIZE, first_stack_page_base, 0, 1);
|
||||
u32_t first_stack_page_base = mm_early_page_alloc();
|
||||
mm_early_map(KERNEL_STACK_TOP - PAGE_SIZE, first_stack_page_base, 0, 1);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user