bootloader bug

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Milo
Posts: 16
Joined: Sat May 26, 2007 7:12 am

bootloader bug

Post by Milo »

Hi everyone. There got something wrong with my bootloader. It reads the floppy disk repeatly and does not intend to stop when it runs. I wrote it in nasm syntax, and the code is similar to linux 1.0 bootloader. The code is as follows:

Code: Select all

	SETUP_SECTS		equ 4						; default nr of setup-sectors
	KERNEL_SECTS 	equ 128					; default nr of kernel-sectors
	SETUP_SEG			equ 9000h				; setup start segment
	SYS_SEG				equ 1000h				; system begins with this segment 
	END_SEG				equ 2000h				; end of system segment
	
	org	07c00h
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	mov	ss, ax
	mov	ax, 7c00h
	mov	sp, ax
	call	print_sth
	call	load_setup
	call	load_kernel
	jmp	$
;	call	kill_motor
	jmp 	SETUP_SEG:0				; SETUP_SEG = 0x9000

print_sth:
; print 'welcome to sparrow world!'
	mov	ax, msg_welm
	mov	bp, ax			; ES:BP = base of string
	mov	cx, 25			; CX = length
	mov	ax, 01301h		; AH = 13,  AL = 01h
	mov	bx, 000ch		; page 0(BH = 0) red word with black background (BL = 0Ch,high light)
	mov	dl, 25			; line
	int	10h
	
; int 10h: ah=3(read cursor pos), ah=A(print char in cursor pos), ah=13h(print string)

; read current cursor position
	mov	ah, 03h			; read cursor pos
	xor	bh, bh			; bh = page no.
	int	10h				; return values in ch/cl, dh/dl

; print 'loading'
	mov	cx, 9				; length of string
	mov	bx, 0007h		; page 0, attribute 7 (normal)
	mov	bp, msg_ld
	mov	ax, 1301h		; write string, cursor follows(al=1)
	int	10h
	ret

; INT 13h AH=02h: Read Sectors From Drive
; AH 02h 
; DH Head 
; DL Drive 
; ES:BX Buffer Address Pointer 
load_setup:
	mov 	ah, 02h	
	mov	al, SETUP_SECTS		; AL Sectors To Read Count 
	mov 	cx, 0002h					; CX Track + Sector
	mov 	dx, 0000h
	mov 	bx, SETUP_SEG
	mov 	es, bx
	sub	bx, bx
	int 	13h
	ret
	
load_kernel:

; There are actually four types of floppy disks classified by
; their capability, including 360KB, 720KB, 1.2MB, 1.44MB and 2.88MB.
; In the other way, they are classified into four types according to number of 
; sectors per track, which are listed as follows:
; 2.88MB disks:	Sectors/Track = 36
; 1.44MB disks:	Sectors/Track = 18
; 1.2MB 	disks:	Sectors/Track = 15
; 720KB/360KB 	disks:	Sectors/Track = 9

check_sectors:
	xor	dx, dx					; drive 0, head 0
	mov	cx, 24h					; sector 36, track 0
	mov	bx, 7c00h + 200h 	; address after boot (es = cs)
	mov	ax, 0201h				; service 2, 1 sector
	int	13h
	jnc	got_sectors
	mov	cl, 12h					; sector 18
	mov	ax, 0201h				; service 2, 1 sector
	int	13h
	jnc	got_sectors
	mov	cl, 0fh					; sector 15
	mov	ax, 0201h				; service 2, 1 sector
	int	13h
	jnc	got_sectors
	mov	cl, 09h
got_sectors:
	mov	[sects_per_trk], cl

start_read2:
	mov	ax, SYS_SEG
	mov 	es, ax
	sub	bx, bx
rp_read:
	mov	ax, [sects_per_trk]
	sub	ax, [sects]
	mov	cx, ax
	shl	cx, 9
	add	cx, bx
	jnc	read_remin
	je		read_remin
	xor	ax, ax
	sub	ax, bx
	shr	ax, 9
read_remin:
	mov	dx, [track]
	mov	cx, [sects]
	inc 	cx
	mov	ch, dl
	mov	dx, [head]
	mov	dh, dl
	mov	dl, 0
	and	dx, 0100h
	mov	ah, 2
	pushad
	mov	ah, 0eh
	mov	al, 2eh
	mov	bx, 7
	int 	10h
	popad
	int 	13h
	mov	cl, al
	mov	ah, 0
	add	ax, [sects]
	cmp	ax, [sects_per_trk]
	jne	adjust_seg
	mov	dx, 1
	sub	dx, [head]
	jnz	org_head
	inc	byte [track]
org_head:
	mov	[head], dx
	sub	ax, ax
adjust_seg:
	mov	[sects], ax
	mov	ch, 0
	shl	cx, 9
	add	cx, bx
	jnc	rp_read
	mov	ax, es
	add	ax, 1000h
	mov	es, ax
	sub 	bx, bx
	cmp 	ax, END_SEG
	jb		rp_read
	jmp	$
	ret
kill_motor:
	push	dx
	mov	dx, 03f2h
	xor 	al, al
	out	dx, al
	pop 	dx
	ret
	msg_welm:		db 	"Welcome to sparrow world!"	
	msg_ld:
	db 	13
	db 	10
	db		"Loading"
	sects_per_trk:		dw	 0
	sects:					dw 1 + SETUP_SECTS		; sectors that have been read already
	head:						dw 0									; current head
	track:					dw 0									; current track
	
		times 510-($-$$)	db 	0
the display will print two lines of dots fast and then keep printing but far more slowly. Thanks!
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

For a start you need to retry on error at least 3 time, but you assume that its the wrong floppy type.
Do youself a favour and simple use 1.44MB, than maybe people will help you.
If you must use other than 1.44MB, get it working first than add that.
Milo
Posts: 16
Joined: Sat May 26, 2007 7:12 am

Post by Milo »

thanks Dex.
Right now I use the following code which is far easier to check error than the previous one. Things are more clear, that when it reads only once from floppy disk, kernel works fine. But when read twice or more, system code that has been previously read seems to be replace by the one loaded after, because the register 'bx' value is equal to zero after finish read. I check much info but still cannot find out why 'bx' would turn to zero after int 13h. any tips are appreciated.

Code: Select all

;I choose 1.44MB to be the default disk driv, whose single track consists of ;18 sectors.
;currently 'boot' and 'setup' has been read already, which took up 5 ;sectors 
;the following code will read from the sixth sector to the end of first track.
;Then it will read one track a time, with times restrict to count number(cx).
start_read:
	mov	ax, 1000h
	mov 	es, ax
	xor	bx, bx
	mov	cx, 3   ;restrict read times. When use 2 instead of 3 here, it works fine. 
	push	cx
rp_read:
	pop	cx
	dec	cx
	jnz	not_finsh
	ret
not_finsh:
	push	cx
	mov	ax, 18    ; 1.44MB floppy disk with 18 sectors per track
	sub	ax, [sects]
read_remin:
	mov	dx, [track]
	mov	cx, [sects]
	inc 	cx
	mov	ch, dl
	mov	dx, [head]
	mov	dh, dl
	mov	dl, 0
	and	dx, 0100h
	mov	ah, 2
	int 	13h
;     cmp   bx, 0           ;here bx is checked and found be zero.
;    jne   keep_read
;     ret
;   keep_read:
	mov	ah, 0
	add	ax, [sects]
	mov	dx, 1
	sub	dx, [head]
	jnz	org_head
	inc	word [track]
org_head:
	mov	[head], dx
	xor	ax, ax
	mov	[sects], ax
	jmp	rp_read

	sects:					dw 5		; sectors that have been read already
	head:						dw 0									; current head
	track:					dw 0									; current track
:)
Milo
Posts: 16
Joined: Sat May 26, 2007 7:12 am

Post by Milo »

All right, got it. missed adding the corresponding value to the bx register. The problem solved.
Post Reply