From e16da3adc87e34bab07763589cb601667b5b9679 Mon Sep 17 00:00:00 2001 From: Jarkko Toivanen Date: Mon, 24 Jul 2023 21:48:21 +0300 Subject: [PATCH] Multiboot parsing and uitoa impl --- Makefile | 2 +- src/itoa.asm | 98 ++++++++++++++++++++++++++++++++++++++ src/mbootinfo.asm | 118 ++++++++++++++++++++++++++++++++++++++++++++++ src/start32.asm | 118 +++++++++++++++++++++++++++++----------------- 4 files changed, 291 insertions(+), 45 deletions(-) create mode 100644 src/itoa.asm create mode 100644 src/mbootinfo.asm diff --git a/Makefile b/Makefile index 1e50876..33d69be 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ all: build/kernel-i386.elf clean: -@rm *.bin 2> /dev/null || true -start32.bin: src/start32.asm src/serial.asm +start32.bin: src/* fasm src/start32.asm start32.bin image: start32.bin mount cp start32.bin mnt/koalemos/ diff --git a/src/itoa.asm b/src/itoa.asm new file mode 100644 index 0000000..914b214 --- /dev/null +++ b/src/itoa.asm @@ -0,0 +1,98 @@ +;; Modified from: https://gist.github.com/SplittyDev/8e728627012e57ac0deac196660014fb + +; +; Routine to convert a 32-bit integer to a string. +; Registers are preserved. +; +; EAX: Source integer +; EBX: Target address +; ECX: Base +; +; Internal register layout: +; start: +; EAX: Source integer +; ECX: Target address +; EDX: Base +; checknegative: +; EAX: Source integer +; EBX: Target address (original) +; ECX: Target address (active) +; divrem: +; EAX: Source integer +; ECX: Target address (active) +; EDX: Base / Result +; reverse: +; EBX: Target address (original) +; ECX: Target address (active) +; EDX: Target address (temporary) +; +__uitoa: +.start: + push ebp + mov ebp, esp + + push eax + push ebx + push ecx + push edx + + mov eax, [ebp+8] + mov ecx, [ebp+12] + mov ebx, [ebp+16] + + mov edx, ecx + mov ecx, ebx +;.checknegative: +; test eax, eax +; jns .divrem +; mov byte [ecx], 0x2D +; inc ecx +; mov ebx, ecx +; neg eax +.divrem: + push edx + push ecx + mov ecx, edx + xor edx, edx + div ecx + mov byte dl, [__itoacvt + edx] + pop ecx + mov byte [ecx], dl + pop edx + inc ecx + cmp eax, 0x00 + jne .divrem + mov byte [ecx], 0x00 + dec ecx +.reverse: + cmp ebx, ecx + jge .end + mov byte dl, [ebx] + mov byte al, [ecx] + mov byte [ebx], al + mov byte [ecx], dl + inc ebx + dec ecx + jmp .reverse +.end: + pop edx + pop ecx + pop ebx + pop eax + + pop ebp + ret + +; +; Conversion table for __itoa. +; Works for bases [2 ... 36]. +; +__itoacvt: + db '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + +; +; Buffer to store the result of __itoa in. +; +align 64 +__itoabuf32: + rb 36 diff --git a/src/mbootinfo.asm b/src/mbootinfo.asm new file mode 100644 index 0000000..a12504a --- /dev/null +++ b/src/mbootinfo.asm @@ -0,0 +1,118 @@ +mbootgetinfo: + push ebp + mov ebp, esp + push ebx + push esi + push edi + cld + + mov eax, [ebp+8] + cmp eax, 0x2badb002 + jne mbootnomagic + + mov ebx, [ebp+12] + mov eax, [ebx] + mov [mbootinfo.flags], eax + + ;; Get memoryinformation + test eax, 1b + jz mbootnomeminfo + mov eax, [ebx+4] + mov [mbootinfo.mem_lower], eax + mov eax, [ebx+8] + mov [mbootinfo.mem_upper], eax + + ;; Get videoinformation + test [mbootinfo.flags], (1 shl 02) + jz mbootnovideoinfo + + mov esi, ebx + add esi, 88 + mov eax, [esi] + mov [mbootinfo.fb_addr], eax + add esi, 8 + + mov eax, [esi] + mov [mbootinfo.fb_pitch], eax + add esi, 4 + + mov eax, [esi] + mov [mbootinfo.fb_width], eax + add esi, 4 + + mov eax, [esi] + mov [mbootinfo.fb_height], eax + add esi, 4 + + mov al, [esi] + cmp al, 32 + je .bppokay + cmp al, 24 + je .bppokay + jmp mbootunsupportedfbbpp +.bppokay: + mov [mbootinfo.fb_bpp], al + inc esi + + mov al, [esi] + cmp al, 1 + jne mbootunsupportedfbtype + mov [mbootinfo.fb_type], al + inc esi + + ;; r/g/b positions and masks + mov ecx, 6 + mov edi, mbootinfo.fb_rpos + rep movsb + +.done: + pop edi + pop esi + pop ebx + pop ebp + ret + + +mbootnomagic: + push .msg + call serialwrite + jmp hang +.msg db "No multiboot magic!", 10, 0 +mbootnomeminfo: + push .msg + call serialwrite + jmp hang +.msg db "No memoryinfo!", 10, 0 +mbootnovideoinfo: + push .msg + call serialwrite + jmp hang +.msg db "No videoryinfo!", 10, 0 +mbootunsupportedfbtype: + push .msg + call serialwrite + jmp hang +.msg db "Unsupported framebuffer type: only direct RGB is supported!", 10, 0 +mbootunsupportedfbbpp: + push .msg + call serialwrite + jmp hang +.msg db "Unsupported bitdepth: only 24 and 32 bpp supported!", 10, 0 + + +mbootinfo: + .flags dd 0 + .mem_lower dd 0 + .mem_upper dd 0 + .fb_addr dd 0 + .fb_pitch dd 0 + .fb_width dd 0 + .fb_height dd 0 + .fb_bpp db 0 + .fb_type db 0 + .fb_rpos db 0 + .fb_rmasksize db 0 + .fb_gpos db 0 + .fb_gmasksize db 0 + .fb_bpos db 0 + .fb_bmasksize db 0 diff --git a/src/start32.asm b/src/start32.asm index fc19dc0..9eb28a9 100644 --- a/src/start32.asm +++ b/src/start32.asm @@ -5,7 +5,7 @@ org 0x100000 MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 MULTIBOOT_PAGE_ALIGN equ (1 shl 0) MULTIBOOT_MEMORY_INFO equ (1 shl 1) -MULTIBOOT_VIDEO_REQUEST equ (0 shl 2) +MULTIBOOT_VIDEO_REQUEST equ (1 shl 2) MULTIBOOT_AOUT_KLUDGE equ (1 shl 16) MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN or MULTIBOOT_MEMORY_INFO or MULTIBOOT_VIDEO_REQUEST MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN or MULTIBOOT_MEMORY_INFO or MULTIBOOT_VIDEO_REQUEST or MULTIBOOT_AOUT_KLUDGE @@ -27,68 +27,98 @@ multiboot: start: ; Setup stack - mov ebp, stack_bottom + mov ebp, stack_top mov esp, stack_top push ebx push eax - cmp eax, 0x2badb002 - jne multibootnomagic - - mov byte [0xb8000], '!' - - push stuff.bootmsg - call printbootmsg call serialinit + push stuff.bootmsg call serialwrite add esp, 4 + call mbootgetinfo + add esp, 2*4 + + mov eax, [mbootinfo.fb_addr] + mov dword [eax], 0xffffffff + + + push stuff.fbaddrmsgpfx + call serialwrite + add esp, 4 + + sub esp, 36 ;Reserve stack for return + push dword esp ;Destination address + push dword 16 ;Base + push dword [mbootinfo.fb_addr] ;source + call __uitoa + add esp, 3*4 + push esp + call serialwrite + add esp, 4 + + push stuff.fbdimensionsmsgpfx + call serialwrite + add esp, 4 + push dword esp ;destination address + push dword 10 ;base + push dword [mbootinfo.fb_width] + call __uitoa + add esp, 3*4 + push esp + call serialwrite + add esp, 4 + push stuff.x + call serialwrite + add esp, 4 + + push dword esp ;destination address + push dword 10 ;base + push dword [mbootinfo.fb_height] + call __uitoa + add esp, 3*4 + push esp + call serialwrite + add esp, 4 + push stuff.x + call serialwrite + + add esp, 4 + push dword esp ;destination address + push dword 10 ;base + xor eax, eax + mov al, [mbootinfo.fb_bpp] + push dword eax + call __uitoa + add esp, 3*4 + push esp + call serialwrite + add esp, 4 + + add esp, 36 ;Clean reserved uitoa return string from stack + jmp hang hang: + push .msg + call serialwrite cli +.loop: hlt - jmp hang - -multibootnomagic: - mov esi, .msg - mov edi, 0xb8000 - mov ah, 64 - cld -.loop: - lodsb - or al, al - jz .done - stosw jmp .loop -.done: - jmp hang -.msg db "No multiboot magic", 0 - -printbootmsg: - push ebp - mov ebp, esp - pushad - mov esi, [ebp+8] - mov edi, 0xb8000 - cld -.loop: - lodsb - or al, al - jz .done - stosb - inc edi - jmp .loop -.done: - popad - pop ebp - ret +.msg db 10, "Halting...", 10, 0 include "src/serial.asm" +include "src/mbootinfo.asm" +include "src/itoa.asm" stuff: - .bootmsg db "=== KoalemOS ===", 10, 0 + .bootmsg db 10, "=== KoalemOS ===", 10, 0 + .fbaddrmsgpfx db 10, "Framebuffer address: 0x", 0 + .fbdimensionsmsgpfx db 10, "Framebuffer dimensions: ", 0 + .x db "x", 0 stack_bottom: