From 348aa69dcb33c487e50cb668742ae8c4ce95370c Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 18 Oct 2022 00:19:44 +0300 Subject: [PATCH] 32bit booting working --- Architecture/i686/MultibootInit.cpp | 43 ----------------- Architecture/i686/boot.asm | 73 ++++++++++++++++++++--------- Architecture/i686/linker.ld | 36 +++----------- Kernel.cpp | 36 ++++++++++++-- 4 files changed, 89 insertions(+), 99 deletions(-) delete mode 100644 Architecture/i686/MultibootInit.cpp diff --git a/Architecture/i686/MultibootInit.cpp b/Architecture/i686/MultibootInit.cpp deleted file mode 100644 index feb4055..0000000 --- a/Architecture/i686/MultibootInit.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include - -#include - -struct multiboot_info -{ - multiboot_uint32_t Size; - multiboot_uint32_t Reserved; - struct multiboot_tag *Tag; -}; - -EXTERNC __attribute__((no_stack_protector, section(".mb2bootcode.text"))) void Multiboot2Initializator(multiboot_info *Info, unsigned int Magic) -{ - if (Info == NULL || Magic == NULL) - { - if (Magic == NULL) - { - ((unsigned char *)0xb8000)[2 * (80) * (25) - 4] = 'E'; - ((unsigned char *)0xb8000)[2 * (80) * (25) - 3] = 4; - } - if (Info == NULL) - { - ((unsigned char *)0xb8000)[2 * (80) * (25) - 2] = 'R'; - ((unsigned char *)0xb8000)[2 * (80) * (25) - 1] = 4; - } - while (1) - asmv("hlt"); - } - else if (Magic != MULTIBOOT2_BOOTLOADER_MAGIC) - { - ((unsigned char *)0xb8000)[2 * (80) * (25) - 2] = 'M'; - ((unsigned char *)0xb8000)[2 * (80) * (25) - 1] = 4; - while (1) - asmv("hlt"); - } - - /* TODO */ - - ((unsigned char *)0xb8000)[2 * (80) * (25) - 2] = 'Y'; - ((unsigned char *)0xb8000)[2 * (80) * (25) - 1] = 2; - while (1) - asmv("hlt"); -} diff --git a/Architecture/i686/boot.asm b/Architecture/i686/boot.asm index 9339f74..16d7477 100644 --- a/Architecture/i686/boot.asm +++ b/Architecture/i686/boot.asm @@ -1,33 +1,60 @@ -KERNEL_VIRTUAL_BASE EQU 0xE0000000 - +; Inspired From: https://github.com/MQuy/mos/blob/master/src/kernel/boot.asm section .multiboot2 -align 8 +align 4096 HEADER_START: - dd 0xE85250D6 - dd 0 - dd (HEADER_END - HEADER_START) - dd -(0xE85250D6 + 0 + (HEADER_END - HEADER_START)) + dd 0xE85250D6 + dd 0 + dd (HEADER_END - HEADER_START) + dd 0x100000000 - (HEADER_END - HEADER_START) - 0 - 0xE85250D6 align 8 MB2_TAG_START: - dw 0 - dw 0 - dd MB2_TAG_END - MB2_TAG_START + dw 0 + dw 0 + dd MB2_TAG_END - MB2_TAG_START MB2_TAG_END: HEADER_END: -extern Multiboot2Initializator +KERNEL_VIRTUAL_BASE equ 0xC0000000 ; 3GB +KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22) ; 768 +KERNEL_STACK_SIZE equ 0x4000 ; 16KB + +extern x32Entry global _start -_start: - cli - mov esp, STACK_TOP - push eax - push ebx - call Multiboot2Initializator -.Hang: - hlt - jmp .Hang +section .data +align 0x1000 +BootPageTable: + dd 0x00000083 + times (KERNEL_PAGE_NUMBER - 1) dd 0 + dd 0x00000083 + times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0 -section .mb2bootcode.bss -STACK_BOTTOM: resb 16384 -STACK_TOP: +section .text +_start: + mov ecx, (BootPageTable - KERNEL_VIRTUAL_BASE) + mov cr3, ecx + mov ecx, cr4 + or ecx, 0x00000010 ; Set PSE in CR4 + mov cr4, ecx + mov ecx, cr0 + or ecx, 0x80000000 ; Set PG in CR0 + mov cr0, ecx + lea ecx, [HigherHalfStart] + jmp ecx + +HigherHalfStart: + mov esp, KernelStack + KERNEL_STACK_SIZE + + push eax ; Multiboot2 Magic + add ebx, KERNEL_VIRTUAL_BASE + push ebx ; Multiboot2 Header + call x32Entry +Loop: + hlt + jmp Loop + + +section .bss +align 16 +KernelStack : + resb KERNEL_STACK_SIZE diff --git a/Architecture/i686/linker.ld b/Architecture/i686/linker.ld index 2a25dea..d604c42 100644 --- a/Architecture/i686/linker.ld +++ b/Architecture/i686/linker.ld @@ -3,55 +3,31 @@ OUTPUT_ARCH(i386) ENTRY(_start) -KERNEL_VIRTUAL_BASE = 0xC0000000; - SECTIONS { - . = 1M; - - .boot : - { - *(.multiboot2 .multiboot2.*) - } - - .mb2bootcode.text : - { - *(.mb2bootcode.text) - } - - .mb2bootcode.data : - { - *(.mb2bootcode.data) - } - - .mb2bootcode.bss : - { - *(.mb2bootcode.bss) - } - - . += ALIGN(4096); - . += KERNEL_VIRTUAL_BASE; + . = 0xC0100000; _kernel_start = .; - .text ALIGN(4096) : AT(ADDR(.text) - KERNEL_VIRTUAL_BASE) + .text ALIGN(4096) : AT(ADDR(.text) - 0xC0000000) { + *(.multiboot2) *(.text .text.*) } _kernel_text_end = .; - .data ALIGN (4096) : AT(ADDR(.data) - KERNEL_VIRTUAL_BASE) + .data ALIGN (4096) : AT(ADDR(.data) - 0xC0000000) { *(.data .data.*) } _kernel_data_end = .; - .rodata ALIGN (4096) : AT(ADDR(.rodata) - KERNEL_VIRTUAL_BASE) + .rodata ALIGN (4096) : AT(ADDR(.rodata) - 0xC0000000) { *(.rodata .rodata.*) } _kernel_rodata_end = .; - .bss ALIGN (4096) : AT(ADDR(.bss) - KERNEL_VIRTUAL_BASE) + .bss ALIGN (4096) : AT(ADDR(.bss) - 0xC0000000) { *(COMMON) *(.bss .bss.*) diff --git a/Kernel.cpp b/Kernel.cpp index 32840ab..c881906 100644 --- a/Kernel.cpp +++ b/Kernel.cpp @@ -1,5 +1,6 @@ #include "kernel.h" +#include #include #include #include @@ -91,9 +92,38 @@ EXTERNC void arm64Entry(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x CPU::Halt(); } -EXTERNC void x32Entry(uint64_t Data) +struct multiboot_info +{ + multiboot_uint32_t Size; + multiboot_uint32_t Reserved; + struct multiboot_tag *Tag; +}; + +EXTERNC void x32Entry(multiboot_info *Info, unsigned int Magic) { trace("Hello, World!"); - while (1) - CPU::Halt(); + + if (Info == NULL || Magic == NULL) + { + if (Magic == NULL) + { + error("Multiboot magic is NULL"); + } + if (Info == NULL) + { + error("Multiboot info is NULL"); + } + CPU::Stop(); + } + else if (Magic != MULTIBOOT2_BOOTLOADER_MAGIC) + { + error("Multiboot magic is invalid (%#x != %#x)", Magic, MULTIBOOT2_BOOTLOADER_MAGIC); + trace("Hello, World!"); + CPU::Stop(); + } + + ((unsigned char *)0xb8000)[2 * (80) * (25) - 2] = 'M'; + ((unsigned char *)0xb8000)[2 * (80) * (25) - 1] = 4; + + CPU::Stop(); }