Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

Testovací zaváděcí sektor

Testovací zaváděcí sektor je prvním nejjednodušším pokusem při zavádění systému. Slouží k vyzkoušení základních principů zavedení sektoru do paměti, jeho spuštění a také způsobu jak takový sektor uložit na disketu.

Vytvořte soubor BOOT.ASM, který bude obsahovat zdrojový kód zaváděcího sektoru. Po vytvoření kódu provedete překlad příkazem "NASM16.EXE -o BOOT.BIN BOOT.ASM".

; ----------------------------------------------------------------------------
;      Start of the boot sector (starting at 0000:7C00)
; ----------------------------------------------------------------------------

SECTION		.text

		org	7C00h		; booting address of boot sector

Start:		jmp	Init		; jump to starting routine

Message		db	"My system loaded OK!",13,10
		db	"Press any key...",13,10,0

; ------------- Init stack (lies below beginning of the boot sector)
	
Init:		cli			; disable interrupts
		xor	ax,ax		; AX <- 0
		mov	ds,ax		; DS <- 0 this segment
		mov	ss,ax		; SS <- 0
		mov	sp,7C00h	; SP <- end of stack
		sti			; enable interrupts

; ------------- Display information message

		mov	si,Message	; information message
NextChar:	cld			; set direction up
		lodsb			; AL <- load next character from DS:SI
		or	al,al		; AL == 0? (is it end of text?)
		jz	KeyPress	; end of text
		mov	ah,0eh		; AH <- function code		
		mov	bx,7		; BL <- color of text, BH <- page 0
		int	10h		; print character
		jmp	short NextChar	; next character

; ------------- Waiting for a key

KeyPress:	mov	ah,0		; AH <- function code
		int	16h		; waiting for a key

; ------------- Continue booting with next device

		int	19h		; continue booting

; ------------- Align to sector size

times 512 - 2 - ($ - Start) db	0

		dw	0aa55h		; Boot sector magic

Zaváděcí sektor je do paměti zaveden od adresy 0000:7C00h (tj. segment 0, offset 7C00h), na tuto adresu BIOS předá řízení. Podmínkou platnosti zaváděcího sektoru je, že musí končit magickým slovem 0AA55h, jinak ho BIOS ignoruje a pokračuje v zavádění systému z dalšího zařízení. Další podmínkou, kterou mnoho BIOSů (a také MBR sektorů) testuje, je instrukce JMP na začátku zaváděcího sektoru - buď se musí jednat o instrukci JMP NEAR (3 bajty) nebo instrukci JMP SHORT (2 bajty) následovanou instrukcí NOP (1 bajt).

Prvním úkonem, který by měl zaváděcí sektor vždy provést, je nastavení ukazatele zásobníku. Přestože instrukce "mov ss,ax" zajistí přechodný zákaz přerušení pro následující instrukci "mov sp,7C00h" je obvyklé zakázat přerušení během operace ještě explicitně.

Druhou operací, kterou testovací zaváděcí sektor provádí, je výpis informačního textu. Text se načítá po znacích z ukazatele DS:SI (až po koncový bajt 0) a zobrazuje se na displeji pomocí BIOS služby INT 10h. Po zobrazení informačního textu čeká zavaděč na stisk klávesy a poté pokračuje opakováním zavádění systému pomocí přerušení INT 19h. Není-li disketa vyjmuta, znovu dojde k zavedení tohoto sektoru, jinak BIOS pokračuje dalšími diskovými jednotkami.

Zaváděcí sektor je zakončen makrem, které zajistí vyplnění zbytku sektoru až do 510 bajtů. Za vyplňovacím prostorem je magické slovo 0AA55h, které BIOS kontroluje po načtení zaváděcího sektoru do paměti.

Po překladu zaváděcího sektoru vznikne soubor BOOT.BIN, který musí být velký 512 bajtů. Tento soubor je nyní potřeba zapsat do prvního sektoru diskety v mechanice A:. Musí být použita zformátovaná disketa, na její velikosti ani souborovém systému nezáleží. K zápisu sektoru na disketu vytvořte zdrojový soubor INSTALL.ASM, který přeložíte příkazem "NASM16.EXE -o INSTALL.COM INSTALL.ASM".

SECTION		.text

		org	100h		; start of COM program

; ------------- Prepare address of disk buffer (cannot overlap 64 KB boundary)

Start:		mov	ax,ds		; AX <- program segment
		shl	ax,1
		shl	ax,1
		shl	ax,1
		shl	ax,1		; AX / 16
		add	ax,[Sector]	; add current buffer offset
		add	ax,200h		; test buffer overlapping
		jnc	BufferOK	; buffer is OK
		mov	ax,[Sector]	; AX <- current buffer address
		add	ax,200h		; move over boundary
		mov	[Sector],ax	; new buffer address

; ------------- Open file with boot sector

BufferOK:	mov	ax,3d00h	; AX <- function code (open for reading)
		mov	dx,Filename	; DX <- name of file with boot sector
		int	21h		; open file for reading
		jnc	OpenOK		; file open OK

; ------------- Error - file not found

		mov	ah,9		; AH <- function code
		mov	dx,FoundErr	; DX <- error message
		int	21h		; display error message
		int	20h		; end of program

; ------------- Read file into memory (AX=file identifier)

OpenOK: 	mov	bx,ax		; BX <- file identifier
		mov	cx,512		; CX <- length of boot sector
		mov	dx,[Sector]	; DX <- buffer for reading sector
		mov	ah,3fh		; AH <- function code
		int	21h		; read sector into memory

; ------------- Close file

		mov	ah,3eh		; AH <- function code
		int	21h		; close file

; ------------- Displays prompt text for user

		mov	ah,9		; AH <- function code
		mov	dx,Message	; DX <- message to display
		int	21h		; display message

; ------------- Waiting for a key

		mov	ax,0c08h	; AX <- function code
		int	21h		; waiting for a key
		cmp	al,27		; is it Esc key?
		jne	InitDisk	; it is not Esc, start write
		int	20h		; end of program

; ------------- Display message - Writing sector

InitDisk:	mov	ah,9		; AH <- function code
		mov	dx,StartText	; DX <- text to display
		int	21h		; display message

; ------------- Write boot sector

		mov	si,3		; number of attempts
WriteAgain:	push	si	        ; push attempt counter
		mov	ax,301h		; AH <- function, AL <- num. of sectors
		mov	cx,1		; CH <- cylinder, CL <- sector
		xor	dx,dx		; DH <- 0 head, DL <- 0 disk A:
		mov	bx,[Sector]	; BX <- buffer with sector
		push	ds		; push DS to stack
		pop	es		; ES <- DS
		int	13h		; write BOOT sector
		pop	si		; pop attempt counter
		jnc	WriteOK		; operation OK

; ------------- Reset of disk (e.g. disk change report)

		mov	ah,0		; AH <- function code
		int	13h		; reset disk system
		dec	si		; attempt counter
		jnz	WriteAgain	; next attempt

; ------------- Error - cannot write to a floppy

		mov	ah,9		; AH <- function code
		mov	dx,WriteErr	; DX <- error message
		int	21h		; display error message

WriteOK:	int	20h		; end of program

; ------------- Messages

FoundErr	db	"ERROR: File BOOT.BIN not found!",13,10,"$"

WriteErr	db	"ERROR: Cannot write to disk!",13,10,"$"

Message		db	"Insert disk into A: and press any",13,10
		db	"key to continue or Esc to abort...",13,10,"$"

StartText	db	"Writing sector...",13,10,"$"

; ------------- File with boot sector

Filename	db	"BOOT.BIN",0

; ------------- Buffer of boot sector

Sector		dw	Buffer
Buffer:

Program INSTALL.COM je určený pro operační systém DOS nebo Windows. Sektor je na disketu zapisován BIOS funkcí INT 13h. Z důvodu architektury řadiče DMA je nutné, aby sektor neležel na hranici 64 KB absolutní adresy paměti. Z toho důvodu je na začátku programu korigována adresa bufferu, do kterého bude zaváděcí sektor načten - pokud absolutní adresa přetéká přes 64 KB, použije se následující adresa.

Další část programu zajistí otevření souboru BOOT.BIN pro čtení, jeho načtení do bufferu a poté uzavření souboru. Následuje zobrazení výzvy uživateli a čekání na klávesu - při stusku klávesy Esc je program přerušen, jinak pokračuje zápisem sektoru na disketu. Při zápisu sektoru je použita BIOS funkce INT 13h. Pokud operace zápisu neproběhne úspěšně, provede se reset disku a zápis se opakuje, to celkem 3x než se ohlásí chyba. Důvodem k opakování zápisu může být nejen vadný disk (příp. aktivovaná ochrana proti zápisu na disketu), ale i výměna diskety (návratový kód 6) - v tom případě je resetem diskety příznak výměny nulován a následující zápis proběhne již úspěšně.

Download zdrojových textů testovacího zaváděcího sektoru.

Zpět na zavaděče systému