diff --git a/Makefile b/Makefile index ec8134c..6f4676f 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,9 @@ TOOLS_DIR = tools include $(TOOLS_DIR)/build.mk -ASFLAGS = -DSTUPID_VERSION=\"$(shell $(GIT-VERSION))\" -Ilib +ASFLAGS = -DSTUPID_VERSION="\"$(shell $(GIT-VERSION))\"" -Ilib \ + -DBUILD_DATE="\"$(shell date --iso)\"" \ + -DNASM_VERSION="\"$(shell nasm -v)\"" QEMUFLAGS = -serial stdio GARBADGE = stupid.iso diff --git a/kernel/build.mk b/kernel/build.mk index e3e97cd..4760e5a 100644 --- a/kernel/build.mk +++ b/kernel/build.mk @@ -1,11 +1,11 @@ include kernel/drivers/build.mk -KERNEL_SRCS = head.s gdt.s pic.s isr.s idt.s paging.s lib/log.s +KERNEL_SRCS = head.s gdt.s pic.s isr.s idt.s pmm.s paging.s lib/log.s KERNEL_OBJS = $(addprefix kernel/, $(KERNEL_SRCS:.s=.o) $(DRIVERS_OBJS)) KERNEL_BIN = vmstupid KERNEL_DUMP = $(KERNEL_BIN).dump -KERNEL_ASFLAGS = $(ASFLAGS) -D__KERNEL__ +KERNEL_ASFLAGS = $(ASFLAGS) -D__KERNEL__ -Ikernel GARBADGE += $(KERNEL_OBJS) $(KERNEL_BIN) $(KERNEL_DUMP) diff --git a/kernel/head.s b/kernel/head.s index 1f47875..3bac1bb 100644 --- a/kernel/head.s +++ b/kernel/head.s @@ -1,6 +1,7 @@ [BITS 32] %include "base.inc" +%include "multiboot.inc" MULTIBOOT_MAGIC equ 0x1BADB002 MULTIBOOT_ALIGN equ 1 << 0 @@ -23,14 +24,29 @@ section .text global entry entry: mov esp, stack_top - cli + mov edi, eax + mov esi, ebx + + ;; initialize serial (mostly used for debug) extern serial_init call serial_init - LOG msg_hello_world + ;; eax <- magic + ;; ebx <- multiboot struct + cmp edi, 0x2BADB002 + je .multiboot_valid + LOG err_invalid_boot_magic, edi + jmp hang + +.multiboot_valid: + + LOG msg_hello_world + mov eax, [esi + mb_info.bootloader_name] + LOG msg_boot_info, eax + extern setup_gdt call setup_gdt @@ -40,20 +56,32 @@ entry: extern setup_idt call setup_idt - ;extern setup_paging - ;call setup_paging + push esi + extern setup_pmm + call setup_pmm + add esp, 4 + test eax, 0 + jz .mem_ok - int3 + LOG err_cannot_map_memory - LOG file - - cli -hang: - hlt jmp hang +.mem_ok: + extern setup_paging + call setup_paging + +hang: + cli + hlt + jmp hang + section .rodata -msg_hello_world db "StupidOS ", STUPID_VERSION, 0 +msg_hello_world db "StupidOS v", STUPID_VERSION, " (built with ", NASM_VERSION, " on ", BUILD_DATE, ")", 0 +msg_boot_info db "Bootloader: %s", 0 +err_invalid_boot_magic db "[ERROR] Invalid boot magic (got: %x, expected: 0x2BADB002)", 0 +err_cannot_map_memory db "[ERROR] Can't map memory", 0 + file db __FILE__, 0 diff --git a/kernel/linker.ld b/kernel/linker.ld index 2082c45..3f7c437 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -4,6 +4,7 @@ ENTRY(entry) SECTIONS { . = 1M; + kernel_start = .; .text : ALIGN(4) { KEEP(*(.multiboot)) @@ -22,4 +23,6 @@ SECTIONS *(COMMON) *(.bss) } + + kernel_end = .; } diff --git a/kernel/multiboot.inc b/kernel/multiboot.inc new file mode 100644 index 0000000..620d735 --- /dev/null +++ b/kernel/multiboot.inc @@ -0,0 +1,66 @@ +struc mb_info + .flags: resd 1 + + ;; flags[0] is set + .mem_lower: resd 1 + .mem_upper: resd 1 + + ;; flags[1] is set + .boot_device: resd 1 + + ;; flags[2] is set + .cmdline: resd 1 + + ;; flags[3] is set + .mods_count: resd 1 + .mods_addr: resd 1 + + ;; flags[4] || flags[4] is set + .syms: resd 4 + + ;; flags[6] is set + .mmap_length: resd 1 + .mmap_addr: resd 1 + + ;; flags[7] is set + .drives_length: resd 1 + .drives_addr: resd 1 + + ;; flags[8] is set + .config_table: resd 1 + + ;; flags[9] is set + .bootloader_name: resd 1 + + ;; flags[10] is set + .apm_table: resd 1 + + ;; + .vbe_control_info: resd 1 + .vbe_mode_info: resd 1 + .vbe_mode: resw 1 + .vbe_interface_seg: resw 1 + .vbe_interface_off: resw 1 + .vbe_interface_len: resw 1 + + .framebuffer_addr: resq 1 + .framebuffer_pitch: resd 1 + .framebuffer_width: resd 1 + .framebuffer_height: resd 1 + .framebuffer_bpp: resb 1 + .framebuffer_type: resb 1 + .framebuffer_misc: resw 3 +endstruc + +struc mb_mmap + .size: resd 1 + .addr: resq 1 + .length: resq 1 + .type: resd 1 +endstruc + +%define MB_MEMORY_AVAILABLE 1 +%define MB_MEMORY_RESERVED 2 +%define MB_MEMORY_ACPI 3 +%define MB_MEMORY_NVS 4 +%define MB_MEMORY_BADRAM 5 diff --git a/kernel/paging.s b/kernel/paging.s index d4448aa..3213e6c 100644 --- a/kernel/paging.s +++ b/kernel/paging.s @@ -1,5 +1,11 @@ [BITS 32] +PE_PRESENT equ 1 << 0 +PE_WRITABLE equ 1 << 1 +PE_USERMODE equ 1 << 2 +PE_ACCESSED equ 1 << 5 +PE_DIRTY equ 1 << 6 + section .data align 4096 diff --git a/kernel/pmm.s b/kernel/pmm.s new file mode 100644 index 0000000..b0ea087 --- /dev/null +++ b/kernel/pmm.s @@ -0,0 +1,74 @@ +[BITS 32] + +%include "base.inc" +%include "multiboot.inc" + +section .text +global setup_pmm +setup_pmm: + push ebp + mov ebp, esp + push edi + push esi + push ebx + + mov edi, [ebp + 8] + + mov eax, [edi] + and eax, 0x40 ; (1 << 6) + jz .no_mmap + mov esi, [edi + mb_info.mmap_length] + mov ebx, [edi + mb_info.mmap_addr] +.loop: + mov eax, ebx + LOG msg_mmap_entry, dword [eax + mb_mmap.addr + 4], \ + dword [eax + mb_mmap.addr], \ + dword [eax + mb_mmap.length + 4], \ + dword [eax + mb_mmap.length], \ + dword [eax + mb_mmap.type] + mov eax, [ebx + mb_mmap.size] + add eax, 0x4 + add ebx, eax + sub esi, eax + jnz .loop + + jmp .end_mem_detection + +.no_mmap: + LOG warn_no_mmap + mov eax, [edi] + and eax, 0x1 + jz .err + + xor eax, eax + mov ecx, [edi + mb_info.mem_lower] + shl ecx, 0xA ; ecx * 1KiB + LOG msg_mem_block, eax, ecx + mov eax, 0x100000 + mov ecx, [edi + mb_info.mem_upper] + shl ecx, 0xA + LOG msg_mem_block, eax, ecx + +.end_mem_detection: + + xor eax, eax + jmp .end +.err: + mov eax, 1 +.end: + pop ebx + pop esi + pop ebx + leave + ret + +section .rodata +warn_no_mmap db "[WARN] mmap flag not set", 0 +msg_mmap_entry db "Memory Map Entry:", 0xA + db 0x9, "Address: (hi): %x (lo): %x", 0xA + db 0x9, "Length: (hi): %x (lo): %x", 0xA + db 0x9, "Type: %x", 0 +msg_mem_block db "Free Memory:", 0xA + db 0x9, "Address: %x", 0xA + db 0x9, "Length: %x", 0 +file db __FILE__, 0 diff --git a/lib/base/log.s b/lib/base/log.s index 7ad8c19..249c59f 100644 --- a/lib/base/log.s +++ b/lib/base/log.s @@ -30,7 +30,6 @@ putstr: ret puthex: - xchg bx, bx push ebp mov ebp, esp push edi