Nyanix

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

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

Big update, cool file tree, awesome

Diffstat:
Makefile | 2+-
src/2nd_stage.s | 356-------------------------------------------------------------------------------
src/boot.s | 93-------------------------------------------------------------------------------
src/boot_early/.2nd_stage.s.swp | 0
src/boot_early/boot.s | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/descriptor_tables/gd32table.s | 33+++++++++++++++++++++++++++++++++
src/drivers/.cmos.s.swp | 0
src/drivers/FDC.s | 26++++++++++++++++++++++++++
src/drivers/cmos.s | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gdt32table.s | 33---------------------------------
src/kernel_loader.s | 62--------------------------------------------------------------
src/main_loader/kernel_loader.s | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 309 insertions(+), 545 deletions(-)

diff --git a/Makefile b/Makefile @@ -2,7 +2,7 @@ as=nasm asflags=-fbin -O0 target=bin/Nyanix -entry=src/boot.s +entry=src/boot_early/boot.s .PHONY: all clean debug qemu install diff --git a/src/2nd_stage.s b/src/2nd_stage.s @@ -1,356 +0,0 @@ - -; ========================================================================== ; -; 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 - - ; Getting the amount of RAM - clc - sti - xor cx, cx - xor dx, dx - mov ax, 0xE801 ; get memory interrupt - int 0x15 - jc .fail - cmp ah, 0x86 ; Unsupported function, pre 1994 machine - je .fail ; or bad BIOS - cmp ah, 0x80 - je .fail - jcxz .continue - mov ax, cx - mov bx, dx - - .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 - - .fail: - mov si, msg_failed_to_get_memory - call real16_dbg_print - .hang: - cli - hlt - jmp .hang - -; ========================================================================== ; -; GDT & few variables ; -; ========================================================================== ; -%include "src/gdt32table.s" -msg_failed_to_switch_pm db "Failed to swap to protected mode", 0x0A, 0x0D, 0 -msg_failed_to_get_memory db "Failed to get amount of RAM avail.", 0x0A, 0x0D, 0 -BOOT_DEV_DB db 0 - -MEMORY_LOWER dw 0 -MEMORY_HIGHER dw 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 - - 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 - cli - hlt - -; ============================================================================ ; -; 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: - 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 - -; 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 - pop 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 DI ; -; ============================================================================ ; -__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 - -; ========================================================================== ; -; Include of the next part of the bootloader (kernel_load). ; -; ========================================================================== ; -%include "src/kernel_loader.s" - - diff --git a/src/boot.s b/src/boot.s @@ -1,93 +0,0 @@ -; ============================================================================ ; -; The entrypoint for bootloader. ; -; ============================================================================ ; - -bits 16 -align 4 -org 0x7c00 -section .text - -; Clearing out the Code-Segment, as some BIOSes start the bootloader -; by setting CS=0x7c00 instead of just jmp 0x0000:0x7c00 -jmp 0x0000:_entry - -%define SECTOR_COUNT 3 - -_entry: - cld - cli - - ; back-uping boot device id & clearing registers - mov [BOOT_DEVICE_DB], dl - ; change to text-mode (and clear the screen) - xor ah, ah - mov al, 0x03 - int 0x10 - xor ax, ax - xor bx, bx - xor cx, cx - - xor si, si - xor di, di - - xor bp, bp - mov ss, ax - mov es, ax - mov fs, ax - ; stack starts at 0x7c00 - mov sp, 0x7c00 - -; ============================================================================ ; -; We'll load 2nd stage of bootloader with BIOS interrupts ; -; (int 13h, ah=2) ; -; ============================================================================ ; - -load_2nd_stage: - sti - mov bx, _start - mov dh, SECTOR_COUNT - mov dl, [BOOT_DEVICE_DB] - mov byte [BL_SECTORS], dh - xor ch, ch - xor dh, dh - mov cl, 0x02 -.read_start: - mov di, 5 -.read: - mov ah, 0x02 - mov al, [BL_SECTORS] - int 0x13 - jc .retry - sub [BL_SECTORS], al - jz .read_done - mov cl, 0x01 - xor dh, 1 - jnz .read_start - inc ch - jmp .read_start -.retry: - xor ah, ah - int 0x13 - dec di - jnz .read - mov si, msg_loader_failed - call real16_dbg_print -.error_hang: - cli - hlt -.read_done: - jmp _start - - msg_loader_failed db "Failed to load bootloader.", 0x0A, 0x0D, 0 - BOOT_DEVICE_DB db 0 - BL_SECTORS db 0 - -; Filling rest of the sector with null-bytes until signature. - times 510-($-$$) db 0x00 - db 0x55 - db 0xAA - -; Rest of the bootloader code comes here. - -%include "src/2nd_stage.s" - diff --git a/src/boot_early/.2nd_stage.s.swp b/src/boot_early/.2nd_stage.s.swp Binary files differ. diff --git a/src/boot_early/boot.s b/src/boot_early/boot.s @@ -0,0 +1,93 @@ +; ============================================================================ ; +; The entrypoint for bootloader. ; +; ============================================================================ ; + +bits 16 +align 4 +org 0x7c00 +section .text + +; Clearing out the Code-Segment, as some BIOSes start the bootloader +; by setting CS=0x7c00 instead of just jmp 0x0000:0x7c00 +jmp 0x0000:_entry + +%define SECTOR_COUNT 5 + +_entry: + cld + cli + + ; back-uping boot device id & clearing registers + mov [BOOT_DEVICE_DB], dl + ; change to text-mode (and clear the screen) + xor ah, ah + mov al, 0x03 + int 0x10 + xor ax, ax + xor bx, bx + xor cx, cx + + xor si, si + xor di, di + + xor bp, bp + mov ss, ax + mov es, ax + mov fs, ax + ; stack starts at 0x7c00 + mov sp, 0x7c00 + +; ============================================================================ ; +; We'll load 2nd stage of bootloader with BIOS interrupts ; +; (int 13h, ah=2) ; +; ============================================================================ ; + +load_2nd_stage: + sti + mov bx, _start + mov dh, SECTOR_COUNT + mov dl, [BOOT_DEVICE_DB] + mov byte [BL_SECTORS], dh + xor ch, ch + xor dh, dh + mov cl, 0x02 +.read_start: + mov di, 5 +.read: + mov ah, 0x02 + mov al, [BL_SECTORS] + int 0x13 + jc .retry + sub [BL_SECTORS], al + jz .read_done + mov cl, 0x01 + xor dh, 1 + jnz .read_start + inc ch + jmp .read_start +.retry: + xor ah, ah + int 0x13 + dec di + jnz .read + mov si, msg_loader_failed + call real16_dbg_print +.error_hang: + cli + hlt +.read_done: + jmp _start + + msg_loader_failed db "Failed to load bootloader.", 0x0A, 0x0D, 0 + BOOT_DEVICE_DB db 0 + BL_SECTORS db 0 + +; Filling rest of the sector with null-bytes until signature. + times 510-($-$$) db 0x00 + db 0x55 + db 0xAA + +; Rest of the bootloader code comes here. + +%include "src/boot_early/2nd_stage.s" + diff --git a/src/descriptor_tables/gd32table.s b/src/descriptor_tables/gd32table.s @@ -0,0 +1,33 @@ + +%ifndef GDT_32_H +%define GDT_32_H 1 + +; Global Descriptor Table & ptrs for that. + +__null: + dq 0 +; code segment (0x9a) +__code: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +; data segment (0x92) +__data: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 +__end: + +GDT_32_PTR: + dw __end - __null - 1 ; See amd system programmers manual + dd __null +GDT_32_CODE equ __code - __null +GDT_32_DATA equ __data - __null + +%endif diff --git a/src/drivers/.cmos.s.swp b/src/drivers/.cmos.s.swp Binary files differ. diff --git a/src/drivers/FDC.s b/src/drivers/FDC.s @@ -0,0 +1,26 @@ +; ========================================================================== ; +; /src/FDC.s ; +; Copyright (c) 2018, k4m1 <k4m1@protonmail.com> ; +; All rights reserved. ; +; See /LICENSE for further copyright information. ; +; ; +; This code is responsible of controlling the Floppy-disk in protected mode ; +; ========================================================================== ; + +[bits 32] + +%ifndef __FDC_H +%define __FDC_H 1 + +; ========================================================================== ; +; Functionality to find floppy disks. ; +; ========================================================================== ; + + + + + + + +%endif + diff --git a/src/drivers/cmos.s b/src/drivers/cmos.s @@ -0,0 +1,94 @@ +; ========================================================================== ; +; /src/cmos.s ; +; Copyright (C) 2018 k4m1 <k4m1@protonmail.com> ; +; All rights reserved ; +; See /License for further copyright information. ; +; ; +; This code is responsible of communicating with CMOS. ; +; ========================================================================== ; + +%ifndef CMOS_H +%define CMOS_H 1 + +[BITS 32] + +%define CMOS_GPIO_OUT 0x70 +%define CMOS_GPIO_IN 0x71 +%define CMOS_FLOPPY_DATA 0x10 + +%define CMOS_FLOPPY_NO_DRIVE 0 +%define CMOS_FLOPPY_360kb_525_DRIVE 1 +%define CMOS_FLOPPY_1_2mb_525_DRIVE 2 +%define CMOS_FLOPPY_720kb_35_DRIVE 3 +%define CMOS_FLOPPY_1_44mb_35_DRIVE 4 +%define CMOS_FLOPPY_2_88mb_35_DRIVE 5 + +%define CMOS_GETRAM_LOW 0x30 +%define CMOS_GETRAM_HIGH 0x31 + +; ========================================================================== ; +; Functions related to read operations to CMOS ; +; ========================================================================== ; + +; ========================================================================== ; +; This function sets CMOS register to use. ; +; ; +; param register_to_use (stack), register we want to use for Read operations ; +; ========================================================================== ; +cmos_select_register: + push ebp + mov ebp, esp + + xor al, al + in al, CMOS_GPIO_IN + or al, 0x80 + shl al, 7 + mov bl, byte [ebp-4] + or al, bl + out CMOS_GPIO_OUT, al + + mov esp, ebp + pop ebp + ret + +; ========================================================================== ; +; Really slow delay() for CMOS operations. ; +; ========================================================================== ; +cmos_delay: + push ebp + mov ebp, esp + + push ecx + xor ecx, ecx + .loop: + inc ecx + nop + cmp ecx, 0xff + jne .loop + pop ecx + + mov esp, ebp + pop ebp + ret + +; ========================================================================== ; +; This function is used to get the status of floppy drives on system. ; +; ; +; return value is at eax. ; +; ========================================================================== ; +cmos_get_floppy_data: + push ebp + mov ebp, esp + + push CMOS_FLOPPY_DATA + call cmos_select_register + call cmos_delay + in al, CMOS_GPIO_IN + + mov esp, ebp + pop ebp + ret + + +%endif + diff --git a/src/gdt32table.s b/src/gdt32table.s @@ -1,33 +0,0 @@ - -%ifndef GDT_32_H -%define GDT_32_H 1 - -; Global Descriptor Table & ptrs for that. - -__null: - dq 0 -; code segment (0x9a) -__code: - dw 0xffff - dw 0 - db 0 - db 10011010b - db 11001111b - db 0 -; data segment (0x92) -__data: - dw 0xffff - dw 0 - db 0 - db 10010010b - db 11001111b - db 0 -__end: - -GDT_32_PTR: - dw __end - __null - 1 ; See amd system programmers manual - dd __null -GDT_32_CODE equ __code - __null -GDT_32_DATA equ __data - __null - -%endif diff --git a/src/kernel_loader.s b/src/kernel_loader.s @@ -1,62 +0,0 @@ -; ========================================================================== ; -; This file contains code responsible for rest of the loading process. ; -; At this point, usage of A20 line has been enabled, we've loaded a little ; -; GDT, swapped to 32-bit protected mode, and saved Real mode Data segment & ; -; Boot device to: ; -; BOOT_DEV_DB ; -; REALMODE_DB ; -; ========================================================================== ; - -%ifndef KERNEL_LOADER_S -%define KERNEL_LOADER_S 1 - -%define V8086_MODE_ON 1 -%define V8086_MODE_OFF 0 - -[ BITS 32 ] -; ========================================================================== ; -; The main function of this file. All rest of the functions are called from ; -; this function. ; -; Referring to cs.emu.edu(1), many of bootloaders do achieve ; -; high-memory disk read by constantly swapping between 16 and 32 bit mode. ; -; The constant swaps allows us to use both BIOS interrupts, and 32-bit ; -; addressing. ; -; ========================================================================== ; -kernel_loader: - push ebp - mov ebp, esp - - cli - hlt - - mov esp, ebp - pop ebp - -; ========================================================================== ; -; The memory area reserved for different sort of variables we'll use between ; -; 16 and 32 bit modes. ; -; ========================================================================== ; -KERNEL_LOCATION dw 0 -KERNEL_SIZE dw 0 -KERNEL_ENTRY dw 0 -SECTORS_LOADED db 0 -MULTIBOOT_LOCATION dw 0 -RUNMODE db 0 ; v8086 MODE - -; ========================================================================== ; -; Functions used by kernel_loader for different purposes. ; -; Helper functions for these functions can be found belowe these. ; -; NOTE: Define bitness for every function belove this line! ; -; ========================================================================== ; - - - -; ========================================================================== ; -; Helper functions for kernel loading process. ; -; ========================================================================== ; - - -times SECTOR_COUNT * 1024 - ($-$$) db 0 - -%endif - diff --git a/src/main_loader/kernel_loader.s b/src/main_loader/kernel_loader.s @@ -0,0 +1,62 @@ +; ========================================================================== ; +; This file contains code responsible for rest of the loading process. ; +; At this point, usage of A20 line has been enabled, we've loaded a little ; +; GDT, swapped to 32-bit protected mode, and saved Real mode Data segment & ; +; Boot device to: ; +; BOOT_DEV_DB ; +; REALMODE_DB ; +; ========================================================================== ; + +%ifndef KERNEL_LOADER_S +%define KERNEL_LOADER_S 1 + +%define V8086_MODE_ON 1 +%define V8086_MODE_OFF 0 + +[ BITS 32 ] +; ========================================================================== ; +; The main function of this file. All rest of the functions are called from ; +; this function. ; +; Referring to cs.emu.edu(1), many of bootloaders do achieve ; +; high-memory disk read by constantly swapping between 16 and 32 bit mode. ; +; The constant swaps allows us to use both BIOS interrupts, and 32-bit ; +; addressing. ; +; ========================================================================== ; +kernel_loader: + push ebp + mov ebp, esp + + cli + hlt + + mov esp, ebp + pop ebp + +; ========================================================================== ; +; The memory area reserved for different sort of variables we'll use between ; +; 16 and 32 bit modes. ; +; ========================================================================== ; +KERNEL_LOCATION dw 0 +KERNEL_SIZE dw 0 +KERNEL_ENTRY dw 0 +SECTORS_LOADED db 0 +MULTIBOOT_LOCATION dw 0 +RUNMODE db 0 ; v8086 MODE + +; ========================================================================== ; +; Functions used by kernel_loader for different purposes. ; +; Helper functions for these functions can be found belowe these. ; +; NOTE: Define bitness for every function belove this line! ; +; ========================================================================== ; + + + +; ========================================================================== ; +; Helper functions for kernel loading process. ; +; ========================================================================== ; + + +times SECTOR_COUNT * 1024 - ($-$$) db 0 + +%endif +