Kernel now is loaded from a partition, allowing a separate MBR bootloader if desired
This commit is contained in:
		
							
								
								
									
										24
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								Makefile
									
									
									
									
									
								
							@@ -7,16 +7,29 @@ LFLAGS = -Wl,--gc-sections -Wl,--print-gc-sections -m32 -nostartfiles -nostdlib
 | 
				
			|||||||
ifeq ($(OUTFILE),)
 | 
					ifeq ($(OUTFILE),)
 | 
				
			||||||
OUTFILE = virtdisk.bin
 | 
					OUTFILE = virtdisk.bin
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					ifeq ($(PARTSTART),)
 | 
				
			||||||
 | 
					PARTSTART = 2048
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PARTVBR=$(shell echo "$(PARTSTART) * (2^9)" | bc)
 | 
				
			||||||
 | 
					PARTVBRBOOT=$(shell echo "$(PARTVBR) + 90" | bc)
 | 
				
			||||||
 | 
					KERNSEC=$(shell echo "$(PARTSTART) + 4" | bc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: $(OUTFILE)
 | 
					.PHONY: $(OUTFILE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: $(OUTFILE)
 | 
					all: $(OUTFILE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(OUTFILE): boot.bin kernel.bin
 | 
					$(OUTFILE): boot.bin boot_partition.bin kernel.bin
 | 
				
			||||||
	# Copy to boot sector, don't overwrite MBR
 | 
						# Copy system bootloader to boot sector, don't overwrite MBR
 | 
				
			||||||
	dd bs=400 count=1 conv=notrunc if=boot.bin of=$@
 | 
						dd bs=400 count=1 conv=notrunc if=boot.bin of=$@
 | 
				
			||||||
	# Write kernel beyond boot sector, maximum 128K (256 sectors)
 | 
						# Ensure partition VBR contains EB 5A
 | 
				
			||||||
	dd bs=512 count=256 seek=1 conv=notrunc if=kernel.bin of=$@
 | 
						echo -n -e '\xeb\x5a' | dd bs=1 seek=$(PARTVBR) count=2 conv=notrunc of=$@
 | 
				
			||||||
 | 
						# Copy kernel bootloader to partition VBR
 | 
				
			||||||
 | 
						dd bs=1 count=420 seek=$(PARTVBRBOOT) conv=notrunc if=boot_partition.bin of=$@
 | 
				
			||||||
 | 
						# TODO Check that disk has enough reserved sectors,
 | 
				
			||||||
 | 
						# currently this will overwrite the disk if too few
 | 
				
			||||||
 | 
						# Write kernel beyond boot sector, maximum 64K (128 sectors)
 | 
				
			||||||
 | 
						dd bs=512 count=128 seek=$(KERNSEC) conv=notrunc if=kernel.bin of=$@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
kernel.bin: out.o link.ld usermode.o
 | 
					kernel.bin: out.o link.ld usermode.o
 | 
				
			||||||
	clang $(LFLAGS) -Wl,-M -Tlink.ld -ffreestanding -o $@ out.o usermode.o
 | 
						clang $(LFLAGS) -Wl,-M -Tlink.ld -ffreestanding -o $@ out.o usermode.o
 | 
				
			||||||
@@ -37,8 +50,7 @@ out.o: $(objects)
 | 
				
			|||||||
	clang $(CFLAGS) -ffunction-sections -fdata-sections -Os -o $@ $<
 | 
						clang $(CFLAGS) -ffunction-sections -fdata-sections -Os -o $@ $<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
virtdisk:
 | 
					virtdisk:
 | 
				
			||||||
	dd bs=1M count=32 if=/dev/zero of=virtdisk.bin
 | 
						cp virtdisk.bin.ex virtdisk.bin
 | 
				
			||||||
	echo -n -e '\x55\xaa' | dd bs=1 seek=510 conv=notrunc of=virtdisk.bin
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	rm -f $(objects) out.o kernel.bin boot.bin usermode.bin
 | 
						rm -f $(objects) out.o kernel.bin boot.bin usermode.bin
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										219
									
								
								boot.nasm
									
									
									
									
									
								
							
							
						
						
									
										219
									
								
								boot.nasm
									
									
									
									
									
								
							@@ -1,6 +1,8 @@
 | 
				
			|||||||
secreadcnt equ 0x38
 | 
					; This boots the active partition.
 | 
				
			||||||
kernelreads equ 0x10000/(512*secreadcnt) ; 64K / Sector Size FIXME This underestimates when kernel size is not divisible by bytes per read
 | 
					; Relocates self to 0x7E00, loads the 
 | 
				
			||||||
[ORG 0x7c00]
 | 
					; first sector of active partition
 | 
				
			||||||
 | 
					; to 0x7C00 and jumps
 | 
				
			||||||
 | 
					[ORG 0x7C00]
 | 
				
			||||||
[BITS 16]
 | 
					[BITS 16]
 | 
				
			||||||
xor ax, ax
 | 
					xor ax, ax
 | 
				
			||||||
mov ds, ax
 | 
					mov ds, ax
 | 
				
			||||||
@@ -8,68 +10,50 @@ mov es, ax
 | 
				
			|||||||
mov ax, 0x8000
 | 
					mov ax, 0x8000
 | 
				
			||||||
mov ss, ax
 | 
					mov ss, ax
 | 
				
			||||||
mov sp, 0xFF00
 | 
					mov sp, 0xFF00
 | 
				
			||||||
 | 
					; Relocate self
 | 
				
			||||||
 | 
					mov di, 0x7E00
 | 
				
			||||||
 | 
					mov si, 0x7C00
 | 
				
			||||||
 | 
					mov cx, 512
 | 
				
			||||||
 | 
					rep movsw
 | 
				
			||||||
 | 
					jmp 0:relocated
 | 
				
			||||||
 | 
					; TODO Make this calculated, somehow
 | 
				
			||||||
 | 
					[SECTION RELOC vstart=0x7E20]
 | 
				
			||||||
 | 
					relocated:
 | 
				
			||||||
mov ah, 0x41 ; int 13 extensions check
 | 
					mov ah, 0x41 ; int 13 extensions check
 | 
				
			||||||
mov bx, 0x55AA
 | 
					mov bx, 0x55AA
 | 
				
			||||||
int 0x13
 | 
					int 0x13
 | 
				
			||||||
jc no_exten
 | 
					jc no_int13
 | 
				
			||||||
mov cx, kernelreads
 | 
					; Find active partition
 | 
				
			||||||
read_loop:
 | 
					xor cx, cx
 | 
				
			||||||
 | 
					mov si, 0x7E00+0x1BE
 | 
				
			||||||
 | 
					.find_active:
 | 
				
			||||||
 | 
					lodsb
 | 
				
			||||||
 | 
					bt ax, 7
 | 
				
			||||||
 | 
					jc read
 | 
				
			||||||
 | 
					add si, 15
 | 
				
			||||||
 | 
					inc cl
 | 
				
			||||||
 | 
					cmp cl, 4
 | 
				
			||||||
 | 
					jl .find_active
 | 
				
			||||||
 | 
					jmp err
 | 
				
			||||||
 | 
					read:
 | 
				
			||||||
 | 
					; Put partition start LBA in disk address packet
 | 
				
			||||||
 | 
					add si, 7
 | 
				
			||||||
 | 
					mov di, addr_packet_start_block
 | 
				
			||||||
 | 
					movsw
 | 
				
			||||||
 | 
					movsw
 | 
				
			||||||
 | 
					; Load the first sector of the partition
 | 
				
			||||||
xor ax, ax
 | 
					xor ax, ax
 | 
				
			||||||
mov ah, 0x42
 | 
					mov ah, 0x42
 | 
				
			||||||
mov si, addr_packet
 | 
					mov si, addr_packet
 | 
				
			||||||
int 0x13
 | 
					int 0x13
 | 
				
			||||||
jc err
 | 
					jc err
 | 
				
			||||||
add word [addr_packet_transfer_buff_seg], (secreadcnt*512)/16
 | 
					; Jump to partition boot
 | 
				
			||||||
add word [addr_packet_start_block], secreadcnt
 | 
					jmp 0:0x7C00
 | 
				
			||||||
loop read_loop
 | 
					
 | 
				
			||||||
entry:
 | 
					no_int13:
 | 
				
			||||||
;mov ax,0x2403 ; A20 BIOS Support
 | 
					mov si, no_exten_str
 | 
				
			||||||
;int 0x15
 | 
					mov cx, no_exten_str_end - no_exten_str
 | 
				
			||||||
;jb .no_a20
 | 
					jmp print
 | 
				
			||||||
;cmp ah,0
 | 
					 | 
				
			||||||
;jnz .no_a20
 | 
					 | 
				
			||||||
;mov ax,0x2401 ; A20 BIOS Activate
 | 
					 | 
				
			||||||
;int 0x15
 | 
					 | 
				
			||||||
;.no_a20:
 | 
					 | 
				
			||||||
cli             ; no interrupts
 | 
					 | 
				
			||||||
xor ax,ax
 | 
					 | 
				
			||||||
mov ds, ax
 | 
					 | 
				
			||||||
lgdt [gdt_desc]  ; load gdt register
 | 
					 | 
				
			||||||
mov eax, cr0    ; set pmode bit
 | 
					 | 
				
			||||||
or al, 1
 | 
					 | 
				
			||||||
mov cr0, eax
 | 
					 | 
				
			||||||
jmp 08h:Pmode
 | 
					 | 
				
			||||||
no_exten:
 | 
					 | 
				
			||||||
; read with CHS
 | 
					 | 
				
			||||||
; FIXME This only reads up to sector count
 | 
					 | 
				
			||||||
mov ah,8
 | 
					 | 
				
			||||||
int 0x13 ; geometry
 | 
					 | 
				
			||||||
and cx, 0x3f
 | 
					 | 
				
			||||||
push cx
 | 
					 | 
				
			||||||
push 0x0080 ; DH=head,DL=disk
 | 
					 | 
				
			||||||
push 0x2000 ; buffer seg
 | 
					 | 
				
			||||||
push 2 ; sector
 | 
					 | 
				
			||||||
.loop:
 | 
					 | 
				
			||||||
mov ax, [esp]
 | 
					 | 
				
			||||||
push 0xb800
 | 
					 | 
				
			||||||
pop es
 | 
					 | 
				
			||||||
xor di,di
 | 
					 | 
				
			||||||
call hexprint
 | 
					 | 
				
			||||||
mov ax, [esp+2]
 | 
					 | 
				
			||||||
mov es, ax
 | 
					 | 
				
			||||||
mov ax, 0x0201
 | 
					 | 
				
			||||||
mov cx, [esp]
 | 
					 | 
				
			||||||
xor bx,bx
 | 
					 | 
				
			||||||
mov dx, [esp+4]
 | 
					 | 
				
			||||||
int 0x13
 | 
					 | 
				
			||||||
jc err
 | 
					 | 
				
			||||||
add word [esp+2], 0x20
 | 
					 | 
				
			||||||
mov cx, [esp]
 | 
					 | 
				
			||||||
inc cl
 | 
					 | 
				
			||||||
mov [esp], cx
 | 
					 | 
				
			||||||
cmp cl, [esp+6]
 | 
					 | 
				
			||||||
jg entry
 | 
					 | 
				
			||||||
jmp .loop
 | 
					 | 
				
			||||||
err:
 | 
					err:
 | 
				
			||||||
mov bx, ax
 | 
					mov bx, ax
 | 
				
			||||||
mov si, string
 | 
					mov si, string
 | 
				
			||||||
@@ -83,126 +67,17 @@ err_print:
 | 
				
			|||||||
lodsb
 | 
					lodsb
 | 
				
			||||||
stosw
 | 
					stosw
 | 
				
			||||||
loop err_print
 | 
					loop err_print
 | 
				
			||||||
;add di, 2
 | 
					 | 
				
			||||||
;mov ax, bx
 | 
					 | 
				
			||||||
;call hexprint
 | 
					 | 
				
			||||||
hlt_loop:
 | 
					hlt_loop:
 | 
				
			||||||
hlt
 | 
					hlt
 | 
				
			||||||
jmp hlt_loop
 | 
					jmp hlt_loop
 | 
				
			||||||
hexprint:
 | 
					 | 
				
			||||||
xor cx, cx
 | 
					 | 
				
			||||||
mov bl, al
 | 
					 | 
				
			||||||
shr al, 4
 | 
					 | 
				
			||||||
jmp .donibble
 | 
					 | 
				
			||||||
.nibble2:
 | 
					 | 
				
			||||||
mov al, bl
 | 
					 | 
				
			||||||
inc cx
 | 
					 | 
				
			||||||
.donibble:
 | 
					 | 
				
			||||||
and al, 0x0F
 | 
					 | 
				
			||||||
cmp al, 0x0A
 | 
					 | 
				
			||||||
jl .noadjust
 | 
					 | 
				
			||||||
add al, 'A' - '0' - 10
 | 
					 | 
				
			||||||
.noadjust:
 | 
					 | 
				
			||||||
add al, '0'
 | 
					 | 
				
			||||||
mov ah, 0x7
 | 
					 | 
				
			||||||
stosw
 | 
					 | 
				
			||||||
test cx, cx
 | 
					 | 
				
			||||||
jz .nibble2
 | 
					 | 
				
			||||||
ret
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[BITS 32]
 | 
					 | 
				
			||||||
Pmode:
 | 
					 | 
				
			||||||
mov eax, 0x10
 | 
					 | 
				
			||||||
mov ds, ax
 | 
					 | 
				
			||||||
mov es, ax
 | 
					 | 
				
			||||||
mov fs, ax
 | 
					 | 
				
			||||||
mov gs, ax
 | 
					 | 
				
			||||||
mov ss, ax
 | 
					 | 
				
			||||||
; check A20
 | 
					 | 
				
			||||||
.a20:
 | 
					 | 
				
			||||||
mov edi, 0x107C00
 | 
					 | 
				
			||||||
mov esi, 0x007C00
 | 
					 | 
				
			||||||
mov [esi], esi
 | 
					 | 
				
			||||||
mov [edi], edi
 | 
					 | 
				
			||||||
cmpsd
 | 
					 | 
				
			||||||
jne .kernel
 | 
					 | 
				
			||||||
call enable_A20
 | 
					 | 
				
			||||||
;in al, 0x92 ; fast A20
 | 
					 | 
				
			||||||
;test al, 2
 | 
					 | 
				
			||||||
;jnz .fa20_end
 | 
					 | 
				
			||||||
;or al, 2
 | 
					 | 
				
			||||||
;and al, 0xFE
 | 
					 | 
				
			||||||
;out 0x92, al
 | 
					 | 
				
			||||||
;.fa20_end:
 | 
					 | 
				
			||||||
jmp .a20
 | 
					 | 
				
			||||||
.kernel:
 | 
					 | 
				
			||||||
;mov dword [0xb8000], 0x07000700 | 'P' | 'M' << 16
 | 
					 | 
				
			||||||
;mov dword [0xb8004], 0x07000700 | 'O' | 'D' << 16
 | 
					 | 
				
			||||||
;mov dword [0xb8008], 0x07000700 | 'E' | ' ' << 16
 | 
					 | 
				
			||||||
mov esi, 0x20000
 | 
					 | 
				
			||||||
mov edi, 0x100000
 | 
					 | 
				
			||||||
mov ecx, 0x10000
 | 
					 | 
				
			||||||
rep movsb
 | 
					 | 
				
			||||||
jmp 08h:0x100000
 | 
					 | 
				
			||||||
enable_A20:
 | 
					 | 
				
			||||||
        cli
 | 
					 | 
				
			||||||
        call    a20wait
 | 
					 | 
				
			||||||
        mov     al,0xAD
 | 
					 | 
				
			||||||
        out     0x64,al
 | 
					 | 
				
			||||||
        call    a20wait
 | 
					 | 
				
			||||||
        mov     al,0xD0
 | 
					 | 
				
			||||||
        out     0x64,al
 | 
					 | 
				
			||||||
        call    a20wait2
 | 
					 | 
				
			||||||
        in      al,0x60
 | 
					 | 
				
			||||||
        push    eax
 | 
					 | 
				
			||||||
        call    a20wait
 | 
					 | 
				
			||||||
        mov     al,0xD1
 | 
					 | 
				
			||||||
        out     0x64,al
 | 
					 | 
				
			||||||
        call    a20wait
 | 
					 | 
				
			||||||
        pop     eax
 | 
					 | 
				
			||||||
        or      al,2
 | 
					 | 
				
			||||||
        out     0x60,al
 | 
					 | 
				
			||||||
        call    a20wait
 | 
					 | 
				
			||||||
        mov     al,0xAE
 | 
					 | 
				
			||||||
        out     0x64,al
 | 
					 | 
				
			||||||
        call    a20wait
 | 
					 | 
				
			||||||
        ret
 | 
					 | 
				
			||||||
a20wait:
 | 
					 | 
				
			||||||
        in      al,0x64
 | 
					 | 
				
			||||||
        test    al,2
 | 
					 | 
				
			||||||
        jnz     a20wait
 | 
					 | 
				
			||||||
        ret
 | 
					 | 
				
			||||||
a20wait2:
 | 
					 | 
				
			||||||
        in      al,0x64
 | 
					 | 
				
			||||||
        test    al,1
 | 
					 | 
				
			||||||
        jz      a20wait2
 | 
					 | 
				
			||||||
        ret
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
gdt_desc:
 | 
					 | 
				
			||||||
    dw gdt_end - gdt
 | 
					 | 
				
			||||||
    dd gdt
 | 
					 | 
				
			||||||
gdt:
 | 
					 | 
				
			||||||
gdt_null: dq 0
 | 
					 | 
				
			||||||
gdt_code: dw 0xFFFF, 0     ; bits 0-15 limit (4GB), bits 0-15 base address
 | 
					 | 
				
			||||||
          db 0             ; bits 16-23 base address
 | 
					 | 
				
			||||||
          db 10011010b     ; access byte
 | 
					 | 
				
			||||||
          db 11001111b     ; bits 16-19 limit (4GB), 4 bits flags
 | 
					 | 
				
			||||||
          db 0 ; bits 24-31 base address
 | 
					 | 
				
			||||||
gdt_data: dw 0xFFFF, 0     ; bits 0-15 limit (4GB), bits 0-15 base address
 | 
					 | 
				
			||||||
          db 0             ; bits 16-23 base address
 | 
					 | 
				
			||||||
          db 10010010b     ; access byte
 | 
					 | 
				
			||||||
          db 11001111b     ; bits 16-19 limit (4GB), 4 bits flags
 | 
					 | 
				
			||||||
          db 0 ; bits 24-31 base address
 | 
					 | 
				
			||||||
gdt_end:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
string: db 'DISK ERROR'
 | 
					string: db 'DISK ERROR'
 | 
				
			||||||
string_end:
 | 
					string_end:
 | 
				
			||||||
;no_exten_str: db 'NO INT13 EXTEN'
 | 
					no_exten_str: db 'NO INT13 EXTEN'
 | 
				
			||||||
;no_exten_str_end:
 | 
					no_exten_str_end:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
addr_packet:
 | 
					addr_packet:
 | 
				
			||||||
db 0x10, 0x00 ; size, reserved
 | 
					db 0x10, 0x00 ; size, reserved
 | 
				
			||||||
dw secreadcnt ; blocks
 | 
					dw 1 ; blocks
 | 
				
			||||||
addr_packet_transfer_buff_off: dw 0x0000 ; transfer buffer offset
 | 
					addr_packet_transfer_buff_off: dw 0x7C00 ; transfer buffer offset
 | 
				
			||||||
addr_packet_transfer_buff_seg: dw 0x2000 ; transfer buffer segment
 | 
					addr_packet_transfer_buff_seg: dw 0x0000 ; transfer buffer segment
 | 
				
			||||||
addr_packet_start_block: dq 1 ; start block
 | 
					addr_packet_start_block: dq 0 ; start block
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										136
									
								
								boot_partition.nasm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								boot_partition.nasm
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,136 @@
 | 
				
			|||||||
 | 
					; This boots *from a FAT partition*
 | 
				
			||||||
 | 
					; So it starts at 0x7C00+90, the offset of
 | 
				
			||||||
 | 
					; the boot code in a FAT VBR
 | 
				
			||||||
 | 
					secreadcnt equ 0x38
 | 
				
			||||||
 | 
					kernelreads equ 0x10000/(512*secreadcnt) ; 64K / Sector Size FIXME This underestimates when kernel size is not divisible by bytes per read
 | 
				
			||||||
 | 
					[ORG 0x7c00+90]
 | 
				
			||||||
 | 
					[BITS 16]
 | 
				
			||||||
 | 
					xor ax, ax
 | 
				
			||||||
 | 
					mov ds, ax
 | 
				
			||||||
 | 
					mov es, ax
 | 
				
			||||||
 | 
					mov ax, 0x8000
 | 
				
			||||||
 | 
					mov ss, ax
 | 
				
			||||||
 | 
					mov sp, 0xFF00
 | 
				
			||||||
 | 
					; FIXME Assumes INT 13 Extension support
 | 
				
			||||||
 | 
					mov ah, 0x42
 | 
				
			||||||
 | 
					mov si, addr_packet
 | 
				
			||||||
 | 
					int 0x13
 | 
				
			||||||
 | 
					jc err
 | 
				
			||||||
 | 
					xor cx, cx
 | 
				
			||||||
 | 
					mov si, 0x7E00+0x1BE
 | 
				
			||||||
 | 
					.find_active:
 | 
				
			||||||
 | 
					lodsb
 | 
				
			||||||
 | 
					bt ax, 7
 | 
				
			||||||
 | 
					jc read
 | 
				
			||||||
 | 
					add si, 15
 | 
				
			||||||
 | 
					inc cl
 | 
				
			||||||
 | 
					cmp cl, 4
 | 
				
			||||||
 | 
					jl .find_active
 | 
				
			||||||
 | 
					jmp err
 | 
				
			||||||
 | 
					read:
 | 
				
			||||||
 | 
					mov dh, cl ; Store active partition
 | 
				
			||||||
 | 
					add si, 7
 | 
				
			||||||
 | 
					mov di, addr_packet_start_block
 | 
				
			||||||
 | 
					lodsw
 | 
				
			||||||
 | 
					; Offset of kernel in partition
 | 
				
			||||||
 | 
					add ax, 4
 | 
				
			||||||
 | 
					stosw
 | 
				
			||||||
 | 
					lodsw
 | 
				
			||||||
 | 
					adc ax, 0
 | 
				
			||||||
 | 
					stosw
 | 
				
			||||||
 | 
					mov cx, kernelreads
 | 
				
			||||||
 | 
					read_loop:
 | 
				
			||||||
 | 
					xor ax, ax
 | 
				
			||||||
 | 
					mov ah, 0x42
 | 
				
			||||||
 | 
					mov si, addr_packet
 | 
				
			||||||
 | 
					int 0x13
 | 
				
			||||||
 | 
					jc err
 | 
				
			||||||
 | 
					add word [addr_packet_transfer_buff_seg], (secreadcnt*512)/16
 | 
				
			||||||
 | 
					add word [addr_packet_start_block], secreadcnt
 | 
				
			||||||
 | 
					loop read_loop
 | 
				
			||||||
 | 
					entry:
 | 
				
			||||||
 | 
					cli             ; no interrupts
 | 
				
			||||||
 | 
					xor ax,ax
 | 
				
			||||||
 | 
					mov ds, ax
 | 
				
			||||||
 | 
					lgdt [gdt_desc]  ; load gdt register
 | 
				
			||||||
 | 
					mov eax, cr0    ; set pmode bit
 | 
				
			||||||
 | 
					or al, 1
 | 
				
			||||||
 | 
					mov cr0, eax
 | 
				
			||||||
 | 
					jmp 08h:Pmode
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
					mov si, string
 | 
				
			||||||
 | 
					mov cx, string_end - string
 | 
				
			||||||
 | 
					print:
 | 
				
			||||||
 | 
					push 0xb800
 | 
				
			||||||
 | 
					pop es
 | 
				
			||||||
 | 
					xor di, di
 | 
				
			||||||
 | 
					mov ah, 0x7
 | 
				
			||||||
 | 
					err_print:
 | 
				
			||||||
 | 
					lodsb
 | 
				
			||||||
 | 
					stosw
 | 
				
			||||||
 | 
					loop err_print
 | 
				
			||||||
 | 
					hlt_loop:
 | 
				
			||||||
 | 
					hlt
 | 
				
			||||||
 | 
					jmp hlt_loop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[BITS 32]
 | 
				
			||||||
 | 
					Pmode:
 | 
				
			||||||
 | 
					mov eax, 0x10
 | 
				
			||||||
 | 
					mov ds, ax
 | 
				
			||||||
 | 
					mov es, ax
 | 
				
			||||||
 | 
					mov fs, ax
 | 
				
			||||||
 | 
					mov gs, ax
 | 
				
			||||||
 | 
					mov ss, ax
 | 
				
			||||||
 | 
					; check A20
 | 
				
			||||||
 | 
					.a20:
 | 
				
			||||||
 | 
					mov edi, 0x107C00
 | 
				
			||||||
 | 
					mov esi, 0x007C00
 | 
				
			||||||
 | 
					mov [esi], esi
 | 
				
			||||||
 | 
					mov [edi], edi
 | 
				
			||||||
 | 
					cmpsd
 | 
				
			||||||
 | 
					jne .kernel
 | 
				
			||||||
 | 
					; FIXME It's annoying that fast A20
 | 
				
			||||||
 | 
					; will crash old systems, but it's
 | 
				
			||||||
 | 
					; just so small...
 | 
				
			||||||
 | 
					in al, 0x92 ; fast A20
 | 
				
			||||||
 | 
					test al, 2
 | 
				
			||||||
 | 
					jnz .fa20_end
 | 
				
			||||||
 | 
					or al, 2
 | 
				
			||||||
 | 
					and al, 0xFE
 | 
				
			||||||
 | 
					out 0x92, al
 | 
				
			||||||
 | 
					.fa20_end:
 | 
				
			||||||
 | 
					jmp .a20
 | 
				
			||||||
 | 
					.kernel:
 | 
				
			||||||
 | 
					mov esi, 0x7E00
 | 
				
			||||||
 | 
					mov edi, 0x100000
 | 
				
			||||||
 | 
					mov ecx, 0x10000
 | 
				
			||||||
 | 
					rep movsb
 | 
				
			||||||
 | 
					xchg bx,bx
 | 
				
			||||||
 | 
					jmp 08h:0x100000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gdt_desc:
 | 
				
			||||||
 | 
					    dw gdt_end - gdt
 | 
				
			||||||
 | 
					    dd gdt
 | 
				
			||||||
 | 
					gdt:
 | 
				
			||||||
 | 
					gdt_null: dq 0
 | 
				
			||||||
 | 
					gdt_code: dw 0xFFFF, 0     ; bits 0-15 limit (4GB), bits 0-15 base address
 | 
				
			||||||
 | 
					          db 0             ; bits 16-23 base address
 | 
				
			||||||
 | 
					          db 10011010b     ; access byte
 | 
				
			||||||
 | 
					          db 11001111b     ; bits 16-19 limit (4GB), 4 bits flags
 | 
				
			||||||
 | 
					          db 0 ; bits 24-31 base address
 | 
				
			||||||
 | 
					gdt_data: dw 0xFFFF, 0     ; bits 0-15 limit (4GB), bits 0-15 base address
 | 
				
			||||||
 | 
					          db 0             ; bits 16-23 base address
 | 
				
			||||||
 | 
					          db 10010010b     ; access byte
 | 
				
			||||||
 | 
					          db 11001111b     ; bits 16-19 limit (4GB), 4 bits flags
 | 
				
			||||||
 | 
					          db 0 ; bits 24-31 base address
 | 
				
			||||||
 | 
					gdt_end:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string: db 'DISK ERROR'
 | 
				
			||||||
 | 
					string_end:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					addr_packet:
 | 
				
			||||||
 | 
					db 0x10, 0x00 ; size, reserved
 | 
				
			||||||
 | 
					dw secreadcnt ; blocks
 | 
				
			||||||
 | 
					addr_packet_transfer_buff_off: dw 0x7E00 ; transfer buffer offset
 | 
				
			||||||
 | 
					addr_packet_transfer_buff_seg: dw 0x0000 ; transfer buffer segment
 | 
				
			||||||
 | 
					addr_packet_start_block: dq 0 ; start block
 | 
				
			||||||
							
								
								
									
										4
									
								
								helper.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								helper.c
									
									
									
									
									
								
							@@ -48,11 +48,13 @@ void SetCursorDisabled() {
 | 
				
			|||||||
    V8086Int(0x10, ®s);
 | 
					    V8086Int(0x10, ®s);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This should DEFINITELY be an argument
 | 
				
			||||||
 | 
					uint8_t SystemPartition = 0;
 | 
				
			||||||
uint32_t OpenVol(VOLINFO *vi) {
 | 
					uint32_t OpenVol(VOLINFO *vi) {
 | 
				
			||||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
					    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
				
			||||||
    uint8_t pactive, ptype;
 | 
					    uint8_t pactive, ptype;
 | 
				
			||||||
    uint32_t pstart, psize;
 | 
					    uint32_t pstart, psize;
 | 
				
			||||||
    pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
 | 
					    pstart = DFS_GetPtnStart(0, diskReadBuf, SystemPartition, &pactive, &ptype, &psize);
 | 
				
			||||||
    if (pstart == -1) return -1;
 | 
					    if (pstart == -1) return -1;
 | 
				
			||||||
    return DFS_GetVolInfo(0, diskReadBuf, pstart, vi);
 | 
					    return DFS_GetVolInfo(0, diskReadBuf, pstart, vi);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								kernel.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								kernel.c
									
									
									
									
									
								
							@@ -101,6 +101,14 @@ void ensure_v86env() {
 | 
				
			|||||||
        *d++ = *s++;
 | 
					        *d++ = *s++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t _ERRORCODE = 0;
 | 
				
			||||||
 | 
					__attribute__((__no_caller_saved_registers__))
 | 
				
			||||||
 | 
					uint32_t check_error_code() {
 | 
				
			||||||
 | 
					    uint32_t v = _ERRORCODE;
 | 
				
			||||||
 | 
					    _ERRORCODE = 0;
 | 
				
			||||||
 | 
					    return v;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__attribute__((__no_caller_saved_registers__))
 | 
					__attribute__((__no_caller_saved_registers__))
 | 
				
			||||||
__attribute__((__noreturn__))
 | 
					__attribute__((__noreturn__))
 | 
				
			||||||
extern void return_prev_task();
 | 
					extern void return_prev_task();
 | 
				
			||||||
@@ -145,6 +153,7 @@ void error_environment(uint32_t stack0, uint32_t stack1, uint32_t stack2, uint32
 | 
				
			|||||||
    // reset error screen
 | 
					    // reset error screen
 | 
				
			||||||
    for (int i = 0; i < (80*50)/2; i++)
 | 
					    for (int i = 0; i < (80*50)/2; i++)
 | 
				
			||||||
        ((uint32_t*)error_screen)[i] = 0x0f000f00;
 | 
					        ((uint32_t*)error_screen)[i] = 0x0f000f00;
 | 
				
			||||||
 | 
					    _ERRORCODE = -1;
 | 
				
			||||||
    return_prev_task();
 | 
					    return_prev_task();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -181,6 +190,10 @@ Protected Only (1MB+)
 | 
				
			|||||||
400000 - 700000 Usermode Code (3mB)
 | 
					400000 - 700000 Usermode Code (3mB)
 | 
				
			||||||
700000 - 800000 Usermode Stack (1mB)
 | 
					700000 - 800000 Usermode Stack (1mB)
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FIXME Truly awful
 | 
				
			||||||
 | 
					extern uint8_t SystemPartition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DrawScreen(uint16_t *vga) {
 | 
					void DrawScreen(uint16_t *vga) {
 | 
				
			||||||
    uint16_t *vga_text = vga;
 | 
					    uint16_t *vga_text = vga;
 | 
				
			||||||
    // clear screen
 | 
					    // clear screen
 | 
				
			||||||
@@ -214,6 +227,7 @@ void DrawScreen(uint16_t *vga) {
 | 
				
			|||||||
    vga_text[80+42] = 0x1f00 | 'S';
 | 
					    vga_text[80+42] = 0x1f00 | 'S';
 | 
				
			||||||
    vga_text[80+43] = 0x1f00 | ' ';
 | 
					    vga_text[80+43] = 0x1f00 | ' ';
 | 
				
			||||||
    vga_text[80+44] = 0x1f00 | '-';
 | 
					    vga_text[80+44] = 0x1f00 | '-';
 | 
				
			||||||
 | 
					    printByte(SystemPartition, &vga_text[80+50]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SetPalette() {
 | 
					void SetPalette() {
 | 
				
			||||||
@@ -418,7 +432,9 @@ void SystemRun() {
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        VOLINFO vi;
 | 
					        VOLINFO vi;
 | 
				
			||||||
        // TODO Check partitions beyond 0
 | 
					        // TODO Check partitions beyond 0
 | 
				
			||||||
        while (OpenVol(&vi)) {
 | 
					        while (1) {
 | 
				
			||||||
 | 
					            create_child(GetFreeStack(), (uintptr_t)OpenVol, 1, &vi);
 | 
				
			||||||
 | 
					            if (!check_error_code()) break;
 | 
				
			||||||
            vga_text = &((word*)0xb8000)[80*4 + 2];
 | 
					            vga_text = &((word*)0xb8000)[80*4 + 2];
 | 
				
			||||||
            vga_text += printStr("Error loading file select. Ensure the disk has a valid MBR and FAT partition.", vga_text);
 | 
					            vga_text += printStr("Error loading file select. Ensure the disk has a valid MBR and FAT partition.", vga_text);
 | 
				
			||||||
            vga_text = &((word*)0xb8000)[80*5 + 2];
 | 
					            vga_text = &((word*)0xb8000)[80*5 + 2];
 | 
				
			||||||
@@ -457,8 +473,8 @@ void start() {
 | 
				
			|||||||
    vga_text = &vga_text[80];
 | 
					    vga_text = &vga_text[80];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // DL *should* be preserved
 | 
					    // DL *should* be preserved
 | 
				
			||||||
    uint8_t dl;
 | 
					    uint16_t boot_dx;
 | 
				
			||||||
    asm volatile("nop":"=d"(dl));
 | 
					    asm volatile("nop":"=d"(boot_dx));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!check_cmov()) {
 | 
					    if (!check_cmov()) {
 | 
				
			||||||
        char cmov_err[] = "NO CMOV";
 | 
					        char cmov_err[] = "NO CMOV";
 | 
				
			||||||
@@ -467,7 +483,7 @@ void start() {
 | 
				
			|||||||
        for (;;) asm volatile("hlt");
 | 
					        for (;;) asm volatile("hlt");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vga_text += printByte(dl, vga_text);
 | 
					    vga_text += printWord(boot_dx, vga_text);
 | 
				
			||||||
    vga_text++;
 | 
					    vga_text++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint32_t o;
 | 
					    uint32_t o;
 | 
				
			||||||
@@ -509,6 +525,9 @@ void start() {
 | 
				
			|||||||
    backup_ivtbios();
 | 
					    backup_ivtbios();
 | 
				
			||||||
    InitDisk();
 | 
					    InitDisk();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // DL contained disk number, DH contained active partition
 | 
				
			||||||
 | 
					    SystemPartition = boot_dx >> 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    create_child(GetFreeStack(), (uintptr_t)SystemRun, 0);
 | 
					    create_child(GetFreeStack(), (uintptr_t)SystemRun, 0);
 | 
				
			||||||
    // If this returns, something is *very* wrong, reboot the system
 | 
					    // If this returns, something is *very* wrong, reboot the system
 | 
				
			||||||
    // TODO Maybe try to recover?
 | 
					    // TODO Maybe try to recover?
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										6
									
								
								tests.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tests.c
									
									
									
									
									
								
							@@ -122,6 +122,10 @@ void TestCHS() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FIXME Just horrible
 | 
				
			||||||
 | 
					extern uint8_t SystemPartition;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TestFAT() {
 | 
					void TestFAT() {
 | 
				
			||||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
					    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
    uint8_t *diskReadBuf = (uint8_t *)0x22400;
 | 
					    uint8_t *diskReadBuf = (uint8_t *)0x22400;
 | 
				
			||||||
@@ -131,7 +135,7 @@ void TestFAT() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    uint8_t pactive, ptype;
 | 
					    uint8_t pactive, ptype;
 | 
				
			||||||
    uint32_t pstart, psize;
 | 
					    uint32_t pstart, psize;
 | 
				
			||||||
    pstart = DFS_GetPtnStart(0, diskReadBuf, 0, &pactive, &ptype, &psize);
 | 
					    pstart = DFS_GetPtnStart(0, diskReadBuf, SystemPartition, &pactive, &ptype, &psize);
 | 
				
			||||||
    vga_text = (uint16_t *)0xb8000;
 | 
					    vga_text = (uint16_t *)0xb8000;
 | 
				
			||||||
    vga_text += printStr("PartStart: ", vga_text);
 | 
					    vga_text += printStr("PartStart: ", vga_text);
 | 
				
			||||||
    vga_text += printDword(pstart, vga_text);
 | 
					    vga_text += printDword(pstart, vga_text);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								virtdisk.bin.ex
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								virtdisk.bin.ex
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user