Virtual PC VHD Boot

If you are new to OS Development, plan on spending some time here first before going into the other forums.

Moderator:Moderators

Post Reply
battewr
Posts:6
Joined:Sun Jun 20, 2010 8:20 pm
Virtual PC VHD Boot

Post by battewr » Sun Jun 20, 2010 10:03 pm

Hi,

I was fiddling around with the bootloader and basically created a fixed drive of 10MB. I took the bootloader from Chapter 4 (the final little set of assembly that prints a message and halts). I tested it on a physical computer and with virtual floppy and it seemed to work great. I took the same binary and did a DD to the VHD file itself (reports 512 bytes moved). Virtual PC loads, detects the magic number (no error message about an unbootable drive), but hangs without printing anything (the cursor moves down a line and seems to just stop). The VM is reporting 1kb read.

If I fudge the magic number, it changes and reports an unbootable drive.

If I remove the "partition" section (just try to print a message), no change.

If I remove the cli and hlt at the end, no change (I would expect the VM to go screaming through the hard drive and eventually crash... VM is still reporting 1kb read).

The magic number reporting correctly (or incorrectly when I change it) seems to imply that VPC is reading the block from the VHD correctly, but it isn't executing any instructions. The fact that it works as a virtual floppy screams that I messed something up though :) Other then the playing described above, the code is verbatem copy and paste from the chapter 4 example.

Any ideas if VPC expects something special from the VHD in order to boot? It reports as a valid VHD still after my DD operation to the first 512 bytes; I can still mount it on my Windows 7 computer (I checked)... for sanity last weekend I downloaded the VHD spec from MS, I don't see anything I could have messed up there (Fixed hard drives are pretty simple).

Thanks

battewr
Posts:6
Joined:Sun Jun 20, 2010 8:20 pm

Re: Virtual PC VHD Boot

Post by battewr » Mon Jun 21, 2010 2:55 am

Update: I changed the code to print out individual characters and put in a cx loop instead. It was moving the cursor. I then added a manual write D before and after the print function. It successfully wrote D followed by the spaces followed by another D.

When I look manually at the binary (and the fixed drive) with a binary reader, the string is there...

Still not sure whats wrong with the db section... it seems like when I DD the binary to the fixed drive, something might be wrong with the db section?

battewr
Posts:6
Joined:Sun Jun 20, 2010 8:20 pm

Re: Virtual PC VHD Boot

Post by battewr » Mon Jun 21, 2010 2:58 am

This is what the code looks like now (its the closest I've been to working):

Code: Select all

;*********************************************
;	Boot1.asm
;		- A Simple Bootloader
;
;	Operating Systems Development Tutorial
;*********************************************

[bits 16]							; We are still in 16 bit Real Mode
[org 0x7c00]						; We are loaded by BIOS at 0x7C00

xor	ax, ax		; Setup segments to insure they are 0. Remember that
mov	ds, ax		; we have ORG 0x7c00. This means all addresses are based
mov	es, ax		; from 0x7c00:0. Because the data segments are within the same
mov	cx, 31
			; code segment, null em.
call loader					; jump over OEM block

end:
	cli
	hlt

;***************************************
;	Prints a string
;	DS=>SI: 0 terminated string
;***************************************

PrintChar:
			mov			ah, 0x0e	; Nope-Print the character
			mov 			bh, 0x00	; Page no.
			mov 			bl, 0x07	; Text attribute 0x07 is lightgrey font on black background
			int			0x10
			ret


Print:
			;lodsb
			mov al, [si]
			inc si
			;or			al, al		; Does AL=0?
			;jz			PrintDone	; Yep, null terminator found-bail out
			call PrintChar
			;jmp			Print		; Repeat until null terminator found
			loop			Print
PrintDone:
			ret					; we are done, so return

;*************************************************;
;	Bootloader Entry Point
;*************************************************;

loader:

	mov	si, HelloWorld					; our message to print
	
		mov			al, 'D'
		call PrintChar
	call	Print						; call our print function
		mov			al, 'D'
		call PrintChar

	;xor	ax, ax						; clear ax
	;int	0x12						; get the amount of KB from the BIOS

	ret

HelloWorld db 'Welcome to My Operating System!', 0

times 510 - ($-$$) db 0						; We have to be 512 bytes. Clear the rest of the bytes with 0

dw 0xAA55							; Boot Signiture

halofreak1990
Posts:92
Joined:Thu May 27, 2010 8:54 pm
Location:Netherlands

Re: Virtual PC VHD Boot

Post by halofreak1990 » Mon Jun 21, 2010 9:08 am

I don't really get why you'd set the text attributes. Black & white (0x07) is the default color scheme in real mode. And mov bh, 0x00? what's that for?

Code: Select all

PrintChar:
         mov         ah, 0x0e    ; Nope-Print the character
         mov         bh, 0x00    ; Page no.
         mov         bl, 0x07    ; Text attribute 0x07 is lightgrey font on black background
         int         0x10
         ret
Also, I think you should take a very good look at your Print routine.
From the looks of it, it is not checking for a null-terminator at the end of the string, which would mean it'd loop forever.

The code below comes straight from my own bootloader (it's for floppy disks, but the print routine should work regardless.)

Code: Select all

Print:
	lodsb						; load next byte from string from SI to AL
	or	al, al				; Does AL=0?
	jz	PrintDone			; Yep, null terminator found-bail out
	mov	ah, 0eh			 ; Nope-Print the character
	int	10h
	jmp	Print				; Repeat until null terminator found
PrintDone:
	ret						  ; we are done, so return

battewr
Posts:6
Joined:Sun Jun 20, 2010 8:20 pm

Re: Virtual PC VHD Boot

Post by battewr » Mon Jun 21, 2010 5:38 pm

The important thing is that verbatem copy and paste from chapter 4 doesn't work.

There is another difference between these setups... the code that doesn't work (also doesn't work in Bochs now)... I am using a different version of NASM... did they change how addressing works around labels? If I change:
mov si, HelloWorld

to

mov si, 0x7c00 + ($-$$) + " some offset ahead depending on how many bytes further into the program the string is"

Everything works great if I do that. I can switch back to verbatem from the example (null terminated string instead of a cx loop) and it works great. The problem is when I am trying to address to the string label directly.

I tried changing the initial clearing of es (es:si) to leave it set to 0x7c0 based on offset addressing and if I mov si, 0 and print 512 bytes, I see my program print out on screen...

Check out the comments if you are curious... but I am unsuccessful in referencing HelloWorld the label direclty. When I cmp HelloWorld, 0 it jumps as "less then".

The following is the code that works perfectly (and can be modified to work as null terminated... see the comments) I just dont understand why I can't reference the db's label:

Code: Select all

;*********************************************
;	Boot1.asm
;		- A Simple Bootloader
;
;	Operating Systems Development Tutorial
;*********************************************

[bits 16]							; We are still in 16 bit Real Mode
[org 0x7c00]						; We are loaded by BIOS at 0x7C00

xor	ax, ax		; Setup segments to insure they are 0. Remember that
;mov	ax, 0x7c0
mov	ds, ax		; we have ORG 0x7c00. This means all addresses are based
mov	es, ax		; from 0x7c00:0. Because the data segments are within the same
mov	cx, 31
			; code segment, null em.
call loader					; jump over OEM block

end:
	cli
	hlt

;***************************************
;	Prints a string
;	DS=>SI: 0 terminated string
;***************************************

PrintChar:
			mov			ah, 0x0e	; Nope-Print the character
			mov 			bh, 0x00	; Page no.
			mov 			bl, 0x07	; Text attribute 0x07 is lightgrey font on black background
			int			0x10
			ret


Print:
			lodsb
			;mov al, [si]
			;inc si
			;or			al, al		; Does AL=0?
			;jz			PrintDone	; Yep, null terminator found-bail out
			call PrintChar
			;jmp			Print		; Repeat until null terminator found
			loop			Print
PrintDone:
			ret					; we are done, so return

;*************************************************;
;	Bootloader Entry Point
;*************************************************;

loader:
	mov	si, 0x7c00 + ($-$$) + 25				; our message to print
	;cmp	si, -0x7c0
	;jle	stage2
returnto:
	
		mov			al, 'D'
		call PrintChar
	call	Print						; call our print function
		mov			al, 'D'
		call PrintChar

	;xor	ax, ax						; clear ax
	;int	0x12						; get the amount of KB from the BIOS

	ret

stage2:
	mov al, 'A'
	call PrintChar
	jmp returnto

HelloWorld db 'Welcome to My Operating System!', 0

times 510 - ($-$$) db 0						; We have to be 512 bytes. Clear the rest of the bytes with 0

dw 0xAA55							; Boot Signiture

battewr
Posts:6
Joined:Sun Jun 20, 2010 8:20 pm

Re: Virtual PC VHD Boot

Post by battewr » Mon Jun 21, 2010 5:51 pm

Oh and the extra stuff in the registers that I loaded there seems to have no effect either way. My "D"'s print great in this program always. I actually pulled those extra high and low values off another tutorial (the same one that I was using as a reference for the cx loop). I did assembly in university, but this is my very first foray into NASM, so when things work sometimes and not others, I have no clue why yet :) so I was just fiddling.

My problems all seem to happen on my Windows 7 computer (in Bochs too, same Flat file setup using DD to write to the .img file) with a newer version of NASM... I might play with NASM versions when I get home. Same exact behavior in Bochs as VPC too... so I might also try a virtual floppy setup on my windows 7 computer now and confirm the problem is completely isolated to that computer and NASM combination.

battewr
Posts:6
Joined:Sun Jun 20, 2010 8:20 pm

Re: Virtual PC VHD Boot

Post by battewr » Mon Jun 21, 2010 7:40 pm

After 2 days of messing with this... I downgraded my NASM from 2.09rc1 to 2.08... everything works on my Windows 7 machine now.

Now that sucks.

Post Reply