Loading second stage boot-loader triggers CF

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.
felipe
Member
Member
Posts: 27
Joined: Tue Sep 28, 2010 8:19 am

Re: Loading second stage boot-loader triggers CF

Post by felipe »

Can you load a floppy ok? Try to use this (it is a piece of my own bootloader) and see if you get a 'A' at memory 0x7e00
(If you don't know just press Ctrl+Alt+2 on QEMU and enter the command xp /1c 0x7E00)

Code: Select all

[bits 16]
[org 0x7c00]

	jmp 0:start
start:
	mov ax, 0
	mov ds, ax
	mov es, ax
	mov ss, ax
	mov [driveNum], dl
	mov sp, 0x7c00
	jmp 0:clearCS
	

clearCS:
	mov bx, 0x7e00
	mov ax, 1
	mov cx, 1
	call loadSector

	jmp $

;;; ======================================================================= ;;;
;;; IN:
;;; 	es:bx 	- buffer address
;;;	ax	- logical sector number (0 based)
;;;     cx  	- number of sectors
;;; 
loadSector:
	pusha

	;; reset floppy
	push ax
.reset:
	mov ah, 0
	mov dl, [driveNum]
	stc			
	int 0x13
	jc .reset
	pop ax

	push cx 		; save counter

	;; get CHS args, ax has the logical sector number
	call LBAToCHS 
	
	pop ax			; put counter in al
	mov ah, 2
	
	mov dl, [driveNum]

	stc
	clc
	int 0x13
	jc .reset

	popa
	ret

;;; ======================================================================= ;;;
;;; IN:
;;; 	ax - logical sector number
;;;
;;; OUT:
;;; 	ch - cylinder
;;; 	dh - head
;;; 	cl - sector
;;; 
LBAToCHS:
	push di
	push bx
	push dx
	
	mov di, ax 		;save lba number

	;; store sector number in cl
	mov dx, 0
	mov bx, 18
	div bx
	inc dx
	mov cl, dl

	;; store cylinder number in ch
	mov ax, 18
	mov bx, 2
	mul bx
	mov bx, ax
	mov dx, 0
	mov ax, di
	div bx
	mov ch, al

	;; store head number in dh
	mov dx, 0
	mov ax, di
	mov bx, 18
	div bx
	mov dx, 0
	mov bx, 2
	div bx
	mov dh, dl

	pop bx
	mov dl, bl
	pop bx
	pop di
	
	ret
	
;;; ======================================================================= ;;;

driveNum:	db 0
	
	times 510-($-$$) db 0
	db 0x55, 0xaa
	
db 'A'


and here is the code to build it on Linux:

Code: Select all

nasm -f bin boot.asm -o boot.bin || exit
dd if=/dev/zero of=boot.flp bs=1024 count=1440
dd conv=notrunc if=boot.bin of=boot.flp
qemu -fda boot.flp
Dulci
Posts: 17
Joined: Tue Oct 05, 2010 4:34 pm

Re: Loading second stage boot-loader triggers CF

Post by Dulci »

That code does work. So obviously the problem is with no-emulation. I have seen in some research that people say no emulation has a lot of advantages. Is it really worth it? Is there a place I can go to learn more about booting up from no emulation?
Dulci
Posts: 17
Joined: Tue Oct 05, 2010 4:34 pm

Re: Loading second stage boot-loader triggers CF

Post by Dulci »

Did some more inspection, DL is actually still 224, however, memory was messing up for some reason (and I was storing the value of dl in memory).

Here is an update on what I have as far as code goes. I changed it so I don't rely on the stack, since I don't have the stack set up right now, amongst other various changes.

Code: Select all


%macro print 2
	mov ah, 0xa
	mov al, [%1]
	mov bl, 0xf
	mov bh, 0
	mov cx, %2
	int 0x10
%endmacro

%macro printr 2
	mov al, %1
	mov bl, 0xf
	mov bh, 0
	mov cl, %2
	mov ah, 0xa
	int 0x10
%endmacro	

[ORG 0x7c00]
[BITS 16]

jmp 0x0000:bootstart ; jump to set up CS:IP

bootstart:
	; Set our data segment
	xor ax, ax
	mov ds, ax
	mov es, ax
	mov [dlvalue], dl
	; Clear interrupts
	cli
	print greeting, 1
	jmp reset
	; 2048 bytes per sector on no emulation mode
	; 18 sectors per track
	; 63 tracks

reset:
	mov		ah, 0					; reset floppy disk function
	mov		dl, [dlvalue]
	stc								; in case a buggy bios doesn't set it on failure	
	int		0x13					; call BIOS
	jmp 	readCD
	jc reset
	
readCDerror:
	xor 	ch, ch
	xor		cl, cl
	mov dl, [dlvalue]
	printr 	[error], ah
	jmp 	reset
	
readCD: ; Read 0x7700 bytes from the disk to point 0x500 in memory from beginning of cd
	mov dh, 0 ; Drive head
	mov ax, 0x500
	mov es, ax ; Set es to 0x500, where we want to buffer to
	xor bx, bx ; buffer is at 500:0, es:bx
	mov ch, 0 ; Set track to 0
	mov cl, 1 ; sector to 1
	mov ah, 0x2 ; What we want to do with 0x13
	mov al, 0x2 ; How much we want to read
	mov dl, [dlvalue]
	stc
	clc
	int 0x13
	jc readCDerror ; There was a problem with reading
	
jumpOut:
	print load, 10
	hlt
	jmp 0x500:0x0 ; No problem, just jump to the entry point
	
data:
	greeting   db 'G'
	error   db 'E'
	load   db 'L'
	dlvalue db 0
times 510-($-$$) db 0
dw 0x55AA

felipe
Member
Member
Posts: 27
Joined: Tue Sep 28, 2010 8:19 am

Re: Loading second stage boot-loader triggers CF

Post by felipe »

First, you inverted the bytes at the end of the file, you have to use dw 0xAA55 to make it bootable.
Second, there is no point in setting the carry flag just to clear it in the next line in the readCD code.
Third, you should leave interrupts alone, and only clear the interrupt flag just before the hlt, see my own thread
http://forum.osdev.org/viewtopic.php?f=1&t=22583 specially the third post from the bottom.

Other than that I tested your code and it seems to work, that is a bunch of L's get printed on the screen and the code stops at the hlt. I tested it on QEMU and only created a virtual floppy like my example, despite the "readCD". My dlvalue by the way is 0. And the load code is definitely working, memory 0x500:0 has the code. Try making those modifications and building the way I built my example to see if it works.
Dulci
Posts: 17
Joined: Tue Oct 05, 2010 4:34 pm

Re: Loading second stage boot-loader triggers CF

Post by Dulci »

Okay, thank you for all of your help!
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: Loading second stage boot-loader triggers CF

Post by qw »

felipe wrote:

Code: Select all

	mov ss, ax
	mov [driveNum], dl
	mov sp, 0x7c00
A little warning. For a moment you are leaving the stack in an undefined state. You should load SP immediatley after SS.
Post Reply