feat: stage0 of a tiny boot loader
This commit is contained in:
		
							parent
							
								
									3fddd705f8
								
							
						
					
					
						commit
						670a7f3bb4
					
				
					 5 changed files with 331 additions and 2 deletions
				
			
		
							
								
								
									
										7
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -4,9 +4,12 @@ TOOLSDIR   := $(TOPDIR)/tools | |||
| 
 | ||||
| RM = echo | ||||
| 
 | ||||
| SUBDIRS	:= kernel lib bin | ||||
| SUBDIRS	:= boot kernel lib bin | ||||
| 
 | ||||
| TARGET	= stupid.iso stupid.tar.gz | ||||
| TARGET	= stupid.tar.gz | ||||
| ifneq ($(OS),Windows_NT) | ||||
| TARGET	+= stupid.iso | ||||
| endif | ||||
| 
 | ||||
| .PHONY: all | ||||
| all: $(TARGET) | ||||
|  |  | |||
							
								
								
									
										22
									
								
								boot/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								boot/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | |||
| AS = fasm | ||||
| RM = rm | ||||
| 
 | ||||
| TARGET = bootcode.bin | ||||
| 
 | ||||
| SRCS	= boot.asm \
 | ||||
| 			const.inc \
 | ||||
| 			a20.inc | ||||
| 
 | ||||
| .PHONY: all | ||||
| all: $(TARGET) | ||||
| 
 | ||||
| $(TARGET): $(SRCS) | ||||
| 	$(AS) boot.asm $@ | ||||
| 
 | ||||
| .PHONY: clean | ||||
| clean: | ||||
| 	$(RM) $(TARGET) | ||||
| 
 | ||||
| .PHONY: install | ||||
| install: $(TARGET) | ||||
| 	@ mkdir -p $(DESTDIR) | ||||
							
								
								
									
										171
									
								
								boot/a20.inc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								boot/a20.inc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,171 @@ | |||
|         ; copy/pasted from https://wiki.osdev.org/A20_Line | ||||
|         ; .... sorry I was lazy :x | ||||
| 
 | ||||
| a20_get_state: | ||||
|         pushf | ||||
|         push si | ||||
|         push di | ||||
|         push ds | ||||
|         push es | ||||
| 
 | ||||
|         cli | ||||
| 
 | ||||
|         xor ax, ax | ||||
|         mov ds, ax | ||||
|         mov si, 0x500 | ||||
| 
 | ||||
|         not ax | ||||
|         mov es, ax | ||||
|         mov di, 0x0510 | ||||
| 
 | ||||
|         mov al, [ds:si]  ; save old values | ||||
|         mov byte [.BufferBelowMB], al | ||||
|         mov al, [es:di] | ||||
|         mov byte [.BufferOverMB], al | ||||
|   | ||||
|         mov ah, 1 ; check byte [0x00100500] == byte [0x0500] | ||||
|         mov byte [ds:si], 0 | ||||
|         mov byte [es:di], 1 | ||||
|         mov al, [ds:si] | ||||
|         cmp al, [es:di] | ||||
|         jne .exit | ||||
|         dec ah | ||||
| .exit: | ||||
|         mov al, [.BufferBelowMB] | ||||
|         mov [ds:si], al | ||||
|         mov al, [.BufferOverMB] | ||||
|         mov [es:di], al | ||||
|         shr ax, 8 | ||||
|         sti | ||||
|         pop es | ||||
|         pop ds | ||||
|         pop di | ||||
|         pop si | ||||
|         popf | ||||
|         ret | ||||
|   | ||||
| .BufferBelowMB: db 0 | ||||
| .BufferOverMB   db 0 | ||||
| 
 | ||||
| 
 | ||||
| a20_query_support: | ||||
|         push bx | ||||
|         clc | ||||
|   | ||||
|         mov ax, 0x2403 | ||||
|         int 0x15 | ||||
|         jc .error | ||||
|   | ||||
|         test ah, ah | ||||
|         jnz .error | ||||
|   | ||||
|         mov ax, bx | ||||
|         pop bx | ||||
|         ret | ||||
| .error: | ||||
|         stc | ||||
|         pop bx | ||||
|         ret | ||||
|   | ||||
| a20_enable_keyboard_controller: | ||||
|         cli | ||||
|   | ||||
|         call .wait_io1 | ||||
|         mov al, 0xad | ||||
|         out 0x64, al | ||||
|   | ||||
|         call .wait_io1 | ||||
|         mov al, 0xd0 | ||||
|         out 0x64, al | ||||
|   | ||||
|         call .wait_io2 | ||||
|         in al, 0x60 | ||||
|         push eax | ||||
|   | ||||
|         call .wait_io1 | ||||
|         mov al, 0xd1 | ||||
|         out 0x64, al | ||||
|   | ||||
|         call .wait_io1 | ||||
|         pop eax | ||||
|         or al, 2 | ||||
|         out 0x60, al | ||||
|   | ||||
|         call .wait_io1 | ||||
|         mov al, 0xae | ||||
|         out 0x64, al | ||||
|   | ||||
|         call .wait_io1 | ||||
|         sti | ||||
|         ret | ||||
| .wait_io1: | ||||
|         in al, 0x64 | ||||
|         test al, 2 | ||||
|         jnz .wait_io1 | ||||
|         ret | ||||
| .wait_io2: | ||||
|         in al, 0x64 | ||||
|         test al, 1 | ||||
|         jz .wait_io2 | ||||
|         ret | ||||
|   | ||||
| ;       out: | ||||
| ;               cf - set on error | ||||
| a20_enable: | ||||
|         clc                                                                     ;       clear cf | ||||
|         pusha | ||||
|         mov bh, 0                                                       ;       clear bh | ||||
|   | ||||
|         call a20_get_state | ||||
|         jc .fast_gate | ||||
|   | ||||
|         test ax, ax | ||||
|         jnz .done | ||||
|   | ||||
|         call a20_query_support | ||||
|         mov bl, al | ||||
|         test bl, 1                                                      ;       enable A20 using keyboard controller | ||||
|         jnz .keybord_controller | ||||
|   | ||||
|         test bl, 2                                                      ;       enable A20 using fast A20 gate | ||||
|         jnz .fast_gate | ||||
| .bios_int: | ||||
|         mov ax, 0x2401 | ||||
|         int 0x15 | ||||
|         jc .fast_gate | ||||
|         test ah, ah | ||||
|         jnz .failed | ||||
|         call a20_get_state | ||||
|         test ax, ax | ||||
|         jnz .done | ||||
| .fast_gate: | ||||
|         in al, 0x92 | ||||
|         test al, 2 | ||||
|         jnz .done | ||||
|   | ||||
|         or al, 2 | ||||
|         and al, 0xfe | ||||
|         out 0x92, al | ||||
|   | ||||
|         call a20_get_state | ||||
|         test ax, ax | ||||
|         jnz .done | ||||
|   | ||||
|         test bh, bh                                                     ;       test if there was an attempt using the keyboard controller | ||||
|         jnz .failed | ||||
| .keybord_controller: | ||||
|         call a20_enable_keyboard_controller | ||||
|         call a20_get_state | ||||
|         test ax, ax | ||||
|         jnz .done | ||||
|   | ||||
|         mov bh, 1                                                       ;       flag enable attempt with keyboard controller | ||||
|   | ||||
|         test bl, 2 | ||||
|         jnz .fast_gate | ||||
|         jmp .failed | ||||
| .failed: | ||||
|         stc | ||||
| .done: | ||||
|         popa | ||||
|         ret | ||||
							
								
								
									
										125
									
								
								boot/boot.asm
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								boot/boot.asm
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,125 @@ | |||
|         ORG 0x7C00 | ||||
|         USE16 | ||||
| 
 | ||||
|         jmp short _start | ||||
|         nop | ||||
| 
 | ||||
|         ; Boot Record | ||||
| OEM_identifier      db 'STUPID ' | ||||
| bytes_per_sector    dw 512 | ||||
| sectors_per_cluster db 1 | ||||
| reserved_sectors    dw 1 | ||||
| FAT_count           db 2 | ||||
| root_dir_entries    dw 224 | ||||
| total_sectors       dw 2880 | ||||
| media_desc_type     db 0xF0 | ||||
| sectors_per_FAT     dw 9 | ||||
| sectors_per_track   dw 18 | ||||
| heads_per_cylinder  dw 2 | ||||
| hidden_sectors      dd 0 | ||||
| large_sector_count  dd 0 | ||||
| 
 | ||||
|         ; Extended Boot Record | ||||
| drive_number db 0 | ||||
| reserved     db 0x90 | ||||
| signature    db 0x29   ; 0x28 or 0x29 | ||||
| volume_id    dd 0xB00B135 ; hope mine will grow :'( | ||||
| volume_label db 'StupidOS   ' | ||||
| system_id    db 'FAT12  ' | ||||
| 
 | ||||
| 
 | ||||
| _start: | ||||
|         cli | ||||
|         cld | ||||
|         jmp 0x0:.canonicalize_cs | ||||
| 
 | ||||
| .canonicalize_cs: | ||||
|         xor ax, ax | ||||
|         mov ds, ax | ||||
|         mov ss, ax | ||||
|         mov es, ax | ||||
|         mov sp, 0x7c00 | ||||
| 
 | ||||
|         ; clear screen | ||||
|         mov al, 0x03 | ||||
|         mov ah, 0 | ||||
|         int 0x10 | ||||
| 
 | ||||
|         mov si, msg_hello | ||||
|         call bios_print | ||||
| 
 | ||||
|         ; reset floppy disk | ||||
| @@: | ||||
|         xor ah, ah | ||||
|         int 0x13 | ||||
|         jc @b | ||||
| 
 | ||||
|         mov si, msg_load_stage | ||||
|         call bios_print | ||||
| 
 | ||||
|         ; read sector into ES:BX (0100:0000) | ||||
|         mov ax, 0x100 ; 100 segment | ||||
|         mov es, ax    ; 0100:0000 (0000:1000) | ||||
|         xor bx, bx | ||||
| 
 | ||||
|         mov ah, 0x2 ; read | ||||
|         mov al, 0x1 ; one sector | ||||
|         mov ch, 0x0 ; cylinder 0 | ||||
|         mov cl, 0x2 ; second sector | ||||
|         mov dh, 0x0 ; head 0 | ||||
|         int 0x13 | ||||
|         jc .error | ||||
| 
 | ||||
|         jmp 0x0:0x1000 | ||||
| 
 | ||||
| .error: | ||||
|         mov si, msg_error_sector | ||||
|         call bios_print | ||||
| 
 | ||||
|         hlt | ||||
|         jmp $ | ||||
| 
 | ||||
| bios_print: | ||||
|         lodsb | ||||
|         or al, al | ||||
|         jz @f | ||||
|         mov ah, 0x0E | ||||
|         int 0x10 | ||||
|         jmp bios_print | ||||
| @@: | ||||
|         ret | ||||
| 
 | ||||
| msg_hello        db "StupidOS Bootloader", 0x0D, 0x0A, 0 | ||||
| msg_load_stage   db "Loading next stage", 0x0D, 0x0A, 0 | ||||
| msg_error_sector db "ERROR: Can't read sector", 0x0D, 0x0A, 0 | ||||
| 
 | ||||
|         rb 0x7C00+512-2-$ | ||||
|         db 0x55, 0xAA | ||||
| 
 | ||||
| ; ---------- stage 1 -------------- | ||||
| 
 | ||||
|         ORG 0x1000 | ||||
| stage2: | ||||
|         push cs | ||||
|         pop ds | ||||
| 
 | ||||
|         mov si, msg_stage2 | ||||
|         call bios_print | ||||
| 
 | ||||
|         call a20_enable | ||||
|         jc .error_a20 | ||||
| 
 | ||||
|         xchg bx, bx | ||||
| 
 | ||||
|         jmp .hang | ||||
| .error_a20: | ||||
|         mov si, msg_error_a20 | ||||
|         call bios_print | ||||
| .hang: | ||||
|         hlt | ||||
|         jmp $ | ||||
| 
 | ||||
|         INCLUDE 'a20.inc' | ||||
| 
 | ||||
| msg_stage2    db "StupidOS Bootloader (Stage 2)", 0x0D, 0x0A, 0 | ||||
| msg_error_a20 db "ERROR: can't enable a20 line", 0x0D, 0x0A, 0 | ||||
							
								
								
									
										8
									
								
								boot/const.inc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								boot/const.inc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| 
 | ||||
| ; -------- Address ---------- | ||||
| STAGE0_BASE    = 0x7C00 | ||||
| STAGE1_BASE    = 0x1000 | ||||
| DISK_BUFFER    = 0x8000 | ||||
| KERNEL_PRELOAD = 0xF000 | ||||
| STACK_TOP      = 0x7000 | ||||
| 
 | ||||
		Loading…
	
	Add table
		
		Reference in a new issue