Nyanix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | LICENSE

commit 2c853c8a02eb849a6376d500e1859aa2e517ad5a
parent aa11d4db706993cb3a4812e201f2ad3795c3fad1
Author: Dani Frisk <dani@silverskin.fi>
Date:   Tue, 14 Aug 2018 20:43:17 +0300

updated 2nd stage

Diffstat:
src/boot_early/2nd_stage.s | 405+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 405 insertions(+), 0 deletions(-)

diff --git a/src/boot_early/2nd_stage.s b/src/boot_early/2nd_stage.s @@ -0,0 +1,405 @@ + +; ========================================================================== ; +; Entry of 2nd stage of the bootloader ; +; ========================================================================== ; +global _start +_start: + ; disable interrupts, adjust Stack pointer + cli + xor bp, bp + add sp, 0x200 + + ; Back uping boot device from + ; 1st 512 byte sector. + + mov dl, [BOOT_DEVICE_DB] + mov [BOOT_DEV_DB], dl + + ; Functionality to get amount of RAM in system. + + + + .continue: + ; we'll jump to protected mode now. + ; after that, we should _never_ return to real 16-bit mode. + ; closest to that we'll get is virtual 8086 mode, aka + ; emulated 16-bit mode. + ; If we return, we'll hang. + call switch_to_pm + + .hang: + cli + hlt + jmp .hang + +; ========================================================================== ; +; GDT & few variables ; +; ========================================================================== ; +msg_failed_to_switch_pm db "Failed to swap to protected mode", 0x0A, 0x0D, 0 +newline db 0x0A, 0 +BOOT_DEV_DB db 0 + +; ========================================================================== ; +; Function to print debug messages in 16-bit real mode. ; +; ; +; param message_in (DI), String to print. ; +; ========================================================================== ; +real16_dbg_print: + lodsb + or al, al + jnz .continue + ret + .continue: + mov ah, 0x0E + int 0x10 + jmp real16_dbg_print + +; ========================================================================== ; +; Function to switch to protected mode ; +; ========================================================================== ; +switch_to_pm: + lgdt [GDT_32_PTR] + mov eax, cr0 + or eax, 1 + mov cr0, eax + ; 1 more instruction to execute in + ; 16 bit real mode, then we'll be + ; in 32-bit mode ! + jmp GDT_32_CODE:main_init + +; ============================================================================ ; +; 32-bit protected mode ; +; ============================================================================ ; +[bits 32] +; Function to initialize main +main_init: + mov ax, GDT_32_DATA + mov ds, ax + mov ss, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Setting up new stack + mov ebp, 0x7e00 + mov esp, ebp + + ; disable interrupts + cli + call main + +; ============================================================================ ; +; Function that's in protected 32-bit mode. ; +; This function server as the 'main' function of tthe bootloader. ; +; ============================================================================ ; +main: + push ebp + mov ebp, esp + + xor eax, eax + xor ebx, ebx + xor ecx, ecx + xor edx, edx + + mov esi, msg_nyanix + call print32dbg + mov esi, msg_mem_avail + call print32dbg + + call cmos_get_ram + + call print32dbg_hex + mov esi, newline + call print32dbg + + call check_a20 + cmp ax, 0 + je .a20_enabled + call enable_a20 + call check_a20 + cmp ax, 0 + je .a20_enabled + + ; Failed to enable a20 ! + mov esi, msg_a20fail + call print32dbg + jmp .hang + +; ============================================================================ ; +; We now have enabled A-20 gate. It's time to read the kernel from the disk. ; +; First we'll swap to unreal v8086 mode, load the kernel with BIOS interrupts, ; +; and then swap back to protected 32 bit mode. ; +; We never return from kernel_loader. If we somehow do due error, we'll jump ; +; to the hang. ; +; ============================================================================ ; +.a20_enabled: + cli + hlt + call kernel_loader + jmp .hang +.hang: + mov esi, msg_booting_failed + call print32dbg +.__hang: + cli + hlt + jmp .__hang + +; ============================================================================ ; +; Messages ; +; ============================================================================ ; +msg_nyanix db "Nyanix 0.1 loading your kernel :) ...", 0x0A, 0x00 +msg_mem_avail db "System RAM amount: ", 0 + +; Fatal errors, start with 'Fatal: ' prefix. +msg_a20fail db "Fatal: Failed to enable A20 line.", 0x0A, 0x00 +msg_booting_failed db "Fatal: Failed to boot the kernel!", 0x0A, 0x00 + +; ============================================================================ ; +; Functionality for enabling a20-gate ; +; ============================================================================ ; +; returns 0 if a20 is enabled, +; returns 1 if a20 is not enabled, +check_a20: + push ebp + mov ebp, esp + ; first gotta check if a20 line is enabled already + pushad + mov esi, 0x012345 + mov edi, 0x112345 + mov [esi], esi + mov [edi], edi + cmpsd + popad + jne .enabled + mov ax, 1 + jmp .ret +.enabled: + xor ax, ax +.ret: + mov esp, ebp + pop ebp + ret + +; ========================================================================== ; +; Function to enable A20 ; +; ========================================================================== ; +enable_a20: + push ebp + mov ebp, esp + ; we'll enable a20-gate via keyboard controller. + call kbd_wait + mov al, __KBD_DISABLE + call kbd_send + + call kbd_wait + mov al, __KBD_READ_IN + call kbd_send + + call kbd_read + push eax + + call kbd_wait + mov al, __KBD_WRITE_OUT + call kbd_send + + call kbd_wait + pop eax + or al, 2 + call kbd_send + call kbd_wait + + mov esp, ebp + ret + +; ============================================================================ ; +; Keyboard Control related functionality. ; +; ============================================================================ ; + +__KBD_DISABLE equ 0xAD +__KBD_ENABLE equ 0xAE +__KBD_READ_IN equ 0xD0 +__KBD_WRITE_OUT equ 0xD1 + +; does not return nor require args +kbd_wait: + push eax + in al, 0x64 + test al, 2 + jnz kbd_wait + pop eax + ret + +; returns one byte at al +kbd_read: + in al, 0x64 + test al, 1 + jz kbd_read + in al, 0x60 + ret + +; parameters for kbd_send: one byte at al +kbd_send: + out 0x64, al + ret + +; ============================================================================ ; +; Functionality for printing to the framebuffer ; +; ; +; Requires a null-terminated string at ESI ; +; ============================================================================ ; +__TTY_COLUMNS db 0 +__TTY_ROWS db 0 +__TTY_COLOR db 0x0F +print32dbg: + push ebp + mov ebp, esp + + push eax + push ebx + push ecx + push edx + + .print_loop: + xor eax, eax + xor ebx, ebx + xor edx, edx + + cmp byte [esi + ecx], 0x00 + je .done + + ; VGA_ADDR = (0xB8000 + (y * 80 + x)) + mov bl, byte [__TTY_COLUMNS] + mov dl, byte [__TTY_ROWS] + + ; setting EBX = VGA-Color + ; and EDX = VGA-address + push ecx + mov ecx, 0xb8000 + imul edx, 80 + add edx, ebx + add ecx, edx + mov edx, ecx + pop ecx + + mov bh, byte [__TTY_COLOR] + + ; printing the character + xor eax, eax + mov al, byte [esi + ecx] + + inc ecx + cmp ecx, 0xffff + jge .prevent_overflow + + cmp al, 0x0A + je .newline + mov ah, bh + mov word [edx], ax + + xor ebx, ebx + mov bl, byte [__TTY_COLUMNS] + add bl, 2 + mov byte [__TTY_COLUMNS], bl + cmp bl, 80 + jl .print_loop + mov bl, byte [__TTY_ROWS] + mov byte [__TTY_COLUMNS], 0 + inc bl + mov byte [__TTY_ROWS], bl + cmp bl, 25 + jl .print_loop + + ; 80x24 lines used? what for, this is a bootloader, + ; not a fairy-tale. No need for roll-over... + .rollover: + mov byte [__TTY_COLUMNS], 0 + mov byte [__TTY_ROWS], 0 + jmp .print_loop + + .newline: + xor ebx, ebx + mov bl, byte [__TTY_ROWS] + cmp bl, 24 + je .rollover + add bl, 2 + mov byte [__TTY_ROWS], bl + mov byte [__TTY_COLUMNS], 0 + jmp .print_loop + + .prevent_overflow: + .done: + mov dl, byte [__TTY_ROWS] + mov bl, byte [__TTY_COLUMNS] + pop edx + pop ecx + pop ebx + pop eax + mov esp, ebp + pop ebp + ret + +; Printing a 32-bit register content +print32dbg_hex: + push ebp + mov ebp, esp + + mov esi, .hex_prefix + call print32dbg + + mov ebx, eax + and eax, 0x0000ffff + and ebx, 0xffff0000 + rol ebx, 16 + and ebx, 0x0000ffff + + call __p16dbghx + mov eax, ebx + call __p16dbghx + + mov esi, newline + call print32dbg + + mov esp, ebp + pop ebp + ret + + .hex_prefix db '0x', 0 + +__p16dbghx: + push ebp + mov ebp, esp + push ebx + + mov di, .outstr16 + mov si, .hexstr + mov cx, 4 + xor bx, bx + .loop: + rol ax, 4 + mov bx, ax + and bx, 0x0f + mov bl, [si + bx] + mov [di], bl + inc di + dec cx + jnz .loop + mov esi, .outstr16 + call print32dbg + + pop ebx + mov esp, ebp + pop ebp + ret + + .hexstr db '0123456789ABCDEF' + .outstr16 db '0000', 0 + +; ========================================================================== ; +; Include of the next part of the bootloader (kernel_load). ; +; ========================================================================== ; +%include "src/descriptor_tables/gd32table.s" +%include "src/drivers/cmos.s" +%include "src/main_loader/kernel_loader.s" + +