Zweiten sector von USB stick lesen
-
Hi,
Ich bin mit meinem bootloader jetzt bei der BIOS Funktion 13h ah=0x02 angekommen (Sektoren in den Speicher lesen).
Die parameter der Funktion übergebe ich in den Registern wie hier beschrieben:
http://www.ctyme.com/intr/rb-0607.htm
Ich bekomme immer den status code 1 zurück (invalid function in AH or invalid parameter). Ich bin mir aber fast zu 100% sicher das die parameter wie ich sie übergeben habe so richtig sind:
http://www.ctyme.com/intr/rb-0606.htm#Table234Hier ist der bootloader:
[ORG 0x7c00] ; The bootsector program will start at 0x7c00 and end at 0x7e00 (512bytes) ; The drive number this program is booted from is stored in dl MOV BYTE[DriveNumber], dl ; Save the drive number to memory XOR ax, ax ; Set ax to zero MOV es, ax ; Set the extra segment to address 0x0000 MOV ds, ax ; Set the data segment to address 0x0000 MOV ss, ax ; Set the stack segment to address 0x0000 MOV bp, 0x8000 ; Set the stack base pointer shortly after the end of the bootsector program MOV sp, bp ; The stack will grow in negative direction JMP begin TestString db "Hello Computer", 0 TestString2 db "Expect Me", 0 NumberBuffer db "------", 0 HexString db "0123456789ABCDEF", 0 InfoMessage db "Could not read sector(s):", 0 InfoMessage2 db "Drive Number:", 0 DriveNumber db 0x00 LetterZero db '0' begin: ;MOV ah, 0x02 ;INT 0x10 MOV cx, 0x0202 MOV dx, TestString2 CALL printString MOV cx, 0x0000 MOV dx, TestString CALL printString MOV cx, 0x0004 MOV dx, InfoMessage2 CALL printString MOV cx, 0x0E04 MOV dx, 0x0000 MOV dl, BYTE[DriveNumber] CALL printValue CALL readSecondSector hang: jmp hang ; ------------------------------------------------------------- ; 0x0 = black 0x1 = blue ; 0x2 = green 0x3 = cyan ; 0x4 = red 0x5 = magenta ; 0x6 = brown 0x7 = white ; 0x8 = grey 0x9 = bright blue ; 0xA = bright green 0xB = bright cyan ; 0xC = bright red 0xD = bright magenta ; 0xE = bright yellow 0xF = bright white ; ; In text video memory mode the screen resolution will be ; 80 columns x 25 lines. ; This function will print a single letter to text video memory ; ; 1.Parameter cx = position (low=y heigh=x) ; 2.Parameter dx = letter (low=letter heigh=attribute) printLetter: PUSHA ; Save the state of all registers to the stack MOV ax, WORD 0 ; Set ax to zero MOV al, 160 ; 80 columns = 160 bytes (2bytes per letter) MUL cl ; Multiply y position with the number of columns MOVZX bx, ch ; Save the x position in the full bx register SHL bx, 1 ; Multiply the x position with two because every letter uses 16bit MOV di, 0 ; Go to the begin of video memory ADD di, bx ; Add x offset ADD di, ax ; Add y offset MOV bx, 0xb800 ; Set bx to the text video memory address MOV es, bx ; Set the extra segment to the text video memory address MOV WORD[es:di], dx ; write letter to video memory POPA ; Restore the state of all registers RET ; Return ; ------------------------------------------------------------- ; Print a string to text video memory ; cx = position to print to (low=y heigh=x) ; dx = string pointer (low=letter heigh=attribute) printString: PUSHA ; Save the state of all registers to the stack MOV ax, WORD 0 ; Use ax as a counter variable .printLoopBegin: PUSH dx ; Save the address of the string to the stack MOV bx, dx ; Save address of the string to be printed in bx ADD bx, ax ; Add the counter value to the string address MOV dl, BYTE[bx] ; Save the current letter to dl MOV dh, 0x1F ; Set the color attribute of the current letter to dh CMP dl, BYTE 0 ; Compare the current letter with zero JE .printLoopEnd ; If the current letter is zero then ; jump to the end of the printing loop CALL printLetter ; Print the current letter to the screen INC ch ; Increment the x position INC ax ; Increment the counter POP dx ; Retrieve the address of the string JMP .printLoopBegin ; Jump to the begin of the loop .printLoopEnd: POP dx ; Pop dx from the stack because after jumping out of the loop, dx will still be on the stack POPA ; Restore all registers RET ; Return ; ------------------------------------------------------------- ; Print a number to the screen in 'text video memory' mode ; cx = position (low=y heigh=x) ; dx = value printValue: PUSHA ; Save all registers to the stack PUSH cx ; Save position to print to MOV ax, dx ; Save the value to be printed to ax MOV cx, WORD 0 ; Use cx as a counter .clearLoopBegin: ; This loop will fill the number buffer with '0' letters MOV dl , BYTE[LetterZero] ; Save the letter '0' to dl MOV bx , NumberBuffer ; Set bx to the address of the buffer where the number is printed to ADD bx , cx ; Add the counter value to the number buffers address MOV BYTE[bx], dl ; Write the letter in dl to the number buffer INC cx ; Increment the counter CMP cx , WORD 6 ; Test if the counter is at value 6 JE .clearLoopEnd ; If the counter is 6 jump out of the loop JMP .clearLoopBegin ; Jump to the begin of the loop .clearLoopEnd: MOV cx, WORD 0 ; Set the counter to zero again .divLoopBegin: ; THis loop will divide the value in ax in every round by 10 MOV dx, WORD 0 ; The remainder of the div operation will be stored in dx MOV bx, WORD 10 ; Set bx to 10 DIV bx ; Divide ax by bx (10) MOV bx, HexString ; Save the address of the number string to bx ADD bx, dx ; Add the remainder to the address of the number string MOV dl, BYTE[bx] ; Save the letter to dl MOV bx , NumberBuffer ; Set bx to the address of the buffer where the number is printed to ADD bx , WORD 5 ; Set the address to the last element of the buffer SUB bx , cx ; Substract the counter value from the buffer address MOV BYTE[bx], dl ; Write the letter to the buffer INC cx ; Increment the counter CMP ax, WORD 0 ; Thest if the value that should be printed is zero JE .divLoopEnd ; If the value is zero then jump out of the loop JMP .divLoopBegin ; Jump to the begin of the dividing loop .divLoopEnd: POP cx ; Restore the printing position from the stack to cx MOV dx, NumberBuffer ; Set dx to the address of the number buffer CALL printString ; Print the number buffer to the screen POPA ; Restore all registers RET ; Return ; ------------------------------------------------------------------ ; readSecondSector: MOV dl, [DriveNumber] ; Select the drive to read from MOV ch, 0 ; Select cylinder 0 MOV dh, 0 ; Select head 0 MOV al, 1 ; Set the number of sectors to read MOV cl, 2 ; Begin reading from the second sector (the sector immediately after the boot sector) MOV bx, 0 ; Set bx to zero MOV es, bx ; Set the extra segment to zero MOV bx, 0x9000 ; The data to be read will be stored at [es:bx] (address 0x0000:0x9000) MOV ah, 0x02 ; Set the BIOS interrupt function to "read sector function" INT 0x13 ; Call the interrupt JC .DiskReadFailed ; Jump if the carry flag is set MOV cx, 0x1A06 ; Print at line 6 after the info message MOVZX dx, ah ; Store the status code of interrupt 0x13 into dx CALL printValue ; Print the status code of interrupt 0x13 MOV cx, 0x0008 ; Set the printing position to line 8 MOV dx, 0x9000 ; Set the address where the second sector is loaded to memory to dx CALL printString ; Print the string from the second sector to the screen RET .DiskReadFailed: MOV cx, 0x0006 ; Print at line 6 MOV dx, InfoMessage ; Store the address of an info message into dx CALL printString ; Print the info message MOV cx, 0x1A06 ; Print at line 6 after the info message MOVZX dx, ah ; Store the status code of interrupt 0x13 into dx CALL printValue ; Print the status code of interrupt 0x13 RET ; ------------------------------------------------------------------ ; TIMES 510-($-$$) DB 0 ; Fill the file til byte 510 with zeros DB 0x55 ; Set byte 511 to the magic bootsector number DB 0xAA ; Set byte 512 to the magic bootsector number ; ------------------------------------------------------------------ ; DB "This text is stored on an USB flash drive this bootloader was started from", 0 TIMES 1024-($-$$) db 0x00
Die Funktion die den zweiten Sektor lesen soll heist hier "readSecondSector"
Kann es sein das ich für USB flash drives eine andere Funktion verwenden muss? Ich lese immer nur etwas von HDDs und Floppies. Ein usb stick hat auch nicht wirklich leseköpfeMfG
Silvio
-
Ich habe rausgefunden, dass ich wohl tatsächlich nicht int 13h ah=0x02 verwenden kann um den zweiten sector zu lesen.
Da gibt es wohl eine Erweiterung zu int 13h (int 13h extensions) womit es funktionieren soll.
Ich habe eine kleine Funktion geschrieben, die testet ob int 13h extensions verfügbar sind:ExtensionInfoMessage db "Interrupt 13h extensions available", 0 NoExtensionInfoMessage db "No interrupt 13h extensions available", 0 ; ------------------------------------------------------------------ ; checkInt13Extensions: MOV bx, 0xAA55 ; Set bx to the magic number MOV ah, 0x41 ; Select the interrupt 13h function 0x41 INT 0x13 ; Call interrupt 13h JC .NoInt13Extension ; If the interrupt 13h extensions are supported then the carry flag is not set CMP bx, 0xAA55 ; Test if the magic number is still present JNE .NoInt13Extension ; Go to error handling if not MOV cx, 0x0006 ; Write info message to line 6 MOV dx, ExtensionInfoMessage ; Set the address of the info message to dx CALL printString ; print the info message RET .NoInt13Extension: MOV cx, 0x0006 ; Write info message to line 6 MOV dx, NoExtensionInfoMessage ; Set the address of the info message to dx CALL printString ; print the info message RET
Bei mir sind die Erweiterungen anscheinend nicht verfügbar. Kann mal jemand testen ob bei ihm die Erweiterungen verfügbar sind?
Für mich stellt sich jetzt natürlich die frage wie ich Daten von dem stick in den Speicher bekomme...
MfG
Silvio