aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2021-03-11 15:59:21 +0200
committerAqua-sama <aqua@iserlohn-fortress.net>2021-03-11 15:59:21 +0200
commita7f8049a8126b6fd1565bcde77700ffeca5d4317 (patch)
tree1e5afb65e45ea548ed9a02ac753ba0973710b785
parentAdd linker script to ld depends (diff)
downloadkernel.cpp-a7f8049a8126b6fd1565bcde77700ffeca5d4317.tar.xz
Map kernel to 0xc000 rather than 0xc010
-rw-r--r--linker.ld13
-rw-r--r--src/boot.S96
2 files changed, 51 insertions, 58 deletions
diff --git a/linker.ld b/linker.ld
index 9383b44..a9c6ec8 100644
--- a/linker.ld
+++ b/linker.ld
@@ -14,12 +14,11 @@ SECTIONS
*(.multiboot.header)
}
- /* Begin putting sections at 1 MiB */
- /* TODO load sections at VADDR_BASE rather than at VADDR_BASE + 1M */
- . = VADDR_BASE + 1M;
+ /* Begin putting sections at 4 MiB */
+ . = VADDR_BASE;
_kernel_start = .;
- .text ALIGN(4K) : AT(ADDR(.text) - VADDR_BASE) {
+ .text ALIGN(4K) : AT(ADDR(.text) - VADDR_BASE + 4M) {
begin_text = .;
*(.multiboot.text)
*(.text*)
@@ -27,14 +26,14 @@ SECTIONS
}
/* Read-only data. */
- .rodata ALIGN(4K) : AT(ADDR(.rodata) - VADDR_BASE) {
+ .rodata ALIGN(4K) : AT(ADDR(.rodata) - VADDR_BASE + 4M) {
begin_rodata = .;
*(.rodata*)
end_rodata = .;
}
/* Read-write data (initialized) */
- .data ALIGN(4K) : AT(ADDR(.data) - VADDR_BASE) {
+ .data ALIGN(4K) : AT(ADDR(.data) - VADDR_BASE + 4M) {
begin_constinit = .;
*(.constinit)
end_constinit = .;
@@ -49,7 +48,7 @@ SECTIONS
}
/* Read-write data (uninitialized) and stack */
- .bss ALIGN(4K) : AT(ADDR(.bss) - VADDR_BASE) {
+ .bss ALIGN(4K) : AT(ADDR(.bss) - VADDR_BASE + 4M) {
begin_bss = .;
*(.pages)
*(.bss)
diff --git a/src/boot.S b/src/boot.S
index 23c1e25..6588004 100644
--- a/src/boot.S
+++ b/src/boot.S
@@ -39,90 +39,84 @@ stack_top:
.section .pages, "aw", @nobits
.align 4096
boot_page_directory:
- .skip 4096
+ .skip 1024 * 4
boot_page_table1:
- .skip 4096
+ .skip 1024 * 4
/*
The linker script specifies _start as the entry point to the kernel and the
bootloader will jump to this position once the kernel has been loaded.
-*/
+ */
.section .multiboot.text, "ax"
-.set VADDR_BASE, 0xc0000000
+.set VADDR_OFFSET, 0xc0000000 - 0x400000
.global _start
.type _start, @function
_start:
cli
# Physical address of boot_page_table1.
- movl $(boot_page_table1 - VADDR_BASE), %edi
- # First address to map is address 0.
- movl $0, %esi
+ movl $(boot_page_table1 - VADDR_OFFSET), %edi
+
+ # Only map the kernel.
+ mov $_kernel_start - VADDR_OFFSET, %esi
# Map 1023 pages. The 1024th will be the VGA text buffer.
movl $1023, %ecx
-1:
- # Only map the kernel.
- cmpl $_kernel_start, %esi
- jl 2f
- cmpl $(_kernel_end - VADDR_BASE), %esi
- jge 3f
+l_page_init:
+ cmpl $(_kernel_end - VADDR_OFFSET), %esi
+ jge map_vga
- # Map physical address as "present, writable". Note that this maps
- # .text and .rodata as writable. Mind security and map them as non-writable.
+ /* TODO: Map physical address as "present, writable". Note that this maps .text and .rodata as writable.
+ Mind security and map them as non-writable. */
movl %esi, %edx
orl $0x003, %edx
movl %edx, (%edi)
-2:
# Size of page is 4096 bytes.
addl $4096, %esi
# Size of entries in boot_page_table1 is 4 bytes.
addl $4, %edi
# Loop to the next entry if we haven't finished.
- loop 1b
-
-3:
- # Map VGA video memory to 0xC03FF000 as "present, writable".
- movl $(0x000B8000 | 0x003), boot_page_table1 - VADDR_BASE + 1023 * 4
-
- # The page table is used at both page directory entry 0 (virtually from 0x0
- # to 0x3FFFFF) (thus identity mapping the kernel) and page directory entry
- # 768 (virtually from VADDR_BASE to 0xC03FFFFF) (thus mapping it in the
- # higher half). The kernel is identity mapped because enabling paging does
- # not change the next instruction, which continues to be physical. The CPU
- # would instead page fault if there was no identity mapping.
-
- # Map the page table to both virtual addresses 0x00000000 and VADDR_BASE.
- movl $(boot_page_table1 - VADDR_BASE + 0x003), boot_page_directory - VADDR_BASE + 0
- movl $(boot_page_table1 - VADDR_BASE + 0x003), boot_page_directory - VADDR_BASE + 768 * 4
+ loop l_page_init
- # Set cr3 to the address of the boot_page_directory.
- movl $(boot_page_directory - VADDR_BASE), %ecx
- movl %ecx, %cr3
+map_vga:
+ # Map VGA video memory to 0xC03FF000 as "present, writable".
+ movl $(0x000B8000 | 0x003), boot_page_table1 - VADDR_OFFSET + 1023 * 4
- # Enable paging and the write-protect bit.
- movl %cr0, %ecx
- orl $0x80010000, %ecx
- movl %ecx, %cr0
-
- # Jump to higher half with an absolute jump.
- lea (kinit), %ecx
- jmp *%ecx
+/*
+ Enabling paging does not change the next instruction, which continues to be physical. Therefore, map the kernel
+ to both its physical address and to the higher half.
+ Use the page table at:
+ - entry 1 starts 0x0040 0000 ends 0x007f ffff
+ - entry 768 starts 0xc000 0000 ends 0xc03f ffff
+ */
+ movl $(boot_page_table1 - VADDR_OFFSET + 0x003), boot_page_directory - VADDR_OFFSET + 1 * 4
+ movl $(boot_page_table1 - VADDR_OFFSET + 0x003), boot_page_directory - VADDR_OFFSET + 768 * 4
+
+ # Set cr3 to the address of the boot_page_directory.
+ movl $(boot_page_directory - VADDR_OFFSET), %ecx
+ movl %ecx, %cr3
+
+ # Enable paging and the write-protect bit.
+ movl %cr0, %ecx
+ orl $0x80010000, %ecx
+ movl %ecx, %cr0
+
+ # Jump to higher half with an absolute jump.
+ lea (kinit), %ecx
+ jmp *%ecx
.section .text
.extern kernel_constructors
.extern kernel_main
kinit:
- # At this point, paging is fully set up and enabled.
-
- # Unmap the identity mapping as it is now unnecessary.
- movl $0, boot_page_directory + 0
-
- # Reload crc3 to force a TLB flush so the changes to take effect.
- movl %cr3, %ecx
- movl %ecx, %cr3
+ # At this point, paging is fully set up and enabled.
+ # Unmap the identity mapping as it is now unnecessary.
+ movl $0, boot_page_directory + 1 * 4
+ # Reload crc3 to force a TLB flush so the changes to take effect.
+ movl %cr3, %ecx
+ movl %ecx, %cr3
#mov $stack_bottom, %ebp
mov $stack_top, %esp # point the stack pointer to the stack