Sun, 24 Dec 2017 12:02:58 +0100
13 files changed,
161 insertions(+),
22 deletions(-)
A
include/kernel.h
@@ -0,0 +1,8 @@
+#ifndef KERNEL_H +#define KERNEL_H + +#define KERNEL_VIRTUAL_ADDR ((void*)0xC0000000) +#define KERNEL_PHYS_ADDR ((void*)0x00100000) +#define KERNEL_STACK_ADDR ((void*)0xD0000000) + +#endif
M
kernel/entry.s
→
kernel/entry.s
@@ -1,20 +1,12 @@
+.section .text .global _kernel_start _kernel_start: - # this code prints out all ascii characters in reverse order in - # rainbow colors just to test if this point of the code was reached - # (you might call it overkill, i call it fabulous) - mov $255, %ecx - mov $0xB8000, %esi - -test: - movb %cl, (%esi) - inc %esi - movb %cl, (%esi) - inc %esi - loop test + call main - # loop until the heat death of the universe loop: jmp loop - .ascii "hey now youre an allstar get your game on" +.section .data +kernel_msg: + .ascii "Welcome to the high kernel. Please take a seat and enjoy the fucking show" + .byte 0
M
kernel/link.txt
→
kernel/link.txt
@@ -1,4 +1,3 @@
-INPUT(build/entry.o) OUTPUT_FORMAT(elf32-i386) OUTPUT_ARCH(i386) ENTRY(_kernel_start)
A
kernel/main.c
@@ -0,0 +1,8 @@
+#include "text.h" + +int main(void) { + clear(); + write("Welcome!"); + + return 0; +}
M
kernel/makefile
→
kernel/makefile
@@ -1,8 +1,8 @@
.RECIPEPREFIX = > .PHONY: build -build: build/entry.o -> $(GCC_PREFIX)ld -r -T link.txt -o $(BUILD_DIR)/kernel.o --oformat elf32-i386 +build: build/entry.o build/text.o build/main.o +> $(GCC_PREFIX)ld $^ -r -T link.txt -o $(BUILD_DIR)/kernel.o --oformat elf32-i386 .PHONY: clear clear:@@ -15,3 +15,9 @@ > $(MAKE) build
build/entry.o: entry.s > $(GCC_PREFIX)as -o $@ $< + +build/text.o: text.c text.h +> $(GCC_PREFIX)gcc -c -I$(INCLUDE_DIR) --prefix=$(GCC_PREFIX) $(GCC_OPTIONS) -o $@ $< + +build/main.o: main.c +> $(GCC_PREFIX)gcc -c -I$(INCLUDE_DIR) --prefix=$(GCC_PREFIX) $(GCC_OPTIONS) -o $@ $<
A
kernel/paging.h
@@ -0,0 +1,53 @@
+#ifndef PAGING_H +#define PAGING_H + +#include <stdint.h> + +#define PAGE_ENTRY_COUNT (1 << 10) +#define PAGE_SIZE (1 << 12) + +typedef union { + uint32_t entry; + struct + { + uint32_t present : 1; + uint32_t read_write : 1; + uint32_t user_supervisor : 1; + uint32_t write_through : 1; + uint32_t cache_disabled : 1; + uint32_t accessed : 1; + uint32_t __zero : 1; + uint32_t page_size : 1; + uint32_t __ignored : 1; + uint32_t available : 3; + uint32_t page_table_addr : 20; + } __attribute((packed)) fields; +} PAGE_DIR_ENTRY; + +typedef union { + uint32_t entry; + uint8_t bytes[4]; + struct { + uint32_t present : 1; + uint32_t read_write : 1; + uint32_t user_supervisor : 1; + uint32_t write_through : 1; + uint32_t cache_disabled : 1; + uint32_t accessed : 1; + uint32_t dirty : 1; + uint32_t __zero : 1; + uint32_t global : 1; + uint32_t available : 3; + uint32_t page_addr : 20; + } __attribute((packed)) fields; +} PAGE_TABLE_ENTRY; + +#define MAKE_PAGE_ENTRY(addr, flags) (uint32_t)(((uint32_t)(addr) & 0xFFFFF000) | (flags)) + +#define PAGE_DIRECTORY (PAGE_DIR_ENTRY[PAGE_ENTRY_COUNT]) +#define PAGE_TABLE (PAGE_TABLE_ENTRY[PAGE_ENTRY_COUNT]) + +#define PAGE_DIR_INDEX(addr) ((uint32_t)(addr) >> 22) +#define PAGE_TABLE_INDEX(addr) ((uint32_t)(addr) >> 12) + +#endif
A
kernel/text.c
@@ -0,0 +1,59 @@
+#include "linker.h" + +#define VGA_TEXTMODE_COLUMNS 80 +#define VGA_TEXTMODE_LINES 25 +#define VGA_TEXTMODE_CELLS (VGA_TEXTMODE_COLUMNS * VGA_TEXTMODE_LINES) +#define VGA_TEXTMODE_BPC 2 +#define VGA_MEM_POS(line, column) ((line) * VGA_TEXTMODE_COLUMNS * VGA_TEXTMODE_BPC + (column) * VGA_TEXTMODE_BPC) + +#define VGA_TEXTMODE_MEM ((uint8_t*)0xB8000) + +uint32_t line = 0; +uint32_t column = 0; +uint8_t color = 0x0F; + +void lfcr() { + line++; + column = 0; +} + +void write_char(char value) { + switch (value) { + case '\n': + lfcr(); + break; + case '\0': + break; + default: + VGA_TEXTMODE_MEM[VGA_MEM_POS(line, column)] = value; + VGA_TEXTMODE_MEM[VGA_MEM_POS(line, column) + 1] = color; + column++; + break; + } + + if (column >= VGA_TEXTMODE_COLUMNS) { + lfcr(); + } +} + +void write_n(const char *string, uint32_t num) { + for (uint32_t i = 0; i < num; i++) { + write_char(string[0]); + } +} + +void write(const char *string) { + while (*string) { + write_char(*(string++)); + } +} + +void clear() { + for (int i = 0; i < VGA_TEXTMODE_CELLS; i++) { + VGA_TEXTMODE_MEM[2 * i] = 0; + VGA_TEXTMODE_MEM[2 * i + 1] = 0; + } + + line = 0; + column = 0; +}
A
kernel/text.h
@@ -0,0 +1,11 @@
+#ifndef TEXT_H +#define TEXT_H + +#include <stdint.h> + +void write_n(const char *string, uint32_t num); +void write(const char *string); + +void clear(); + +#endif
M
second_stage/entry.s
→
second_stage/entry.s
@@ -16,7 +16,6 @@ movl %cr0, %eax
or $0x80000010, %eax movl %eax, %cr0 - # TODO: # jump to kernel code ljmp $8, $__KERNEL_VMA
M
second_stage/link.txt
→
second_stage/link.txt
@@ -1,4 +1,3 @@
-INPUT(build/entry.o build/gdt.o build/main.o build/paging.o) OUTPUT_FORMAT(elf32-i386) OUTPUT_ARCH(i386) ENTRY(_ss_start)
M
second_stage/makefile
→
second_stage/makefile
@@ -2,7 +2,7 @@ .RECIPEPREFIX = >
.PHONY: build build: build/entry.o build/gdt.o build/main.o build/paging.o -> $(GCC_PREFIX)ld -r -T link.txt -o $(BUILD_DIR)/second_stage.o --oformat elf32-i386 +> $(GCC_PREFIX)ld $^ -r -T link.txt -o $(BUILD_DIR)/second_stage.o --oformat elf32-i386 .PHONY: clear clear:
M
second_stage/paging.c
→
second_stage/paging.c
@@ -1,5 +1,6 @@
#include "paging.h" #include "linker.h" +#include "kernel.h" void *ss_memset(void *ptr, uint8_t value, uint32_t num) { for (uint32_t i = 0; i < num; i++) {@@ -17,12 +18,11 @@ // set everything to zero
ss_memset(pdir, 0, 3 * PAGE_SIZE); // map page directory to itself - //(*pdir)[PAGE_DIR_INDEX(0)].entry = MAKE_PAGE_ENTRY(pdir, 0b000000000011); + (*pdir)[PAGE_DIR_INDEX(PAGE_ENTRY_COUNT - 1)].entry = MAKE_PAGE_ENTRY(pdir, 0b000000000011); // map kernel to 0xC0000000 (*pdir)[PAGE_DIR_INDEX(KERNEL_VMA)].entry = MAKE_PAGE_ENTRY(kernel, 0b000000000011); - for (uint32_t i = 0; i < 1 << 8; i++) { (*kernel)[i].entry = MAKE_PAGE_ENTRY(0x100000 + PAGE_SIZE * i, 0b000000000011); }@@ -33,6 +33,8 @@
for (uint32_t i = 0; i < 1 << 10; i++) { (*lowmem)[i].entry = MAKE_PAGE_ENTRY(PAGE_SIZE * i, 0b000000000011); } + + // map return pdir; }