Nyanix

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

commit 99bb06ad448e0fb646dc6b17c2403d65ebf3dd8e
parent c8aa59cb5c7408360e677c702fef74bea9c56a28
Author: k4m1 <k4m1@localhost.localdomain>
Date:   Wed,  9 May 2018 15:12:02 -0400

Add boot.s

Diffstat:
Makefile | 15---------------
src/VGA_COLORS.inc | 26--------------------------
src/a20_gate.inc | 235-------------------------------------------------------------------------------
src/boot.asm | 37-------------------------------------
src/boot.s | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gdt16table.inc | 22----------------------
src/main.inc | 39---------------------------------------
src/messages.inc | 15---------------
src/start.inc | 50--------------------------------------------------
9 files changed, 163 insertions(+), 439 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,15 +0,0 @@ - -as=nasm -asflags=-f bin - -all: - cd src; nasm -f bin -o ../bin/Nyanix boot.asm; -clean: - rm -rf bin/* - -qemu: - qemu-system-x86_64 -full-screen -d guest_errors bin/Nyanix - -qemu-debug: - qemu-system-x86_64 -S -s -gdb tcp::1234 -d in_asm bin/Nyanix - diff --git a/src/VGA_COLORS.inc b/src/VGA_COLORS.inc @@ -1,26 +0,0 @@ - -%ifndef VGA_COLORS_HEADER -%define VGA_COLORS_HEADER - -%define VGA_COLOR_BLACK 0x0 -%define VGA_COLOR_BLUE 0x1 -%define VGA_COLOR_GREEN 0x2 -%define VGA_COLOR_CYAN 0x3 -%define VGA_COLOR_RED 0x4 -%define VGA_COLOR_MAGENTA 0x5 -%define VGA_COLOR_BROWN 0x6 -%define VGA_COLOR_LIGHT_GREY 0x7 -%define VGA_COLOR_DARK_GREY 0x8 -%define VGA_COLOR_LIGHT_BLUE 0x9 -%define VGA_COLOR_LIGHT_GREEN 0xA -%define VGA_COLOR_LIGHT_CYAN 0xB -%define VGA_COLOR_LIGHT_RED 0xC -%define VGA_COLOR_LIGHT_MAGENTA 0xD -%define VGA_COLOR_LIGHT_BROWN 0xE -%define VGA_COLOR_WHITE 0xF - -%endif - - - - diff --git a/src/a20_gate.inc b/src/a20_gate.inc @@ -1,235 +0,0 @@ - -%ifndef a20_gate - -; NOTE: -; This code is intended to be used only from 16 bit real mode! -; Do not attempt to call these functions from protected mode, as they -; may cause unforeseen results. -; TODO: -; Add check for runmode. - -; Function to check wheter a20 gate is enabled or not. -; -; @params none -; @return [ax] 0 if the a20 line is not set, -; 1 if the a20 line is set. -check_a20_gate: - push ebp - mov ebp, esp - pushf - push ds - push es - push di - push si - - cli - - xor ax, ax - mov es, ax - mov di, 0x0500 - mov si, 0x0510 - mov al, byte [es:di] - push ax - mov byte [es:di], 0x00 - mov byte [ds:si], 0xff - - cmp byte [es:di], 0xff - - pop ax - mov byte [ds:si], al - pop ax - mov byte [es:di], al - - mov ax, 0 - je .return - mov ax, 1 - - .return: - sti - pop si - pop di - pop es - pop ds - popf - mov esp, ebp - pop ebp - ret - -; helper functions a20wait and a20wait2. -a20_wait: - in al, 0x64 - test al, 2 - jnz a20_wait - ret -a20_wait2: - in al, 0x64 - test al, 1 - jz a20_wait2 - ret - -; enable a20 line with keyboard controller. -; -; @params none -; @returns none. -; Use check_a20_gate to see wheter succeeded or failed. -ea20_wkbdctl: - push ebp - mov ebp, esp - - cli - - call a20_wait - mov al, 0xAD - out 0x64, al - - call a20_wait - mov al, 0xD0 - out 0x64, al - - call a20_wait2 - in al, 0x60 - push eax - - call a20_wait - mov al, 0xD1 - out 0x64, al - - call a20_wait - pop eax - or al, 2 - out 0x60, al - - call a20_wait - mov al, 0xAE - out 0x64, al - - call a20_wait - - sti - - mov esp, ebp - pop ebp - ret - -; Attempt to enable a20 line via fast a20 gate. -; @param none -; @return none -; -; use check_a20_gate to see wheter succeeded or failed. -ea20_wfeag: - in al, 0x92 - test al, 2 - jnz .ns - or al, 2 - and al, 0xfe - out 0x92, al -.ns: - ret - -; Check wheter a20 gate is supported or not. -; @return [ax] 1 if supported, or 0 if not supported. -a20_issupported: - push ebp - mov ebp, esp - - mov ax, 0x2403 - int 0x15 - jb .ns - cmp ah, 0 - jnz .ns - - mov eax, 1 - jmp .return -.ns: - xor eax, eax -.return: - mov ebp, esp - pop ebp - - -; enable a20 line with BIOS. -; -; @params none -; @return [ax] 0 on success or non-zero on failure. -ea20_wBIOS: - push ebp - mov ebp, esp - - ; Apparently a20 gate is supported - ; so trying to enable it next - mov ax, 0x2402 - int 0x15 - - jb .a20_fail - cmp ah, 0x00 - jnz .a20_fail - - cmp al, 1 - jz .a20_activated - - mov ax, 0x2401 - int 0x15 - jb .a20_fail - cmp ah, 0 - jnz .a20_fail - - .a20_activated: - xor eax, eax - jmp .return - .not_supported: - xor eax, eax - inc eax - jmp .return - .a20_fail: - xor eax, eax - add eax, 2 - jmp .return - .return: - mov esp, ebp - pop ebp - -; Function used for enabling a20 line usage -; -; @params none -; @return [ax] 1 on success -; 0 on fail -enable_a20_gate: - push ebp - mov ebp, esp - - call a20_issupported - cmp ax, 0 - je .not_supported - - xor eax, eax - call ea20_wfeag - call check_a20_gate - test ax, ax - jnz .done - - call ea20_wkbdctl - call check_a20_gate - test ax, ax - jnz .done - - call ea20_wBIOS - test ax, ax - jz .done - xor eax, eax - - test ax, ax - jnz .done - -.not_supported: - xor ax, ax - jmp .return - -.done: - mov eax, 1 -.return: - mov esp, ebp - pop ebp - ret - -%endif - diff --git a/src/boot.asm b/src/boot.asm @@ -1,37 +0,0 @@ - -;*************************************************************************; -; The entry point for Nyanix bootloader. ; -;*************************************************************************; -org 0x7c00 -bits 16 - -; Clear out cpu registers -xor ax, ax -mov fs, ax -mov es, ax -mov ss, ax -mov sp, 0x7c00 - -; Load 2nd stage memory from disk -add ah, 0x02 -inc al -xor dx, dx -add dl, 0x80 -xor cx, cx -add cl, 0x02 -mov bx, _start -int 0x13 - -jmp _start - -times 510-($-$$) db 0x00 -db 0x55 -db 0xAA - -%include "start.inc" - - - - - - diff --git a/src/boot.s b/src/boot.s @@ -0,0 +1,163 @@ +;*****************************************************************************; +; Nyanix ; +; ; +; Nyanix is a simple bootloader aiming for fastest possible boot time. ; +; Other goals are being as bloat-free as possible, and as clean as possible. ; +; ; +; If you wish to contribute to developement of Nyanix bootloader, do git fork ; +; of the current stable version of the bootloader, add your changes, and do a ; +; pull request. The developer(s) will verify, and accept/reject your code ; +; as soon as humanly possible :) ; +; ; +; Copyright 2018 k4m1 <k4m1@protonmail.com> ; +; ; +; Redistribution and use in source and binary forms, ; +; with or without modification, are permitted provided that the following ; +; conditions are met: ; +; ; +; 1. Redistributions of source code must retain the above copyright notice, ; +; this list of conditions and the following disclaimer. ; +; ; +; 2. Redistributions in binary form must reproduce ; +; the above copyright notice, this list of conditions and ; +; the following disclaimer in the documentation and/or other materials ; +; provided with the distribution. ; +; ; +; 3. Neither the name of the copyright holder nor the names of its ; +; contributors may be used to endorse or promote products derived from ; +; this software without specific prior written permission. ; +; ; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ; +; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ; +; THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ; +; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ; +; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ; +; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ; +; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ; +; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ; +; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ; +; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, ; +; EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; +; ; +; ~ Enjoy ; +; ; +; vim: set tw=80 ; +;*****************************************************************************; + +[BITS 16] +org 0x7c00 +section .text + +; We'll start by jumping to 0x0000:stage1 +; in order to clean CS. This is needed as some BIOSes +; do entry to here by setting CS instead of IP. +jmp 0x0000:stage1 + +; Here live all the global variables & definitions needed by 1st stage +; of the bootloader. + +BOOT_DEVICE db 0 ; One byte of memory reserved for boot device ident + +NYANIX_VERSION db "Nyanix 0.1", 0x0A, 0x0D, 0 ; Current version of loader. + +; Our first function label *-* +stage1: + cli + cld + ; Clear rest of segments + xor ax, ax + mov ds, ax + mov fs, ax + mov gs, ax + mov es, ax + mov ss, ax + + ; Store boot-device id from BIOS (dl) to + ; BOOT_DEVICE. + mov dl, [BOOT_DEVICE] + + ; Clear rest of registers + xor bx, bx + xor cx, cx + xor dx, dx + xor di, di + xor si, si + + ; set stack ptr + mov sp, 0x7c00 + mov bp, 0 + + ; Start loading 2nd stage of boot-loader. + sti + mov bx, second_stage_entry + mov dh, 2 + mov dl, [BOOT_DEVICE] + xor ch, ch + xor dh, dh + mov cl, 2 +read_start: + mov di, 5 +.read: + mov ah, 0x02 ; int 13h, ah=2. Disk read + mov al, 1 ; sectors to read + int 0x13 + jc .retry + ; we apparently loaded the sector! Great! + ; check for signature + lea bx, [second_stage_entry] + cmp byte [bx], 'N' + jne .corrupted + cmp byte [bx+1], 'y' + jne .corrupted + cmp byte [bx+2], 'a' + jne .corrupted + cmp byte [bx+3], 'n' + jne .corrupted + + ; Rest of the code seems fine, let's jump! + add bx, 4 + jmp bx + +.retry: + cmp di, 0 + dec di + jg .read + mov si, msg_diskread_failed + call real16_print + jmp .hang + +.corrupted: + mov si, msg_disk_corrupted + call real16_print +.hang: + cli + hlt + jmp .hang + +real16_print: + lodsb + or al, al + jz .done + mov ah, 0x0E + int 0x10 + jmp real16_print +.done: + ret + +times 510-($-$$) db 0x00 +db 0x55 +db 0xAA + +; The entrypoint for second stage bootloader +; This is basicly just signature + nop. +second_stage_entry: + db 'N' + db 'y' + db 'a' + db 'n' + nop +second_stage: + add sp, 0x200 ; adjusting stack ptr + + + diff --git a/src/gdt16table.inc b/src/gdt16table.inc @@ -1,22 +0,0 @@ - -%ifndef GDT_H - -GDT_PTR: - dw GDT_END - GDT_PTR - 1 - dd GDT_HEAD -GDT_HEAD: - dd 0 - dd 0 -GDT_DESC: - dw 0xFFFF - dw 0x0000 - dw 0x0092 - dw 0xCF00 -GDT_END: - -%endif - - - - - diff --git a/src/main.inc b/src/main.inc @@ -1,39 +0,0 @@ - -;********************************************************; -; main() function, calling all of the rest functions ; -; from here. loading GDT, IDT, enabling A20, etc... ; -;********************************************************; - -%include "prints.inc" -%include "messages.inc" - -; Rest of the includes may be found from bottom of this file. - - -; CALL ORDER: -; -; CALL SETUP_GDT -; CALL SETUP_IDT -; CALL ENABLE_20_GATE - -main: - push ebp - mov ebp, esp - - call clear - mov si, MSG_MAIN_BOOTED - call printf - - ; We should not return, but if we do. - ; we'll do it fancy -.end: - mov esp, ebp - pop ebp - ret - -%include "a20_gate.inc" -%include "gdt16table.inc" - - - - diff --git a/src/messages.inc b/src/messages.inc @@ -1,15 +0,0 @@ - -%ifndef MESSAGES_H - -; Add here the messages you want to print out. -; messages shall be in form of: -; -; MSG_<RELATED_FUNCTION/FILE><STATUS>, <NULL BYTE> -; eg. -; MSG_A20STATUS_FAILED db "Failed to enable a20 gate! ", 0x0A, 0x0D, 0 -; - -MSG_MAIN_BOOTED db "BOOTED THE BOARD", 0x0A, 0 - -%endif - diff --git a/src/start.inc b/src/start.inc @@ -1,50 +0,0 @@ - - -;************************************************************; -; Start function is used for re-initializing stack & regs ; -; clearing the screen, calling the main(), and at last ; -; shutting down the machine. ; -;************************************************************; - -global _start -_start: - xor ax, ax - mov es, ax - mov fs, ax - mov ss, ax - mov sp, 0x9c00 ; We've jumped, so increasing stack address with 0x2000 - - mov ax, 0xb800 ; We cannot access es direcctly, so moving video memory address - mov es, ax ; to es via ax. - - ; Enabling video mem - mov ah, 0x0B - xor bx, bx - add bl, 0x11 - int 0x10 - - ; Clearing the screen - call clear - - ; Claring direction flag - cld - ; Resetting video memory - mov ax, 0xb800 - mov es, ax - - ; Disabling interrupts and calling main() - call main - - ; We returned from main() for some reason! that's odd... - cli - hlt - - -%include "main.inc" - - - - - - -