mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 20:47:45 +00:00
Kernel: Move Kernel mapping to 0xc0000000
The kernel is now no longer identity mapped to the bottom 8MiB of memory, and is now mapped at the higher address of `0xc0000000`. The lower ~1MiB of memory (from GRUB's mmap), however is still identity mapped to provide an easy way for the kernel to get physical pages for things such as DMA etc. These could later be mapped to the higher address too, as I'm not too sure how to go about doing this elegantly without a lot of address subtractions.
This commit is contained in:
parent
61ba19f031
commit
bd33c66273
13 changed files with 132 additions and 64 deletions
|
@ -34,9 +34,9 @@ stack_top:
|
|||
.section .page_tables
|
||||
.align 4096
|
||||
page_tables_start:
|
||||
.skip 4096*3
|
||||
.skip 4096*5
|
||||
|
||||
.section .text
|
||||
.section .text.boot
|
||||
|
||||
.global start
|
||||
.type start, @function
|
||||
|
@ -51,13 +51,79 @@ start:
|
|||
cli
|
||||
cld
|
||||
|
||||
# We first save the multiboot_info_ptr so it doesn't get trampled
|
||||
addl $0xc0000000, %ebx
|
||||
movl %ebx, multiboot_info_ptr - 0xc0000000
|
||||
|
||||
# First, let's set up the first page table to map the the first 4MiB of memory.
|
||||
# This makes sure we don't crash after we set CR3 and enable paging
|
||||
movl $0x200, %ecx
|
||||
xor %ebx, %ebx
|
||||
movl $((page_tables_start + (4096 * 1)) - 0xc0000000), %edx
|
||||
call make_table
|
||||
|
||||
# Now we create the kernel mappings. The kernel maps 0MiB -> 8MiB into its address space at
|
||||
# v0xc0000000.
|
||||
movl $0x400, %ecx
|
||||
movl $0x0, %ebx # ebx is the base pointer (kernel base is at physical address 0 in this case)
|
||||
movl $((page_tables_start + (4096 * 2)) - 0xc0000000), %edx
|
||||
call make_table
|
||||
|
||||
movl $0x400, %ecx
|
||||
movl $0x400000, %ebx # ebx is the base pointer (kernel base is at physical address 0 in this case)
|
||||
movl $((page_tables_start + (4096 * 3)) - 0xc0000000), %edx
|
||||
call make_table
|
||||
|
||||
|
||||
# Okay, so we have a page table that contains addresses of the first 4MiB of memory. Let's insert this into the
|
||||
# boot page directory. The index we need to insert it into is at vaddr >> 22, which is the page directory index.
|
||||
# This reveals that we need to insert the page directory into 0xc0000000 >> 22 = 768
|
||||
# An interesting quirk is that we must also identity map the first 4MiB too, as the next instruction after enabling
|
||||
# paging is at a physical address, which cause a page fault. As we have no handler, this would cause a triple fault.
|
||||
movl $((page_tables_start + (4096 * 1)) - 0xc0000000 + 0x003), page_tables_start - 0xc0000000 + 0
|
||||
movl $((page_tables_start + (4096 * 2)) - 0xc0000000 + 0x003), page_tables_start - 0xc0000000 + 768 * 4
|
||||
movl $((page_tables_start + (4096 * 3)) - 0xc0000000 + 0x003), page_tables_start - 0xc0000000 + 769 * 4
|
||||
|
||||
# Now let's load the CR3 register with our page directory
|
||||
movl $(page_tables_start - 0xc0000000), %ecx
|
||||
movl %ecx, %cr3
|
||||
|
||||
# Let's enable paging!
|
||||
movl %cr0, %ecx
|
||||
orl $0x80000001, %ecx
|
||||
movl %ecx, %cr0
|
||||
|
||||
lea high_address_space_start, %ecx
|
||||
jmp *%ecx
|
||||
|
||||
|
||||
# Make a page table. This is called with the following arguments:
|
||||
# ebx = base pointer of mapping
|
||||
# edx = page table physical address
|
||||
# ecx = number of pages to map
|
||||
#
|
||||
# Registers used in function
|
||||
# eax = loop counter
|
||||
make_table:
|
||||
xorl %eax, %eax
|
||||
.loop:
|
||||
pushl %ecx
|
||||
movl %ebx, %ecx
|
||||
orl $0x3, %ecx # addr | READ_WRITE | PAGE_PRESENT
|
||||
movl %ecx, 0(%edx, %eax, 4)
|
||||
addl $0x1000, %ebx
|
||||
inc %eax
|
||||
popl %ecx
|
||||
loop .loop
|
||||
ret
|
||||
|
||||
# At this point, the CPU now starts reading instructions from (virtual) address 0xc00100000
|
||||
high_address_space_start:
|
||||
mov $stack_top, %esp
|
||||
|
||||
and $-16, %esp
|
||||
|
||||
mov %ebx, multiboot_info_ptr
|
||||
|
||||
pushl $page_tables_start
|
||||
pushl $(page_tables_start - 0xc0000000)
|
||||
call init
|
||||
add $4, %esp
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#define PAGE_SIZE 4096
|
||||
#define PAGE_MASK 0xfffff000
|
||||
|
||||
static const u32 kernel_virtual_base = 0xc0000000;
|
||||
|
||||
class MemoryManager;
|
||||
class PageTableEntry;
|
||||
|
||||
|
@ -89,6 +91,7 @@ class PageDirectoryEntry {
|
|||
|
||||
public:
|
||||
PageTableEntry* page_table_base() { return reinterpret_cast<PageTableEntry*>(m_raw & 0xfffff000u); }
|
||||
PageTableEntry* page_table_virtual_base() { return reinterpret_cast<PageTableEntry*>((m_raw + kernel_virtual_base) & 0xfffff000u); }
|
||||
void set_page_table_base(u32 value)
|
||||
{
|
||||
m_raw &= 0xfff;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue