Nyanix

Bootloader
Log | Files | Refs | LICENSE

main_loader.s (3824B)


      1 ; =========================================================================== ;
      2 ; /src/main/main_loader.s                                                     ;
      3 ; Copyright (C) 2018, k4m1 <k4m1@protonmail.com>                              ;
      4 ; See /LICENSE for whole license text.                                        ;
      5 ;                                                                             ;
      6 ; This is the main loader code, with a20 gate enabled, running in unreal mode ;
      7 ; and having located to suitable place, it's time to start loading the kernel ;
      8 ; from boot disk.                                                             ;
      9 ; =========================================================================== ;
     10 
     11 [ BITS 16 ]
     12 
     13 %ifndef __LOADER_MAIN_S__
     14 %define __LOADER_MAIN_S__ 1
     15 
     16 ; =========================================================================== ;
     17 ; Variables needed for kernel loading process.                                ;
     18 ; =========================================================================== ;
     19 
     20 sectors_remaining 	dw 1 		; the amount of sectors to load
     21 kernel_sectors_loaded 	dw 0
     22 
     23 main_loader:
     24 	push 	ebp
     25 	mov 	ebp, esp
     26 
     27 	xor 	eax, eax
     28 	xor 	ebx, ebx
     29 	xor	ecx, ecx
     30 
     31 	; this is a loop for loading up to 255KB kernels.
     32 	; we'll be loading from disk in 15kb chunks.
     33 
     34 	.load_disk_loop:
     35 		; check if there is more than 15KB left to load
     36 		cmp	word [sectors_remaining], 15
     37 		jle	.final_iteration
     38 
     39 		; adjust the entry-address for load
     40 		mov	eax, kernel_entry_address
     41 		xor	ebx, ebx
     42 		mov	bx, word [kernel_sectors_loaded]
     43 		imul	ebx, 1024
     44 		add	eax, ebx
     45 
     46 		; load next 15 Kb from disk.
     47 		mov	bx, word [boot_device_db]
     48 		mov	cl,  15
     49 		call	load_sectors
     50 
     51 		mov	bx, word [kernel_sectors_loaded]
     52 		add	bx, 15
     53 		mov	word [kernel_sectors_loaded], bx
     54 
     55 		mov	bx, word [sectors_remaining]
     56 		sub	bx, 15
     57 		mov	word [sectors_remaining], bx
     58 
     59 		jmp	.load_disk_loop
     60 
     61 	; final iteration of disk-load loop
     62 	.final_iteration:
     63 		mov	eax, kernel_entry_address
     64 		xor	ebx, ebx
     65 		mov	bx, word [kernel_sectors_loaded]
     66 		imul	ebx, 1024
     67 		add	eax, ebx
     68 
     69 		mov	bl, byte [boot_device_db]
     70 		mov	cl, byte [sectors_remaining]
     71 		call	load_sectors
     72 
     73 	; disk read is finished, time for relocation.
     74 	mov	esi, kernel_entry_address
     75 	mov	edi, 0x10000
     76 	xor	ecx, ecx
     77 	mov	cx, word [kernel_sectors_loaded]
     78 	imul	ecx, 1024
     79 
     80 	.relocate_loop:
     81 		mov	al, byte [esi+ecx]
     82 		mov	byte [edi+ecx], al
     83 		loop	.relocate_loop
     84 
     85 	mov	al, byte [esi]
     86 	mov	byte [edi], al
     87 
     88 	; jump	to protected mode
     89 	mov	eax, cr0
     90 	or	al, 1
     91 	mov	cr0, eax
     92 
     93 	; jump to entry of kernel
     94 	jmp	edi
     95 
     96 	.fail:
     97 		mov 	esi, msg_kernel_not_found
     98 		call 	panic
     99 
    100 msg_kernel_not_found db "Kernel not found.", 0x0A, 0
    101 
    102 ; =========================================================================== ;
    103 ; Helper functions for kernel loading process.                                ;
    104 ; =========================================================================== ;
    105 
    106 ; Function to load N amount of sectors starting from
    107 ; address X at device Y
    108 ;
    109 ; Initial address at EAX
    110 ; Boot device at bl 
    111 ; Sector count at cl
    112 load_sectors:
    113 	push 	ebp
    114 	mov 	ebp, esp
    115 
    116 	mov 	dh, cl  			; Sector count
    117 	mov 	byte [.sectors_to_load], cl 
    118 	mov 	dl, bl 				; boot device
    119 	mov 	byte [.boot_device], bl
    120 
    121 	mov 	ebx, eax	 		; initial address
    122 	mov  	byte [.sectors_left], cl
    123 	xor 	ch, ch
    124 	xor 	dh, dh
    125 	mov 	cl, 0x02
    126 	xor 	eax, eax
    127 	.read_start:
    128 		mov 	di, 15
    129 	.read:
    130 		mov 	ah, 0x02
    131 		mov 	al, [.sectors_left]
    132 		int 	0x13
    133 		jc 	.retry
    134 		sub 	[.sectors_left], al
    135 		jz 	.read_done
    136 		mov 	cl, 0x01
    137 		xor 	dh, 1
    138 		jnz 	.read_start
    139 		inc 	ch
    140 		jmp 	.read_start
    141 	.retry:
    142 		; reset disk
    143 		xor 	ah, ah
    144 		int 	0x13
    145 		dec 	di
    146 		jnz 	.read
    147 		mov 	esi, msg_disk_read_failed
    148 		call 	panic
    149 	.read_done:
    150 		mov 	esp, ebp
    151 		pop 	ebp
    152 		ret
    153 
    154 	.sectors_to_load 	db 0
    155 	.boot_device 		db 0
    156 	.sectors_left 		db 0
    157 
    158 
    159 %endif
    160 
    161 kernel_entry_address: