From d7889d3a847d1d692febdce78a28bf7a984fd25a Mon Sep 17 00:00:00 2001 From: Kat Richey Date: Sat, 29 Oct 2022 10:03:56 -0500 Subject: [PATCH] Higher half, baby!!! --- arch/i386/boot.S | 79 +++++++++++++++++++++++++++++++++++++++++---- arch/i386/linker.ld | 28 +++++++++++----- 2 files changed, 93 insertions(+), 14 deletions(-) diff --git a/arch/i386/boot.S b/arch/i386/boot.S index c28621b..13d29fd 100755 --- a/arch/i386/boot.S +++ b/arch/i386/boot.S @@ -6,25 +6,93 @@ .set CHECKSUM, -(MAGIC + FLAGS) # checksum to prove we're multiboot # Declare header for multiboot - .section .multiboot + .section .multiboot.data, "aw" .align 4 .long MAGIC .long FLAGS .long CHECKSUM # Reserve stack for initial thread - .section .bss - .align 16 + .section .bootstrap_stack, "aw", @nobits stack_bottom: .skip 16384 # 16K stack_top: + # Preallocate pages for paging + .section .bss, "aw", @nobits + .align 4096 +boot_page_directory: + .skip 4096 +boot_page_table1: + .skip 4096 + # May need additional page for kernel > 3 MiB + # Kernel entry - .section .text + .section .multiboot.text, "a" .global _start .type _start, @function _start: - movl $stack_top, %esp + # Physical address of boot_page_table 1 + movl $(boot_page_table1 - 0xC0000000), %edi + # Map address 0 + movl $0, %esi + # Map first 1023 pages + movl $1023, %ecx + +1: + # Only map the kernel + cmpl $_kernel_start, %esi + jl 2f + cmpl $(_kernel_end - 0xC0000000), %esi + jge 3f + + # Map physical address as "present, writable" + # TODO: map .text and .rodata as non-writable + movl %esi, %edx + orl $0x003, %edx + movl %edx, (%edi) + +2: + # Size of page is 4KiB + addl $4096, %esi + # Size of entries in boot_page_table1 is 4 bytes + addl $4, %edi + # Loop to next if not done + loop 1b + +3: + # Map VGA memory to 0xC03FF000 as "present, writable" + movl $(0x000B8000 | 0x003), boot_page_table1 - 0xC0000000 + 1023 * 4 + + # Map page table to 0x0 and 0xC0000000 + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0 + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4 + + # Set cr3 to address of boot page directory + movl $(boot_page_directory - 0xC0000000), %ecx + movl %ecx, %cr3 + + # Enable paging and write-protect + movl %cr0, %ecx + orl $0x80010000, %ecx + movl %ecx, %cr0 + + # Jump to higher half + lea 4f, %ecx + jmp *%ecx + + .section .text + +4: + # Unmap identity mapping + movl $0, boot_page_directory + 0 + + # Reload cr3 to force TLB flush + movl %cr3, %ecx + movl %ecx, %cr3 + + # Set up stack + mov $stack_top, %esp # Call global constructors call _init @@ -36,4 +104,3 @@ _start: cli 1: hlt jmp 1b - .size _start, . - _start diff --git a/arch/i386/linker.ld b/arch/i386/linker.ld index d766d45..9a020c5 100755 --- a/arch/i386/linker.ld +++ b/arch/i386/linker.ld @@ -4,21 +4,33 @@ SECTIONS { . = 1M; - .text BLOCK (4K) : ALIGN (4K) { - *(.multiboot) - *(.text) + _kernel_start = .; + .multiboot.data : { + *(.multiboot.data) + } + + .multiboot.text : { + *(.multiboot.text) + } + + . += 0xC0000000; + + .text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000) { + *(.text) } - .rodata BLOCK (4K) : ALIGN (4K) { + .rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000) { *(.rodata) } - .data BLOCK (4K) : ALIGN (4K) { - *(.data) + .data ALIGN (4K) : AT (ADDR(.data) - 0xC0000000) { + *(.data) } - .bss BLOCK (4K) : ALIGN (4K) { - *(COMMON) + .bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000) { + *(COMMON) *(.bss) + *(.bootstrap_stack) } + _kernel_end = .; }