1
Lowlevel-Coding / Re: Bochs LBA support
« am: 04. September 2012, 18:00 »
So es funktioniert bei Qemu falls man die .bin datei als erstes HDD angibt.
25. November 2024, 08:24
Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.
Meinst du damit, dass QEMU den von dir geposteten Code nicht startet?
Aha, die Festplatte ist also extern und vermutlich per USB angebunden, außerdem benutzt du Windows. Schonmal zwei Informationen, die im Ursprungsartikel fehlen.
Vermutlich funktionierte das nicht.
Diese Meldung ist in deinem Code nicht drin. Also wird der überhaupt nicht ausgeführt. Im Übrigen ist es durchaus sinnvoll, wenn dein MBR auch ein paar Meldungen ausgeben kann (und wenn es ein sich veränderndes Zeichen in der oberen linken Ecke ist) - dann weiß man auf realen Systemen wenigstens, wo er hängt.
;Master Boot Record Test Version 0.0.1
;The BIOS load the MBR to the Address 0x7c00
;The CPU is in Real Mode
[BITS 16]
org 7c00h
mov ax,0x9000 ;We set the Stack to 0x9000
mov ss,ax ;Intialize Stacksegment
xor sp,sp ;Set the stackpointer to zero
xor ax,ax ;Setup segments we only work with offsets so we set the segments to zero
mov ds,ax
mov es,ax
mov di,0x0500 ;We write our structures to the Address 0x0500
mov si,PartitionTable ;We want to write fist the partition Table
mov cx,32 ;We want to transfer 32 words
rep movsw ;Transfer the Data
;The next 16 are reserved for the LBA packet
add di,0x0500 ;Load the address again
add di,80 ;We add 80 because PartitionTable = 64 bytes LBA packet = 16 bytes = 80 Bytes
mov byte[di],dl ;Store the Bootdrive
mov di,0x0600 ;Our C0ode we will write to the Address 0x0600
mov si,ExecutableCode ;
mov cx,EndOfCode-ExecutableCode
rep movsb ;Write the Code to the right Address
jmp 0x0000:0x0600 ;Let's go
ExecutableCode:
mov di,0x0500 ;Load the Address of our Structures
mov cl,0 ;In cl we store the number of our Attempts
.NextPartition:
add di,16 ;One entry in the Partition Table is 16 bytes width so we add that value to get the next entry
inc cl ;We increase our Attempts
cmp cl,3 ;If we have read 4 Partition Table entrys we must quit
ja .NoPartitionBootable ;We only have 4 entry in the Partition Table so we must quit
.VerifyBootability:
mov al,0x80
cmp al,byte[di] ;We try if the Partition is bootable so we compare the first byte of the entry with 0x80
jne .NextPartition ;okay it's not bootable so try the next Partition
;Yeah it's bootable first we will try the int 13h extension support
mov ax,0x4100 ;We use BIOS funktion 41h for that
mov bx,0x55AA ;Setup the other Parameters
mov dl,byte[0500h+80] ;get the Bootdrive from our Structures
int 13h ;Make the Call
jc .NoPartitionBootable ;If int 13h extension is not supported we quit
;int 13h extension is supported so we setup the lba packet
mov si,di ;Get the address of the partition entry which is bootable
mov di,0x0500 ;Get the address of our structures
add di,64 ;Set the Address to the begin of our LBA Packet
mov byte[di],16 ;We setup the Size of the Packet its 16 bytes
;mov byte[di+1],0 This byte will be ignored anyway so we don't need to set it
mov word[di+2],1 ;We only read one sector its the bootsektor
mov dword[di+4],0x00007c00 ;We set the low 16 bits to 0x7c00 and the high 16 bits to 0x0000 so we will load it to the correct address
mov ax,word[si+8] ;in si we stored the Value of the Partition wich we will use we store the low 16 bits of our lba address in ax
mov bx,word[si+10] ;We store the high 16 bits in bx
mov word[di+8],ax ;First we write the low 16 bits in the packet
mov word[di+10],bx ;Then we store the high 16 bits in the packet
mov dword[di+12],0 ;We don't use the high lba address
push si ;Push the address of our partition entry that we will store later in di
mov ax,0x4200
mov dl,byte[0500h+80] ;get the Bootdrive from our Structures
mov si,0500h+64 ;Get the address of our packet
int 13h ;Load it to the right address
pop di ;Set es:di to the partition entry which we use
mov dl,byte[0500h+80] ;get the Bootdrive from our Structures
jmp 0x0000:0x7c00 ;Jump to the bootsektor
.NoPartitionBootable:
int 18h ;Tell the BIOS that we fail and give the control back to it
EndOfCode:
times 0x01BD-($-$$) hlt
PartitionTable times 64 db 0 ;We need the 64 Bytes for the Partition Table
times 510-($-$$) hlt
db 0x55
db 0xAA
Da haben wir den Fehler ja schon...
Wo kommt diese Meldung her? Dein Code scheint sie nicht auszugeben.
Mit welchen Optionen startest du qemu?
Externe Festplatte heißt was genau? USB?
;Master Boot Record Test Version 0.0.1
;The BIOS load the MBR to the Address 0x7c00
;The CPU is in Real Mode
[BITS 16]
org 7c00h
mov ax,0x9000 ;We set the Stack to 0x9000
mov ss,ax ;Intialize Stacksegment
xor sp,sp ;Set the stackpointer to zero
xor ax,ax ;We only works with offsets so we set the ds and the es to zero
mov ds,ax
mov es,ax
mov byte[Bootdrive],dl
;We want to copy our code to 0x0000:0x0600
mov di, 0x0600
mov si,ExecutableCode
mov cx,EOF-ExecutableCode ;Load the Size of the Section wich we want to copy
rep movsb ;Copy it
jmp 0x0000:0x0600 ;Execute it
ExecutableCode:
mov di,Part1Bootflag
jmp Bootable_loop
Bootable_Prep:
add di,16
cmp di,Part4Bootflag
ja NoPartBootable
Bootable_loop:
;Now we are at the right position
mov al,0x80
cmp al,byte[di] ;bootable?
jnz Bootable_Prep ;No then test the next
;yes its bootable
;First we try if we have the BIOS int 13h extension
mov ax,0x4100
mov dl,byte[Bootdrive]
mov bx,0x55AA
int 13h ;Try the support
jc NoPartBootable ;If the extension is not supported we quit cause we know that Qemu and the most of the hardware will support it
;TODO: This MBR should be more optimized with CHS support
Again:
mov ax,0
mov dl,byte[Bootdrive]
int 13h ;Reset Drive
mov byte[PacketSize],16
mov word[Blockcount],0
mov dword[BufferAddr],0x7C00 ;We have an Little endian system so we write to the low 16 bits(offset bits) 0x7c00 and to the higher 0x0000 because we don't use segments
mov ax,word[di+8] ;Save the low 16 bits of the LBA Addres in ax
mov bx,word[di+10] ;And the high 16 bits in bx
mov word[BlockNumLow],ax ;Fill the lower 16 bits
mov word[BlockNumLow+2],bx ;Fill the higher 16 bits
mov ax,0x4200 ;We use ah=42h int 13h read extension
mov dl,byte[Bootdrive] ;Load our bootdrive
mov si,PacketSize ;Load the Address of the Packet
int 13h ;Use the bios 13h extension
jc Again ;If we fail we try it again
mov di,si ;Set es:di to the bootpartition entry
mov dl,byte[Bootdrive] ;Set dl to the Bootdrive
jmp 0x0000:0x7C00 ;Jump to the bootloader
NoPartBootable:
int 18h ;We have finished
Bootdrive db 0
;Normally we try to load the Bootloader with LBA via LBA Packet
PacketSize db 0 ;Our Packet size
Reserved db 0 ;Must be zero
Blockcount dw 0 ;
BufferAddr dd 0;
BlockNumLow dd 0;
BlockNumHigh dd 0;
times 446-($-$$) db 0 ;Fill the Unused bytes with zero
;This Section will be filled by the BIOS
;This is the Partition table
Part1Bootflag db 0
Part1Headstart db 0
Part1FSectorFCylinder db 0
Part1FSector db 0
Part1Type db 0
Part1LastHead db 0
Part1LSectorLCylinder db 0
Part1LastSector db 0
Part1LBAAddress dd 0
Part1Length dd 0
Part2Bootflag db 0
Part2Headstart db 0
Part2FSectorFCylinder db 0
Part2FSector db 0
Part2Type db 0
Part2LastHead db 0
Part2LSectorLCylinder db 0
Part2LastSector db 0
Part2LBAAddress dd 0
Part2Length dd 0
Part3Bootflag db 0
Part3Headstart db 0
Part3FSectorFCylinder db 0
Part3FSector db 0
Part3Type db 0
Part3LastHead db 0
Part3LSectorLCylinder db 0
Part3LastSector db 0
Part3LBAAddress dd 0
Part3Length dd 0
Part4Bootflag db 0
Part4Headstart db 0
Part4FSectorFCylinder db 0
Part4FSector db 0
Part4Type db 0
Part4LastHead db 0
Part4LSectorLCylinder db 0
Part4LastSector db 0
Part4LBAAddress dd 0
Part4Length dd 0
;Fill the last bytes until we set the bootsignatur
times 510-($-$$) db 0
db 0x55
db 0xAA
EOF:
dd bs=512 count=1 if=MBR.bin of=\\?\Device\HarddiskVolume4
Das hat sehr gut funktioniert, Bochs konnte auch weiterhin von dem Stick starten, allerdings weder mein PC noch Qemu können von dem Stick booten...
CheckLBASupport:
xor dx,dx
mov ah,0x41 ;Use the function 41h
mov bx,0x55AA ;Store the right value in bx
mov dl,byte[bootdrive] ;Get the bootdrive
int 13h ;Call the interrupt
jc LBANotSupported ;If the Carry Flag is set LBA is not supported
Ich habe diesen Code gepostet da er doch sehr übersichtlich ist. Es wird in diesem Quellcode immer die Methode LBANotSupported aufgerufen. Ich benutze Bochs 2.5.1.