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 | 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 | .PHONY: all | ||||||
| all: $(TARGET) | 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