Skip to content

Bootloader

Oliver Po edited this page Jan 27, 2025 · 2 revisions

Stage 0

Extended Read Sectors From Drive

When we want to load sectors to be able to execute/read the data stored in the image, we need to specify how the number of sectors to read. First we need to specify the destination by setting dap_dest (dword) after which we specify the sectors to read, and finally, the start of the sectors to read by using logical block addressing.

The example can be seen down below.

Example

	; BIOS give us the booting drive index in dl
	; dap_dest = buffer address (where the data will be copied to)
	; dap_sectors = how many sectors to read
	; dap_lba = the first sector you want to read and write
	mov	dword	[dap_dest], 0x7e00
	mov	word	[dap_sectors], 1
	mov	dword	[dap_lba], 0x1
	call	disk_load_lba

What is logical block addressing?

Logical block addressing (LBA) is used to specify blocks of data in storage devices. It uses a linear addressing scheme, meaning blocks can be found using a integer index. Below, this is how LBA would be translated into Cylinder-head-sector (CHS) addresses.

image

disk_load_lba function

The parameters for Extended Read Sectors From Drive are stored in the Disk Address Packet (DAP) data structure (seen below).

dap:
	; size of DAP
	db	0x10
	; unused
	db	0
dap_sectors:
	; sectors to read. some BIOSes are limited to a single signed byte (127)
	dw	0
dap_dest:
	; destination address
	dd	0
dap_lba:
	; little-endian start of LBA address to read. 0-indexed
	dd	0
	dd	0

Here, the function will attempt to call the bios service. If unsuccessful, the carry bit will be set thereby causing it to print an error (.disk_lba_err).

NOTE: dl is commented out as its assumed it will never change (dl is initialised to 0 on boot).

; dl = drive index
; si = address of disk address packet
; automatically loads to drive 0
disk_load_lba:
	pusha

	mov	ah, 0x42
	; mov	dl, dl
	mov	si, dap
	int	0x13
	; carry bit set if err
	jc	.disk_lba_err

	popa
	ret

Clone this wiki locally