diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/boot.S | 25 | ||||
| -rw-r--r-- | kernel/boot64.S | 7 | ||||
| -rw-r--r-- | kernel/grub.cfg | 1 | ||||
| -rw-r--r-- | kernel/header.S | 43 | ||||
| -rw-r--r-- | kernel/kernel.ld | 3 | ||||
| -rw-r--r-- | kernel/main.c | 102 |
6 files changed, 157 insertions, 24 deletions
diff --git a/kernel/boot.S b/kernel/boot.S index 4276c98..e870c37 100644 --- a/kernel/boot.S +++ b/kernel/boot.S @@ -6,6 +6,10 @@ _start: mov $stack_top, %esp + pushl $0 + pushl %eax + pushl $0 + pushl %ebx call check_multiboot call check_cpuid @@ -62,6 +66,19 @@ setup_page_tables: or $0x3, %eax mov %eax, page_table_lvl3 + mov $page_table_lvl2 + 4096, %eax + or $0x3, %eax + mov %eax, page_table_lvl3+8 + + mov $page_table_lvl2 + 8192, %eax + or $0x3, %eax + mov %eax, page_table_lvl3+16 + + mov $page_table_lvl2 + 12288, %eax + or $0x3, %eax + mov %eax, page_table_lvl3+24 + + movl $0, %ecx 1: movl $0x200000, %eax @@ -71,7 +88,7 @@ setup_page_tables: leal (%edx, %ecx, 8), %edx movl %eax, (%edx) inc %ecx - cmp $512, %ecx + cmp $512*4, %ecx jne 1b ret @@ -100,15 +117,12 @@ enable_paging: ret no_multiboot: - movl $0x4f4d, 0xb8000 hlt no_cpuid: - movl $0x4f43, 0xb8000 hlt no_long_mode: - movl $0x4f4c, 0xb8000 hlt @@ -125,8 +139,9 @@ page_table_lvl4: .skip 4096 page_table_lvl3: .skip 4096 +// map first 4GB page_table_lvl2: - .skip 4096 + .skip 4096*4 .section .rodata gdt64: diff --git a/kernel/boot64.S b/kernel/boot64.S index e46bbef..561fe6b 100644 --- a/kernel/boot64.S +++ b/kernel/boot64.S @@ -4,7 +4,6 @@ .code64 begin_long_mode: - // reload segment registers mov $0, %eax mov %eax, %ss @@ -13,5 +12,9 @@ begin_long_mode: mov %eax, %fs mov %eax, %gs - call main + popq %rdi + popq %rsi + + cli + call kernel_main hlt diff --git a/kernel/grub.cfg b/kernel/grub.cfg index 535022a..05a13f7 100644 --- a/kernel/grub.cfg +++ b/kernel/grub.cfg @@ -1,6 +1,7 @@ set timeout=0 set default=0 +insmod efi_gop menuentry "mykernel64" { multiboot2 /boot/kernel.bin boot diff --git a/kernel/header.S b/kernel/header.S index 5a57741..bbcb9be 100644 --- a/kernel/header.S +++ b/kernel/header.S @@ -1,17 +1,40 @@ +// multiboot tags +.set TAG_END, 0 +.set TAG_FRAMEBUFFER, 5 + +// multiboot flags +.set TAG_REQUIRED, 0 +.set TAG_OPTIONAL, 1 + +# multiboot2 header constants +.set MAGIC, 0xe85250d6 +.set ARCH, 0 +.set HEADER_LENGTH, (header_end - header_start) +.set CHECKSUM, 0x100000000 - (MAGIC + ARCH + HEADER_LENGTH) + .section .multiboot_header, "a" .align 4 header_start: - # magic number - .long 0xe85250d6 # multiboot2 - # architecture - .long 0 # protected mode i386 - # header length - .long (header_end - header_start) - # checksum - .long 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) + # magic + .align 8 + .long MAGIC + .long ARCH + .long HEADER_LENGTH + .long CHECKSUM + + # framebuffer + .align 8 + .word TAG_FRAMEBUFFER + .word TAG_REQUIRED + .long 20 + .long 1024 + .long 768 + .long 32 # end tag - .word 0 - .word 0 + .align 8 + .word TAG_END + .word TAG_REQUIRED .long 8 + header_end: diff --git a/kernel/kernel.ld b/kernel/kernel.ld index bccea62..da5c87c 100644 --- a/kernel/kernel.ld +++ b/kernel/kernel.ld @@ -33,6 +33,7 @@ SECTIONS /DISCARD/ : { *(.comment.*) - /* *(.note.*) */ + *(.note.*) + *(.eh_frame) } } diff --git a/kernel/main.c b/kernel/main.c index ec40737..79039e6 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,12 +1,102 @@ #include <stdint.h> -int main(void) +struct mb2_tag_header { + uint32_t type; + uint32_t size; +} __attribute__((packed, aligned(8))); +typedef struct mb2_tag_header mb2_tag_header; + +struct mb2_tag_fb { + uint32_t type; + uint32_t size; + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; + uint8_t framebuffer_type; +} __attribute__((packed, aligned(8))); +typedef struct mb2_tag_fb mb2_tag_fb; + +// multiboot2 magic check +#define MB2_MAGIC 0x36D76289 + +// multiboot2 tag +#define MB2_TAG_END 0 +#define MB2_TAG_CMDLINE 1 +#define MB2_TAG_BOOTLOADER 2 +#define MB2_TAG_MODULES 3 +#define MB2_TAG_MEM 4 +#define MB2_TAG_BIOS 5 +#define MB2_TAG_MMAP 6 +#define MB2_TAG_VBE 7 +#define MB2_TAG_FB 8 + +void breakpoint(void) +{ + __asm__ volatile ("xchgw %bx, %bx;"); +} + +void put_in_r8(uint64_t value) +{ + __asm__ volatile ("movq %0, %%r8;" : : "r"(value) : "%r8"); +} + +void put_in_r9(uint64_t value) { - uint16_t* ct_buffer = (uint16_t*)0xb8000; - ct_buffer[0] = 0x2f4c; - ct_buffer[1] = 0x2f4f; - ct_buffer[2] = 0x2f4e; - ct_buffer[3] = 0x2f47; + __asm__ volatile ("movq %0, %%r9;" : : "r"(value) : "%r9"); +} + +void put_in_r10(uint64_t value) +{ + __asm__ volatile ("movq %0, %%r10;" : : "r"(value) : "%r10"); +} + +int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) +{ + if (multiboot_magic != MB2_MAGIC) { + // not loaded by multiboot2 bootloader + __asm__ volatile ("hlt;"); + } + + // we will store framebuffer information here + static mb2_tag_fb* tag_fb; + + // skip first 8 bytes (total_size + reserved) + mb2_tag_header* tag_header = multiboot_bootinfo + 1; + + while (tag_header->type != MB2_TAG_END) { + // process tag_type + switch(tag_header->type) { + case MB2_TAG_FB: + tag_fb = (mb2_tag_fb*)tag_header; + break; + default: + break; + } + + // next mb2_tag + tag_header += tag_header->size / 8 + ((tag_header->size % 8) > 0); + } + + uint64_t* framebuffer_addr = (uint64_t*)tag_fb->framebuffer_addr; + uint32_t framebuffer_width = tag_fb->framebuffer_width; + uint32_t framebuffer_height = tag_fb->framebuffer_height; + //uint8_t framebuffer_bpp = tag_fb->framebuffer_bpp; + uint32_t framebuffer_pitch = tag_fb->framebuffer_pitch; + + put_in_r8(framebuffer_width); + put_in_r9(framebuffer_height); + put_in_r10(framebuffer_pitch); + breakpoint(); + + uint32_t value = 0x0000; + for (uint32_t x = 0 ; x < framebuffer_width; x++) { + for (uint32_t y = 0; y < framebuffer_height; y++) { + framebuffer_addr[y*framebuffer_width + x] = value; + value += 0x250; + } + } return 0; } |
