Skip to content

Commit

Permalink
KERNEL.SYS: detect boot partition by partition offset
Browse files Browse the repository at this point in the history
  • Loading branch information
boeckmann committed Jul 31, 2024
1 parent a1a43a4 commit 64186cf
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 123 deletions.
231 changes: 121 additions & 110 deletions drbio/bdosldr.asm
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
; ENDLOG


if SINGLEFILE eq 0

include request.equ
include driver.equ
include config.equ
Expand All @@ -60,71 +58,150 @@ ASSUME CS:CGROUP,DS:CGROUP

VER_MUSTBE equ 1072h

Public dos_version_check

Public detect_boot_drv
if SINGLEFILE eq 0
Public dos_version_check
Public read_dos ; read BDOS from disk
endif

;--------
read_dos: ; read in the BDOS
;--------
call login_drive ; build BPB for the boot drive
mov si,offset dos_name ; get name of file to open
call open_file ; open the BDOS file
call read_file ; read in the system file
ret

login_drive:
;-----------
; Tries to detect to logical boot drive by the given phys boot drv
; and a partition offset
detect_boot_drv proc
les di,boot_device ; get device driver address
mov dl,boot_drv ; get the boot drive sub unit
xor dh,dh
dec dh
dec dh ; dh=255
mov ax,es
or ax,di ; make sure boot device is initialised
jnz login_drive10
jmp dev_fail
login_drive10:
jnz @@get_device_procs
if SINGLEFILE eq 0
jmp dev_fail ; panic, cannot determine boot drv
else
ret ; single-file kernel, user may resolve
endif
@@get_device_procs:
mov ax,es:6[di] ; get strategy offset
mov strat_off,ax
mov strat_seg,es ; get strategy segment
mov ax,es:8[di] ; get interrupt offset
mov intrpt_off,ax
mov intrpt_seg,es ; get interrupt segment

login_drive12:
@@test_drv:
mov bx,offset req_hdr
mov [bx+RH_UNIT],dl ; save logical unit to use
mov [bx+RH_CMD],CMD_BUILD_BPB
call device_request ; tell it to build a BPB
; jc dev_fail ; return if can't determine BPB
jnc login_drive15
jmp login_drive17 ; return if can't determine BPB
login_drive15:
jnc @@bpb_ok ; BPB successfully built
jmp @@next_drv ; if not, try next drive
@@bpb_ok:
cmp dl,boot_drv
jne login_drive16
mov dh,dl
login_drive16:
jne @@compare_part_off
mov dh,dl ; dh=boot_drv
@@compare_part_off:
les di,[bx+RH2_BPB]
mov ax,part_off
cmp es:word ptr BPB_HIDDEN[di],ax
jne login_drive17
jne @@next_drv
mov ax,part_off+2
cmp es:word ptr BPB_HIDDEN+2[di],ax
jne login_drive17
jne @@next_drv
mov dh,dl
jmp login_drive18
login_drive17:
inc dl
jz login_drive18
jmp login_drive12
login_drive18:
jmp @@done
@@next_drv:
inc dl ; increase log drv num
jz @@done
jmp @@test_drv
@@done:
cmp dh,255
jne login_drive19
jne @@store_boot_drv ; boot drv found?
jmp dev_fail
login_drive19:
@@store_boot_drv:
mov dl,dh
mov boot_drv,dl
mov init_drv,dl
ret
detect_boot_drv endp


dev_fail: ; any error has occurred loading the BDOS
;--------
; Print '$' terminated message at offset DX to console without using the BDOS
;
mov dx,offset dos_msg
les di,resdev_chain ; get first device driver address
fail_scan:
test es:[di+DEVHDR.ATTRIB],DA_CHARDEV
jz fail_next ; skip if not a character device
test es:[di+DEVHDR.ATTRIB],DA_ISCOT
jnz fail_found ; skip if console device found
fail_next:
les di,es:[di] ; get next device
jmp fail_scan
fail_found:
mov ax,es:6[di] ; get strategy offset
mov strat_off,ax
mov strat_seg,es ; get strategy segment
mov ax,es:8[di] ; get interrupt offset
mov intrpt_off,ax
mov intrpt_seg,es ; get interrupt segment

mov bx,offset req_hdr
mov [bx+RH_CMD],CMD_OUTPUT ; write to console
mov [bx+RH_LEN],RH4_LEN ; set request header length
mov [bx+RH4_BUFOFF],dx ; set address of string
mov [bx+RH4_BUFSEG],ds
mov [bx+RH4_COUNT],-1
mov si,dx ; now find the end of the string
fail_count_chars:
inc [bx+RH4_COUNT] ; print another char
lodsb ; examine the next one
cmp al,'$' ; terminating char ?
jnz fail_count_chars
call device_request ; call the console driver

sti
wait_forever:
jmp wait_forever ; wait for reboot


device_request: ; general device driver interface
;--------------
; entry: BX -> request header
; exit: CY = 1 if error

push ds
push es
push ds
pop es
mov ds,strat_seg
call dword ptr cs:strat_ptr
call dword ptr cs:intrpt_ptr
pop es
pop ds
test [bx+RH_STATUS],RHS_ERROR
jnz devreq_err
clc
ret
devreq_err:
stc
; jmp dev_fail ; print error message
ret

if SINGLEFILE eq 0
;--------
read_dos: ; read in the BDOS
;--------
call login_drive ; build BPB for the boot drive
mov si,offset dos_name ; get name of file to open
call open_file ; open the BDOS file
call read_file ; read in the system file
ret

login_drive:
;-----------
les di,boot_device ; get device driver address
mov dl,boot_drv ; get the boot drive sub unit
mov bx,offset req_hdr
mov [bx+RH_UNIT],dl ; save logical unit to use
mov [bx+RH_CMD],CMD_BUILD_BPB
Expand Down Expand Up @@ -210,71 +287,6 @@ dos_version_check:
jne dev_fail ; reject all but the one we want
ret ; return now I'm happy

dev_fail: ; any error has occurred loading the BDOS
;--------
; Print '$' terminated message at offset DX to console without using the BDOS
;
mov dx,offset dos_msg
les di,resdev_chain ; get first device driver address
fail_scan:
test es:[di+DEVHDR.ATTRIB],DA_CHARDEV
jz fail_next ; skip if not a character device
test es:[di+DEVHDR.ATTRIB],DA_ISCOT
jnz fail_found ; skip if console device found
fail_next:
les di,es:[di] ; get next device
jmp fail_scan
fail_found:
mov ax,es:6[di] ; get strategy offset
mov strat_off,ax
mov strat_seg,es ; get strategy segment
mov ax,es:8[di] ; get interrupt offset
mov intrpt_off,ax
mov intrpt_seg,es ; get interrupt segment

mov bx,offset req_hdr
mov [bx+RH_CMD],CMD_OUTPUT ; write to console
mov [bx+RH_LEN],RH4_LEN ; set request header length
mov [bx+RH4_BUFOFF],dx ; set address of string
mov [bx+RH4_BUFSEG],ds
mov [bx+RH4_COUNT],-1
mov si,dx ; now find the end of the string
fail_count_chars:
inc [bx+RH4_COUNT] ; print another char
lodsb ; examine the next one
cmp al,'$' ; terminating char ?
jnz fail_count_chars
call device_request ; call the console driver

sti
wait_forever:
jmp wait_forever ; wait for reboot


device_request: ; general device driver interface
;--------------
; entry: BX -> request header
; exit: CY = 1 if error

push ds
push es
push ds
pop es
mov ds,strat_seg
call dword ptr cs:strat_ptr
call dword ptr cs:intrpt_ptr
pop es
pop ds
test [bx+RH_STATUS],RHS_ERROR
jnz devreq_err
clc
ret
devreq_err:
stc
; jmp dev_fail ; print error message


ret
open_file: ; open BDOS system file
;---------
Expand Down Expand Up @@ -825,6 +837,9 @@ div32_2:
mov [bp],ax ; save remainder onto stack
mov 2[bp],dx
ret

endif ; SINGLEFILE=0

INITCODE ends


Expand All @@ -850,6 +865,8 @@ intrpt_ptr label dword
intrpt_off dw ?
intrpt_seg dw ?

if SINGLEFILE eq 0

dta_ptr label dword
dta_off dw ?
dta_seg dw ?
Expand All @@ -862,13 +879,9 @@ current_fatsec dw -1,-1 ; no FAT sector read yet
fattype dw 0 ; defaults to 12 bit FAT
nfatsecs dw 0,0 ; number of FAT sectors (32-bit)

; single error message if BDOS can't be loaded:


include initmsgs.def ; Include TFT Header File
endif


;dos_msg db CR,LF,'Can''t load DOS file.$'
include initmsgs.def ; for dos_msg error msg


; static request header for DOS device driver I/O
Expand Down Expand Up @@ -923,6 +936,4 @@ BPB_HIDDEN equ 17
extrn sector_buffer:byte
INITDATA ends

endif ; SINGLEFILE

end
5 changes: 5 additions & 0 deletions drbio/biosinit.asm
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ INITCODE segment public byte 'INITCODE'
extrn config:near ; CONFIG.SYS Processor
extrn crlf:near ; Output CR/LF to screen
extrn resident_device_init:near ; Device Driver Init
extrn detect_boot_drv:near
if SINGLEFILE eq 0
extrn read_dos:near ; load DOS file
extrn dos_version_check:near
Expand Down Expand Up @@ -329,6 +330,10 @@ relocated_init:
mov ax,0100h ; the multi tasker (386 or above)
dont_align:
mov free_seg,ax ; and save as first Free Segment
test init_flags,INIT_ROMCODE ; ROM boot: no boot drv detection
jnz skip_boot_drv_detection
call detect_boot_drv
skip_boot_drv_detection:
if SINGLEFILE eq 0
cmp current_dos,0 ; does the OEM want us to read
jnz dos_reloc ; the DOS file from disk?
Expand Down
24 changes: 11 additions & 13 deletions drbio/init.asm
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ local_buffer label byte
pop di
pop cx

push ax ; bdos_seg if loaded from ROM
push ax ; ROM boot: BDOS seg
mov ax, cs ; preserve entry registers
mov ds, ax ; other than si, ds and es
xor si, si
Expand All @@ -666,7 +666,7 @@ local_buffer label byte
; standardize to DL holding drive unit
cmp ax,60h ; are we loaded at segment 60h?
jne uncompress_and_relocate_kernel
mov dl,bl ; then copy unit fron BL to DL
mov dl,bl ; copy phys boot drive fron BL to DL

uncompress_and_relocate_kernel:
if COMPRESSED eq 0
Expand All @@ -679,10 +679,10 @@ if COMPRESSED eq 0
jmp not_compressed
@@:
endif
push di ; bios_seg
push bx ; initial drives
push cx ; memory size
push dx ; initial flags
push di ; ROM boot: DL=0ffh, Disk boot: DL=phys boot drv
push bx ; ROM boot: memory size, Disk boot: unused
push cx ; ROM boot: initial drives, Disk boot: unused
push dx ; ROM boot: BIO seg, Disk boot: unused

mov ax,TEMP_RELOC_SEG
mov es,ax
Expand Down Expand Up @@ -760,15 +760,13 @@ if COMPRESSED eq 1
jmp @@uncompress_block
@@uncompress_fini:
endif
push cs
pop ds ; ds = BIO segment
pop dx
pop cx
pop bx
pop di
pop dx ; ROM boot: DL=0ffh, Disk boot: DL=phys boot drv
pop cx ; ROM boot: memory size, Disk boot: unused
pop bx ; ROM boot: initial drives, Disk boot: unused
pop di ; ROM boot: BIO seg, Disk boot: unused
not_compressed:

pop ax
pop ax ; ROM boot: BDOS seg
jmp init1 ; next initialization stage is
; part of discardable ICODE segment
init0 endp
Expand Down

0 comments on commit 64186cf

Please sign in to comment.