diff options
| author | Aleksa Vučković <aleksav013@gmail.com> | 2022-06-29 01:52:48 +0200 |
|---|---|---|
| committer | Aleksa Vučković <aleksav013@gmail.com> | 2022-06-29 16:44:25 +0200 |
| commit | 1f57e99720c4bc5e3e27a88ff469cef43c202a43 (patch) | |
| tree | 8161bd72d272009a520dd173eac3658a48a9f096 | |
| parent | 58240b0509d11b09ce2994b88308650e7cfb93bd (diff) | |
HigherHalf
| -rw-r--r-- | Makefile | 6 | ||||
| -rw-r--r-- | src/as/boot.s | 119 | ||||
| -rw-r--r-- | src/as/paging.s | 20 | ||||
| -rw-r--r-- | src/c/kernel.c | 2 | ||||
| -rw-r--r-- | src/c/paging.c | 24 | ||||
| -rw-r--r-- | src/c/shell/game.c | 8 | ||||
| -rw-r--r-- | src/c/vga.c | 3 | ||||
| -rw-r--r-- | src/include/source/paging.h | 1 | ||||
| -rw-r--r-- | src/linker.ld | 70 |
9 files changed, 178 insertions, 75 deletions
@@ -18,9 +18,9 @@ export CFLAGS=-std=gnu99 -O3 $(WARNINGS) -ffreestanding -fstack-protector-all export MKDIR=mkdir -p export RM=rm -rf export CP=cp -r -QEMU=qemu-system-x86_64 +QEMU=qemu-system-i386 QEMU_FLAGS=-enable-kvm -QEMU_DEBUG= +QEMU_DEBUG=-s @@ -105,4 +105,4 @@ run: compile $(QEMU) $(QEMU_FLAGS) -kernel $(BINARY) $(QEMU_DEBUG) run-iso: iso - $(QEMU) $(QEMU_FLAGS) -cdrom $(ISO) + $(QEMU) $(QEMU_FLAGS) -cdrom $(ISO) $(QEMU_DEBUG) diff --git a/src/as/boot.s b/src/as/boot.s index f65cc72..adb24b7 100644 --- a/src/as/boot.s +++ b/src/as/boot.s @@ -1,42 +1,125 @@ -.set ALIGN, 1<<0 -.set MEMINFO, 1<<1 -.set FLAGS, ALIGN | MEMINFO -.set MAGIC, 0x1BADB002 -.set CHECKSUM, -(MAGIC + FLAGS) +# Declare constants for the multiboot header. +.set ALIGN, 1<<0 # align loaded modules on page boundaries +.set MEMINFO, 1<<1 # provide memory map +.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field +.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header +.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot -.section .multiboot +# Declare a multiboot header that marks the program as a kernel. +.section .multiboot.data, "aw" .align 4 .long MAGIC .long FLAGS .long CHECKSUM -.set CODE_SEGMENT, 0x08 -.set DATA_SEGMENT, 0x10 - -.section .bss -.align 16 +# Allocate the initial stack. +.section .bootstrap_stack, "aw", @nobits stack_bottom: -.skip 16384 +.skip 16384 # 16 KiB stack_top: -.section .text +# Preallocate pages used for paging. Don't hard-code addresses and assume they +# are available, as the bootloader might have loaded its multiboot structures or +# modules there. This lets the bootloader know it must avoid the addresses. +.section .bss, "aw", @nobits + .align 4096 +boot_page_directory: + .skip 4096 +boot_page_table1: + .skip 4096 +boot_page_table2: + .skip 4096 +# Further page tables may be required if the kernel grows beyond 3 MiB. + +# The kernel entry point. +.section .multiboot.text, "a" .global _start .type _start, @function _start: + movl $(boot_page_table1 - 0xC0000000), %edi + movl $0, %esi + +1: + jl 2f + cmpl $0x00400000, %esi + jge 3f + + 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: + movl $(boot_page_table2 - 0xC0000000), %edi + +4: + jl 5f + cmpl $0x00800000, %esi + jge 6f + + movl %esi, %edx + orl $0x003, %edx + movl %edx, (%edi) + +5: + # 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 4b + +6: + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0 * 4 + movl $(boot_page_table2 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 1 * 4 + movl $(boot_page_table1 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4 + movl $(boot_page_table2 - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 769 * 4 + + # Set cr3 to the address of the boot_page_directory. + movl $(boot_page_directory - 0xC0000000), %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 7f, %ecx + jmp *%ecx + +.section .text + +7: + # 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 + movl $0, boot_page_directory + 4 + + # Reload crc3 to force a TLB flush so the changes to take effect. + movl %cr3, %ecx + movl %ecx, %cr3 + + movl $stack_top, %esp call init_gdt_table - ljmp $CODE_SEGMENT, $code + ljmp $0x08, $code code: - movw $DATA_SEGMENT, %ax + movw $0x10, %ax movw %ax, %ds movw %ax, %es movw %ax, %fs movw %ax, %gs movw %ax, %ss - movl $stack_top, %esp cli call _init call kernel_main hlt - -.size _start, . - _start diff --git a/src/as/paging.s b/src/as/paging.s index e1cf42a..c3a9a0d 100644 --- a/src/as/paging.s +++ b/src/as/paging.s @@ -1,14 +1,16 @@ +.text + .global loadPageDirectory loadPageDirectory: push %ebp - mov %esp, %ebp - mov 8(%esp), %eax - mov %eax, %cr3 + movl %esp, %ebp + movl 8(%esp), %eax + subl $0xC0000000, %eax + movl %eax, %cr3 mov %ebp, %esp pop %ebp ret -.text .global enablePaging enablePaging: push %ebp @@ -19,3 +21,13 @@ enablePaging: mov %ebp, %esp pop %ebp ret + +.global flushPaging +flushPaging: + push %ebp + mov %esp, %ebp + movl %cr3, %ecx + movl %ecx, %cr3 + mov %ebp, %esp + pop %ebp + ret diff --git a/src/c/kernel.c b/src/c/kernel.c index a5dc31a..9692b32 100644 --- a/src/c/kernel.c +++ b/src/c/kernel.c @@ -14,7 +14,7 @@ void kernel_main(void) init_timer(50); init_keyboard(); kheapinit(); - kheapaddblock(0x00200000, 0x00100000, 16); + kheapaddblock(0xC0700000, 0x00100000, 16); terminal_initialize(); prompt(); diff --git a/src/c/paging.c b/src/c/paging.c index 4aba4af..0a4c01f 100644 --- a/src/c/paging.c +++ b/src/c/paging.c @@ -3,6 +3,7 @@ extern void loadPageDirectory(uint32_t*); extern void enablePaging(void); +extern void flushPaging(void); uint32_t page_directory[1024] __attribute__((aligned(4096))); @@ -23,11 +24,6 @@ uint32_t page_table[1024][1024] __attribute__((aligned(4096))); void set_pt(size_t num,uint32_t address) { - // holds the physical address where we want to start mapping these pages - // to. - // in this case, we want to map these pages to the very beginning of - // memory. - //we will fill all 1024 entries in the table, mapping 4 megabytes for(size_t i=0;i<1024;i++) { @@ -37,14 +33,26 @@ void set_pt(size_t num,uint32_t address) // attributes: supervisor level, read/write, present. } - page_directory[num] = ((uint32_t)page_table[num]) | 3; + page_directory[num] = ((uint32_t)page_table[num] - 0xC0000000) | 3; // attributes: supervisor level, read/write, present } +void empty_pt(size_t num) +{ + for(size_t i=0;i<1024;i++) + { + page_table[num][i] = 0; + } + + page_directory[num] = 0x00000002; +} + void set_paging(void) { set_pd(); - for(size_t i=0;i<1024;i++) set_pt(i,0x00400000 * i); // all 4GB mapped + set_pt(768,0x00000000); // maps 0x00000000 to 0xC0000000 + set_pt(769,0x00400000); // maps 0x00400000 to 0xC0400000 + set_pt(832,0x000B8000); // maps 0x000B8000 to 0xD0000000 loadPageDirectory(page_directory); - enablePaging(); + flushPaging(); } diff --git a/src/c/shell/game.c b/src/c/shell/game.c index ce7793b..9e7323e 100644 --- a/src/c/shell/game.c +++ b/src/c/shell/game.c @@ -56,8 +56,8 @@ void game_keyboard_handler(uint16_t keycode) void game_init(void) { - x=VGA_WIDTH/2; - y=VGA_HEIGHT/2; + x=(uint16_t)VGA_WIDTH/2; + y=(uint16_t)VGA_HEIGHT/2; game_time=0; game_tick=0; duzina=1; @@ -80,7 +80,7 @@ void game_timer_handler() { case 1: if(y>0) y--; - else y=VGA_HEIGHT-1; + else y=(uint16_t)VGA_HEIGHT-1; break; case 2: if(y<VGA_HEIGHT-1) y++; @@ -88,7 +88,7 @@ void game_timer_handler() break; case 3: if(x>0) x--; - else x=VGA_WIDTH-1; + else x=(uint16_t)VGA_WIDTH-1; break; case 4: if(x<VGA_WIDTH-1) x++; diff --git a/src/c/vga.c b/src/c/vga.c index 84eb538..4e20745 100644 --- a/src/c/vga.c +++ b/src/c/vga.c @@ -27,7 +27,8 @@ void terminal_initialize(void) terminal_row=0; terminal_column=0; set_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); - terminal_buffer=(uint16_t*) 0xB8000; + //terminal_buffer=(uint16_t*) 0xC00B8000; + terminal_buffer=(uint16_t*) 0xD0000000; for(size_t y=0;y<VGA_HEIGHT;y++) { for(size_t x=0;x<VGA_WIDTH;x++) diff --git a/src/include/source/paging.h b/src/include/source/paging.h index dc4e357..f236365 100644 --- a/src/include/source/paging.h +++ b/src/include/source/paging.h @@ -5,6 +5,7 @@ void set_pd(void); void set_pt(size_t num, uint32_t address); +void empty_pt(size_t num); void set_paging(void); #endif diff --git a/src/linker.ld b/src/linker.ld index d8e7f4b..54437ba 100644 --- a/src/linker.ld +++ b/src/linker.ld @@ -1,43 +1,41 @@ -/* The bootloader will look at this image and start execution at the symbol - designated as the entry point. */ -ENTRY(_start) +ENTRY (_start) -/* Tell where the various sections of the object files will be put in the final - kernel image. */ SECTIONS { - /* Begin putting sections at 1 MiB, a conventional place for kernels to be - loaded at by the bootloader. */ - . = 1M; + . = 0x00100000; + /* The kernel will live at 3GB + 1MB in the virtual address space, */ + /* which will be mapped to 1MB in the physical address space. */ + /* Note that we page-align the sections. */ - /* First put the multiboot header, as it is required to be put very early - early in the image or the bootloader won't recognize the file format. - Next we'll put the .text section. */ - .text BLOCK(4K) : ALIGN(4K) - { - *(.multiboot) - *(.text) - } + _kernel_start = .; + .multiboot.data : { + *(.multiboot.data) + } - /* Read-only data. */ - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } + .multiboot.text : { + *(.multiboot.text) + } - /* Read-write data (initialized) */ - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - - /* Read-write data (uninitialized) and stack */ - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } - - /* The compiler may produce other sections, by default it will put them in - a segment with the same name. Simply add stuff here as needed. */ + . += 0xC0000000; + /* Add a symbol that indicates the start address of the kernel. */ + .text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000) + { + *(.text) + } + .rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000) + { + *(.rodata) + } + .data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000) + { + *(.data) + } + .bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000) + { + *(COMMON) + *(.bss) + *(.bootstrap_stack) + } + /* Add a symbol that indicates the end address of the kernel. */ + _kernel_end = .; } |
