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),)
 | 
			
		||||
OUTFILE = virtdisk.bin
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
all: $(OUTFILE)
 | 
			
		||||
 | 
			
		||||
$(OUTFILE): boot.bin kernel.bin
 | 
			
		||||
	# Copy to boot sector, don't overwrite MBR
 | 
			
		||||
$(OUTFILE): boot.bin boot_partition.bin kernel.bin
 | 
			
		||||
	# Copy system bootloader to boot sector, don't overwrite MBR
 | 
			
		||||
	dd bs=400 count=1 conv=notrunc if=boot.bin of=$@
 | 
			
		||||
	# Write kernel beyond boot sector, maximum 128K (256 sectors)
 | 
			
		||||
	dd bs=512 count=256 seek=1 conv=notrunc if=kernel.bin of=$@
 | 
			
		||||
	# Ensure partition VBR contains EB 5A
 | 
			
		||||
	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
 | 
			
		||||
	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 $@ $<
 | 
			
		||||
 | 
			
		||||
virtdisk:
 | 
			
		||||
	dd bs=1M count=32 if=/dev/zero of=virtdisk.bin
 | 
			
		||||
	echo -n -e '\x55\xaa' | dd bs=1 seek=510 conv=notrunc of=virtdisk.bin
 | 
			
		||||
	cp virtdisk.bin.ex virtdisk.bin
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f $(objects) out.o kernel.bin boot.bin usermode.bin
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										219
									
								
								boot.nasm
									
									
									
									
									
								
							
							
						
						
									
										219
									
								
								boot.nasm
									
									
									
									
									
								
							@@ -1,6 +1,8 @@
 | 
			
		||||
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]
 | 
			
		||||
; This boots the active partition.
 | 
			
		||||
; Relocates self to 0x7E00, loads the 
 | 
			
		||||
; first sector of active partition
 | 
			
		||||
; to 0x7C00 and jumps
 | 
			
		||||
[ORG 0x7C00]
 | 
			
		||||
[BITS 16]
 | 
			
		||||
xor ax, ax
 | 
			
		||||
mov ds, ax
 | 
			
		||||
@@ -8,68 +10,50 @@ mov es, ax
 | 
			
		||||
mov ax, 0x8000
 | 
			
		||||
mov ss, ax
 | 
			
		||||
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 bx, 0x55AA
 | 
			
		||||
int 0x13
 | 
			
		||||
jc no_exten
 | 
			
		||||
mov cx, kernelreads
 | 
			
		||||
read_loop:
 | 
			
		||||
jc no_int13
 | 
			
		||||
; Find active partition
 | 
			
		||||
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
 | 
			
		||||
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:
 | 
			
		||||
;mov ax,0x2403 ; A20 BIOS Support
 | 
			
		||||
;int 0x15
 | 
			
		||||
;jb .no_a20
 | 
			
		||||
;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
 | 
			
		||||
; Jump to partition boot
 | 
			
		||||
jmp 0:0x7C00
 | 
			
		||||
 | 
			
		||||
no_int13:
 | 
			
		||||
mov si, no_exten_str
 | 
			
		||||
mov cx, no_exten_str_end - no_exten_str
 | 
			
		||||
jmp print
 | 
			
		||||
err:
 | 
			
		||||
mov bx, ax
 | 
			
		||||
mov si, string
 | 
			
		||||
@@ -83,126 +67,17 @@ err_print:
 | 
			
		||||
lodsb
 | 
			
		||||
stosw
 | 
			
		||||
loop err_print
 | 
			
		||||
;add di, 2
 | 
			
		||||
;mov ax, bx
 | 
			
		||||
;call hexprint
 | 
			
		||||
hlt_loop:
 | 
			
		||||
hlt
 | 
			
		||||
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_end:
 | 
			
		||||
;no_exten_str: db 'NO INT13 EXTEN'
 | 
			
		||||
;no_exten_str_end:
 | 
			
		||||
no_exten_str: db 'NO INT13 EXTEN'
 | 
			
		||||
no_exten_str_end:
 | 
			
		||||
 | 
			
		||||
addr_packet:
 | 
			
		||||
db 0x10, 0x00 ; size, reserved
 | 
			
		||||
dw secreadcnt ; blocks
 | 
			
		||||
addr_packet_transfer_buff_off: dw 0x0000 ; transfer buffer offset
 | 
			
		||||
addr_packet_transfer_buff_seg: dw 0x2000 ; transfer buffer segment
 | 
			
		||||
addr_packet_start_block: dq 1 ; start block
 | 
			
		||||
dw 1 ; blocks
 | 
			
		||||
addr_packet_transfer_buff_off: dw 0x7C00 ; transfer buffer offset
 | 
			
		||||
addr_packet_transfer_buff_seg: dw 0x0000 ; transfer buffer segment
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This should DEFINITELY be an argument
 | 
			
		||||
uint8_t SystemPartition = 0;
 | 
			
		||||
uint32_t OpenVol(VOLINFO *vi) {
 | 
			
		||||
    uint8_t *diskReadBuf = (uint8_t *)0x20000;
 | 
			
		||||
    uint8_t pactive, ptype;
 | 
			
		||||
    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;
 | 
			
		||||
    return DFS_GetVolInfo(0, diskReadBuf, pstart, vi);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								kernel.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								kernel.c
									
									
									
									
									
								
							@@ -101,6 +101,14 @@ void ensure_v86env() {
 | 
			
		||||
        *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__((__noreturn__))
 | 
			
		||||
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
 | 
			
		||||
    for (int i = 0; i < (80*50)/2; i++)
 | 
			
		||||
        ((uint32_t*)error_screen)[i] = 0x0f000f00;
 | 
			
		||||
    _ERRORCODE = -1;
 | 
			
		||||
    return_prev_task();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -181,6 +190,10 @@ Protected Only (1MB+)
 | 
			
		||||
400000 - 700000 Usermode Code (3mB)
 | 
			
		||||
700000 - 800000 Usermode Stack (1mB)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// FIXME Truly awful
 | 
			
		||||
extern uint8_t SystemPartition;
 | 
			
		||||
 | 
			
		||||
void DrawScreen(uint16_t *vga) {
 | 
			
		||||
    uint16_t *vga_text = vga;
 | 
			
		||||
    // clear screen
 | 
			
		||||
@@ -214,6 +227,7 @@ void DrawScreen(uint16_t *vga) {
 | 
			
		||||
    vga_text[80+42] = 0x1f00 | 'S';
 | 
			
		||||
    vga_text[80+43] = 0x1f00 | ' ';
 | 
			
		||||
    vga_text[80+44] = 0x1f00 | '-';
 | 
			
		||||
    printByte(SystemPartition, &vga_text[80+50]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SetPalette() {
 | 
			
		||||
@@ -418,7 +432,9 @@ void SystemRun() {
 | 
			
		||||
    {
 | 
			
		||||
        VOLINFO vi;
 | 
			
		||||
        // 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 += printStr("Error loading file select. Ensure the disk has a valid MBR and FAT partition.", vga_text);
 | 
			
		||||
            vga_text = &((word*)0xb8000)[80*5 + 2];
 | 
			
		||||
@@ -457,8 +473,8 @@ void start() {
 | 
			
		||||
    vga_text = &vga_text[80];
 | 
			
		||||
 | 
			
		||||
    // DL *should* be preserved
 | 
			
		||||
    uint8_t dl;
 | 
			
		||||
    asm volatile("nop":"=d"(dl));
 | 
			
		||||
    uint16_t boot_dx;
 | 
			
		||||
    asm volatile("nop":"=d"(boot_dx));
 | 
			
		||||
 | 
			
		||||
    if (!check_cmov()) {
 | 
			
		||||
        char cmov_err[] = "NO CMOV";
 | 
			
		||||
@@ -467,7 +483,7 @@ void start() {
 | 
			
		||||
        for (;;) asm volatile("hlt");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vga_text += printByte(dl, vga_text);
 | 
			
		||||
    vga_text += printWord(boot_dx, vga_text);
 | 
			
		||||
    vga_text++;
 | 
			
		||||
 | 
			
		||||
    uint32_t o;
 | 
			
		||||
@@ -509,6 +525,9 @@ void start() {
 | 
			
		||||
    backup_ivtbios();
 | 
			
		||||
    InitDisk();
 | 
			
		||||
 | 
			
		||||
    // DL contained disk number, DH contained active partition
 | 
			
		||||
    SystemPartition = boot_dx >> 8;
 | 
			
		||||
 | 
			
		||||
    create_child(GetFreeStack(), (uintptr_t)SystemRun, 0);
 | 
			
		||||
    // If this returns, something is *very* wrong, reboot the system
 | 
			
		||||
    // 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() {
 | 
			
		||||
    uint16_t *vga_text = (uint16_t *)0xb8000;
 | 
			
		||||
    uint8_t *diskReadBuf = (uint8_t *)0x22400;
 | 
			
		||||
@@ -131,7 +135,7 @@ void TestFAT() {
 | 
			
		||||
 | 
			
		||||
    uint8_t pactive, ptype;
 | 
			
		||||
    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 += printStr("PartStart: ", 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