diff --git a/kernel/arch/i386/boot.s b/kernel/arch/i386/boot.s index 6bf9a5fa9f..52bf0a86dc 100644 --- a/kernel/arch/i386/boot.s +++ b/kernel/arch/i386/boot.s @@ -6,109 +6,34 @@ .set MB_CHECKSUM, -(MB_MAGIC + MB_FLAGS) #checksum of above, to prove we are multiboot # Multiboot header -.section .multiboot.data, "aw" +.section .multiboot .align 4 .long MB_MAGIC .long MB_FLAGS .long MB_CHECKSUM # Create stack -.section .bootstrap_stack, "aw", @nobits +.section .bss stack_bottom: .skip 16384 # 16 KiB stack_top: -# Preallocate pages -.section .bss, "aw", @nobits - .align 4096 - boot_page_directory: - .skip 4096 - boot_page_table1: - .skip 4096 - -# Kernel entrypoint -.section .multiboot.text, "a" +.section .text .global _start .type _start, @function _start: - # Physical address of boot_page_table1 - movl $(boot_page_table1 - 0xC0000000), %edi + movl $stack_top, %esp - # First address to map is 0 - movl $0, %esi + pushl %eax + pushl %ebx - # Map 1023 pages, 1024th will be VGA memory - movl $1023, %ecx + call _init - -1: - # Only map the kernel - cmpl $_kernel_start, %esi - jl 2f - cmpl $(_kernel_end - 0xC0000000), %esi - jge 3f - - # 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 entry in boot_page_table1 is 4 bytes - addl $4, %edi - # Loop to next entry if we haven't finished - loop 1b - -3: - # Map VGA memory to 0xC03FF000 as "present, writable" - movl $(0x000B8000 | 0x003), boot_page_table1 - 0xC0000000 + 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 0xC0000000 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 virtual addresses 0x00000000 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 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 4f, %ecx - jmp *%ecx - -.section .text - -4: - # Now paging is fully set up and enabled - - # Unmap the identity mapping since it is not unnecessary - movl $0, boot_page_directory + 0 - - # Reload crc3 to force a TLB flush for the changes to take effect - movl %cr3, %ecx - movl %ecx, %cr3 - - # Setup stack - mov $stack_top, %esp - - # Call into C code call kernel_main - - # Hang if kernel_main returns + cli -1: hlt +1: + hlt jmp 1b + +.size _start, . - _start diff --git a/kernel/arch/i386/linker.ld b/kernel/arch/i386/linker.ld index 9841709960..7fd644dfc6 100644 --- a/kernel/arch/i386/linker.ld +++ b/kernel/arch/i386/linker.ld @@ -2,37 +2,24 @@ ENTRY(_start) SECTIONS { - . = 0x00100000; + . = 1M; - _kernel_start = .; - .multiboot.data : { - *(.multiboot.data) - } - - .multiboot.text : { - *(.multiboot.text) - } - - . += 0xC0000000; - - .text ALIGN(4K) : AT(ADDR(.text) - 0xC0000000) + .text BLOCK(4K) : ALIGN(4K) { + *(.multiboot) *(.text) } - .rodata ALIGN(4K) : AT(ADDR(.rodata) - 0xC0000000) + .rodata BLOCK(4K) : ALIGN(4K) { *(.rodata) } - .data ALIGN(4K) : AT(ADDR(.data) - 0xC0000000) + .data BLOCK(4K) : ALIGN(4K) { *(.data) } - .bss ALIGN(4K) : AT(ADDR(.bss) - 0xC0000000) + .bss BLOCK(4K) : ALIGN(4K) { *(COMMON) *(.bss) - *(.bootstrap_stack) } - - _kernel_end = .; } diff --git a/kernel/arch/i386/tty.cpp b/kernel/arch/i386/tty.cpp index f7f5ffb996..9c8af8b6c2 100644 --- a/kernel/arch/i386/tty.cpp +++ b/kernel/arch/i386/tty.cpp @@ -7,7 +7,7 @@ static constexpr size_t VGA_WIDTH = 80; static constexpr size_t VGA_HEIGHT = 25; -static uint16_t* const VGA_MEMORY = (uint16_t*)0xC03FF000; +static uint16_t* const VGA_MEMORY = (uint16_t*)0xB8000; static size_t terminal_row; static size_t terminal_col; diff --git a/kernel/include/kernel/tty.h b/kernel/include/kernel/tty.h index 604527a5b7..eb318d5f66 100644 --- a/kernel/include/kernel/tty.h +++ b/kernel/include/kernel/tty.h @@ -3,11 +3,8 @@ #include #include -__BEGIN_DECLS void terminal_initialize(); void terminal_putchar(char c); void terminal_write(const char* data, size_t size); void terminal_writestring(const char* data); - -__END_DECLS \ No newline at end of file diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index fb2ec33e70..c4f02efba2 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -1,21 +1,60 @@ +#include +#include +#include #include #include -#include +#include +#include +#define DISABLE_INTERRUPTS() asm volatile("cli") +#define ENABLE_INTERRUPTS() asm volatile("sti") + +// https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format +struct multiboot_info_t +{ + uint32_t flags; + uint32_t mem_lower; + uint32_t mem_upper; + uint32_t boot_device; + uint32_t cmdline; + uint32_t mods_count; + uint32_t mods_addr; + uint32_t syms[4]; + uint32_t mmap_length; + uint32_t mmap_addr; + uint32_t drives_length; + uint32_t drives_addr; + uint32_t config_table; + uint32_t boot_loader_name; + uint32_t apm_table; + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; + uint8_t framebuffer[22]; +#if 1 + uint8_t color_info[6]; +#endif +} __attribute__((packed)); extern "C" -void kernel_main() +void kernel_main(multiboot_info_t* mbi, uint32_t magic) { - asm volatile("cli"); - + DISABLE_INTERRUPTS(); terminal_initialize(); + if (magic != 0x2BADB002) + Kernel::panic("Invalid magic in multiboot"); + if (mbi->flags & 0b00100000) + { + printf("mmap_length: %d\n", mbi->mmap_length); + printf("mmap_addr: %p\n", mbi->mmap_addr); + } + printf("Hello from the kernel!\n"); - printf("%p\n", kernel_main); - - int a = 10; - printf("%p\n", &a); } \ No newline at end of file