How to convert a flat floppy image to a qemu hard disk

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
kemosparc
Member
Member
Posts: 207
Joined: Tue Oct 29, 2013 1:13 pm

How to convert a flat floppy image to a qemu hard disk

Post by kemosparc »

Hi,

I am trying to put some data on my floppy disk to use it inside my OS. My OS boots perfectly from my floppy and I can read the data,


Actually the data I am loading is getting larger than 1.4 MB so I have decided to switch to a hard disk.

But when I boot with Qemu and try to load the disk parameters using interrupt 13H using the following code:

Code: Select all

  mov ah,0x8                      ; Get Drive Parameters
    mov dl,0x80                     ; First Internal Hard Drive
    int 0x13

    add dh,0x1                      ; DH has the number of heads-1
    mov [heads],dh                  ; Store number of heads into memory

    mov ax,cx                       ; The 10 left most bits of CX has the
    shr ax,0x6                      ; number of Cylenders-1
    add ax,0x1
    mov [cyl],al                    ; Store number of cylenders into memory

    mov ax,cx                       ; The 6 right most bits of CX has the
    and ax,0000000000111111b        ; number of sectors per cylender - 1
    add ax,0x1
    mov [sectors],al                ; Store number of sector to memory

The number of cylinders returns 0. here is a snapshot from qemu info registers at this point:

Code: Select all

QEMU 2.0.0 monitor - type 'help' for more information
(qemu) info registers
EAX=00000040 EBX=00000008 ECX=0000003f EDX=00001001
ESI=000082e6 EDI=00000000 EBP=00000000 ESP=00007bfc
EIP=0000803d EFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 0000ffff 00009300
CS =0000 00000000 0000ffff 00009b00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 ffffffff 00c09300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT=     0000832d 0000000f
IDT=     00000000 000003ff
CR0=00000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Notice that CX right most 10 bits are zeros.

I created my disk as follows:
$(CAT) $(BIN)/bootstage1.bin $(BIN)/bootstage2.bin $(BIN)/stage1.bin $(BIN)/trampoline.bin /dev/zero | $(DD) bs=512 count=2880 of=$(IMAGE)/boot.flp
$(DD) if=$(BIN)/bosml.bin bs=512 seek=25 of=$(IMAGE)/boot.flp conv=notrunc,noerror
$(DD) if=$(IMAGE)/ramdisk.img bs=512 seek=825 of=$(IMAGE)/boot.flp conv=notrunc,noerror
$(DD) if=$(BIN)/KernelMain.bin bs=512 seek=1625 of=$(IMAGE)/boot.flp conv=notrunc,noerror

Any ideas on how to convert the resulting image to another format that when I start qemu with "-hda" instead of "-fda" it fetches its cylinders configuration correctly?

Thanks
Karim.
Octocontrabass
Member
Member
Posts: 6298
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to convert a flat floppy image to a qemu hard disk

Post by Octocontrabass »

Is your disk image smaller than 1096704 bytes? If so, qemu is reporting the correct number of cylinders.
kemosparc
Member
Member
Posts: 207
Joined: Tue Oct 29, 2013 1:13 pm

Re: How to convert a flat floppy image to a qemu hard disk

Post by kemosparc »

Yes, my image is around than 10 MB

I did the same but on physical USB:

Code: Select all

	$(CAT) $(BIN)/bootstage1.bin $(BIN)/bootstage2.bin $(BIN)/stage1.bin $(BIN)/trampoline.bin  /dev/zero | $(DD) bs=512 count=2880 of=/dev/sdb
	$(DD) if=$(BIN)/bosml.bin bs=512 seek=25 of=/dev/sdb conv=notrunc,noerror
	$(DD) if=$(IMAGE)/ramdisk.img bs=512 seek=825 of=$(IMAGE)/boot.flp conv=notrunc,noerror	
	$(DD) if=$(BIN)/KernelMain.bin bs=512 seek=1625 of=/dev/sdb conv=notrunc,noerror	

and booted with qemu using "-hda /dev/sdb" and it worked fine with now problems.

From the USB it reads the correct number of sectors.

How can I move the data from the usb to a qcow image for example and boot from it.

Thanks.
Karim.
Octocontrabass
Member
Member
Posts: 6298
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to convert a flat floppy image to a qemu hard disk

Post by Octocontrabass »

kemosparc wrote:Yes, my image is around than 10 MB
I don't understand. Exactly how big is your image?
kemosparc
Member
Member
Posts: 207
Joined: Tue Oct 29, 2013 1:13 pm

Re: How to convert a flat floppy image to a qemu hard disk

Post by kemosparc »

Sorry,

It is almost 10 MB

But even when I decrease it to 1.5 MB it still does not work.

When I move it to the USB it works

Thank,
Karim
Octocontrabass
Member
Member
Posts: 6298
Joined: Mon Mar 25, 2013 7:01 pm

Re: How to convert a flat floppy image to a qemu hard disk

Post by Octocontrabass »

That's strange, qemu should be able to guess the correct parameters automatically. You can override it with the -hdachs option, with something like this:

qemu -hdachs 40,16,32,none

That will give you a hard disk that is exactly 10 megabytes. (Please read the manual if you'd like a different size.)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: How to convert a flat floppy image to a qemu hard disk

Post by Brendan »

Hi,

This isn't the problem at all, but...
kemosparc wrote:

Code: Select all

    mov ax,cx                       ; The 10 left most bits of CX has the
    shr ax,0x6                      ; number of Cylenders-1
    add ax,0x1
    mov [cyl],al                    ; Store number of cylenders into memory
CL contains the highest 2 bits of the cylinder number (not the lowest 2 bits of the cylinder number); so you'd need to do something more like:

Code: Select all

    mov ax,cx   ;al = highest 2 bits of max. cylinder in bits 6 and 7, ah = lowest 8 bits of cylinder
    shr al,6    ;al = highest 2 bits of max. cylinder in bits 0 and 1
    ror ax,8    ;ax = max. cylinder number
    inc ax      ;ax = total cylinders
    mov [cyl],ax     ; Store number of cylinders
Also note that the number of cylinders can be from 1 to 1024, and when there's more than 255 cylinders it won't fit in a byte.

Finally; don't forget that this old BIOS function is almost entirely obsolete for hard disks. For very tiny hard disks (< 512 MiB) it's fine. For small drives (between 512 MiB and 8 GiB); the BIOS function is limited to 1024 cylinders and 64 sectors per track, and the old ATA interface is/was limited to 16 heads; which means that the BIOS has to do insane hackery (geometry translation) to make it work. For anything larger it's unusable.

Basically; you want to be using "IBM/MS INT 13 Extensions" (e.g. int 0x13, AH=0x48) instead.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
kemosparc
Member
Member
Posts: 207
Joined: Tue Oct 29, 2013 1:13 pm

Re: How to convert a flat floppy image to a qemu hard disk

Post by kemosparc »

Hi,

My problem was that if the disk image is not exactly divisible by 512 Qemu will get confused and report incorrect CHS values.

Here is my final version of the DD command that worked:

Code: Select all

	$(CAT) $(BIN)/bootstage1.bin $(BIN)/bootstage2.bin $(BIN)/stage1.bin $(BIN)/trampoline.bin /dev/zero | $(DD) bs=512 count=61440 of=$(IMAGE)/boot.flp
	$(DD) if=$(BIN)/bosml.bin bs=512 seek=25 of=$(IMAGE)/boot.flp conv=notrunc,noerror
	$(DD) if=$(IMAGE)/ramdisk.img bs=512 seek=825 of=$(IMAGE)/boot.flp conv=notrunc,noerror
	$(DD) if=$(BIN)/KernelMain.bin bs=512 seek=52025 of=$(IMAGE)/boot.flp conv=notrunc,noerror
Notice that I have created the whole file image in the first line to be 61440 sectors and then I started writing within it using the seek command.

Just thought it might be of any benefit for anyone who is going through the same problem now or in the future.

Thanks,
Karim.
Post Reply