summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/boot.S25
-rw-r--r--kernel/boot64.S7
-rw-r--r--kernel/grub.cfg1
-rw-r--r--kernel/header.S43
-rw-r--r--kernel/kernel.ld3
-rw-r--r--kernel/main.c102
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;
}