Auf HDD zugreifen



  • Hallo,

    ich beschäftige mich seit einer langen Zeit mal wieder ein bisschen mit Assembler und hätte mal eine Frage. Wie kann ich direkt Sektoren auf der HDD beschreiben.
    Mich würde es interessieren, wie das unter Windows geht, wenn es überhaupt geht bzw. wie Windows das überhaupt macht. Irgendwie muss es ja irgendwo eine Stelle geben wo die mal was auf die Platte schieben. Mit dem int 13 ging das ohne Windows noch soweit ich mich noch erinnern kann.
    So, das war Punkt 1.) Die zweite Frage ist: Wie kann ich das komplett ohne Windows machen? Ich habe irgendwo noch einen alten Bootloader von früher. Long Mode wäre auch nicht das Problem. Aber wie kann ich dann auch meine kompletten 1000GB zugreifen? Und das Sektor für Sektor...



  • Es gibt bestimmt Standard Schnittstellen wie ATA/ATAPI für heute meist gebräuchliche Festplatten und CD/DVD-ROM Laufwerken. Also alles was mit PATA oder SATA angeschlossen wird.
    Da neben gibt es z.B. noch SCSI, ist eher seltener.

    Hier Dokus zu ATA/ATAPI:
    www.t13.org
    http://www.ata-atapi.com/

    Die BIOSe bieten auch unterschiedliche Funktionen die über Software Interrupts aufgerufen werden können. Dabei verwendet das BIOS selber auch den ATA/ATAPI Standard.
    Da dieser Standard sich mit der Zeit entwickelt hat, von CHS Adressierung (Cylinder Header Sector), zu LBA28 (2^28 * 512Byte Sektor = max. 128 GiB adressierbar) zu LBA48 können die BIOS Funktionen, besonders älterer Mainboards, nicht immer die gesamte Festplatte ansprechen wenn deren Größe solche magischen Grenzen überschreitet.

    Dann gibt es noch unterschiedliche Methoden die Daten zwischen der Festplatte und dem Arbeitsspeicher zu kopieren.
    Entweder es gibt für jeden Byte oder jeden 512Byte Sektor einen Interrupt und die CPU kopiert dann Byte für Byte hin und her. (Sehr veraltet und langsam!!)
    Oder man verwendet DMA bzw. beim aktuellen Standard könnte das auch schon über Bus mastering gehen.
    Dabei werden Daten ohne Zutun der CPU in den oder vom Arbeitsspeicher kopiert und die CPU erst mittels Interrupt benachrichtigt wenn alles fertig ist.



  • Hallo,

    besten Dank für deine Antwort. Da war so das ein oder andere Stichwort dabei, das mir sehr geholfen hat. Gerade das mit ATA/ATAPI.

    Allerdings ist das ja schon mit sehr viel Verwaltungsaufwand verbunden wenn man was auf die Festplatte schreiben oder von der selben lesen will. Hätte ich so erstmal nicht gedacht. Schwamm drüber...

    Habe folgendes Problem. Ich habe meinen Bootloader und hab vorerst auf PM oder LM verzichtet und bleibe erstmal im RM. Wenn ich nun versuche, was aus meinem Statusregister zu lesen, dann erhalte ich ständig ein leeres Register(00000000).
    Dementsprechend spring mein Bootloader auch bei der DRDY Überprüfung raus:-( Woran kann das liegen? Das ganze läuft unter Virtual Box. Binde das Image zum Testen immer in zwei Maschinen ein. Eine komplett leere und eine Windows 8 Test Maschine. Beide haben natürlich einen IDE Controller mit einer *.vdi. Also "intern" ist eine Platte auf jeden Fall da. Was mache ich falsch? Muss das vorher noch initialisiert werden oder so?!

    Hier mal mein Code:

    %define FREE_SPACE 0x9000
    
    ORG 0x7C00
    BITS 16 
    ;------------------------------------------------------------------------------------------------------------
    Main:
        JMP 0x0000:FlushCS
    ;------------------------------------------------------------------------------------------------------------
    FlushCS:
        CLI
        CLD
    ;------------------------------------------------------------------------------------------------------------
    	XOR  AX, AX
    	MOV  DS, AX
    	MOV  ES, AX
    	MOV  FS, AX
    	MOV  GS, AX
    	MOV  SS, AX
    	MOV  SP, Main
    ;------------------------------------------------------------------------------------------------------------
    	MOV  SI, RUNNING
        CALL PrintText
        MOV  SI, EMPLINE
        CALL PrintText
        MOV  SI, BUSY
        CALL PrintText
    ;------------------------------------------------------------------------------------------------------------
        MOV  DX, 177h 			;status register 1F7
        MOV  CX, -1
    LOOP1:
        INC  CX
        CMP  CX, 3
        JE   BUSYEXIT
        IN   AL, DX 			;sets AL to status register (which is 8 bits)
    
    	MOV  SI, CTRLSTATUS1
    	CALL PrintText
        MOV  BL, AL
        CALL PrintBinary
    	MOV  SI, EMPLINE
    	CALL PrintText
    
        AND  AL, 10000000b
        JNE  LOOP1
        CLI
    ;------------------------------------------------------------------------------------------------------------
        MOV  SI, NOTBUSY
        CALL PrintText
    ;------------------------------------------------------------------------------------------------------------
        MOV  DX, 177h 			;status register again 1F7
        MOV  CX, -1
    LOOP2:
        INC  CX
        CMP  CX, 3
        JE   READYEXIT
        IN   AL, DX 			;sets AL to status register again
    
    	MOV  SI, CTRLSTATUS2
    	CALL PrintText
        MOV  BL, AL
        CALL PrintBinary
        MOV  SI, EMPLINE
        CALL PrintText
    
        AND  AL, 01000000b
        JE   LOOP2
    ;------------------------------------------------------------------------------------------------------------
        MOV  SI, READY
        CALL PrintText
    ;------------------------------------------------------------------------------------------------------------
        MOV  DX, 176h 			;device/head register 1F6
        MOV  AL, 0 				;0 selects device 0 (master). 10h would select device 1 (slave).
        OUT  DX, AL 			;selects master device
    ;------------------------------------------------------------------------------------------------------------
        MOV  SI, ID
        CALL PrintText
    ;------------------------------------------------------------------------------------------------------------
        MOV  DX, 177h 			;command register 1F7
        MOV  AL, 0ECh 			;"IDENTIFY DRIVE" command
        OUT  DX, AL 			;sends the command!
    ;------------------------------------------------------------------------------------------------------------
        MOV  DX, 177h 			;status register 1F7
    LOOP3:
        IN   AL, DX
        AND  AL, 00001000b 		;if DRQ is not high, the device doesn't have data for us
        JE   LOOP3 				;yet, so keep looking until it does!
    ;------------------------------------------------------------------------------------------------------------
        MOV  DX, 170h 			;data register 1F0
        MOV  DI, STATUSBUFFER 	;points DI to the buffer we're using
        MOV  CX, 256 			;256 decimal. This controls the REP command.
        CLD 					;clear the direction flag so INSW increments DI (not decrements it)
        REP  INSW
    ;------------------------------------------------------------------------------------------------------------
        STI
    ;------------------------------------------------------------------------------------------------------------
        mov  SI, IDENTIFICATION
        call PrintText   
        mov  SI, STATUSBUFFER
        call PrintText
        jmp  EXIT
    ;------------------------------------------------------------------------------------------------------------
    READERROR:
        MOV  DX, 171h 			;error register 1F1
        IN   AL, DX 
    	MOV  BL, AL
        CALL PrintBinary
    	ret
    
    BUSYEXIT:
    	STI
        MOV  SI, EXITBUSY               
        CALL PrintText
    	CALL READERROR
        JMP  EXIT
    
    READYEXIT:
    	STI
        MOV  si, EXITREADY              
        CALL PrintText
    	CALL READERROR
        JMP  EXIT
    
    EXIT:
        HLT
        JMP EXIT
    ;------------------------------------------------------------------------------------------------------------
    PrintText:
    	PUSHF
        PUSHA
    .PrintLoop1:
        LODSB             		; Load the value at [@es:@si] in @al.
        TEST  AL, AL          	; If AL is the terminator character, stop printing.
        JE    .PrintDone                  	
        MOV   AH, 0x0E	
        INT   0x10
        JMP   .PrintLoop1      	; Loop till the null character not found.
    .PrintDone:
        POPA                	; Pop all general purpose registers to save them.
    	POPF
        RET
    ;------------------------------------------------------------------------------------------------------------
    PrintBinary:
    	PUSHF
        PUSHA
        MOV  CX, 8
    .PrintLoop2: 
        MOV  AH, 0x0E     
        MOV  AL, '0'
        TEST BL, 10000000b
        JZ   .Zero
        MOV  AL, '1'
    .Zero:  
        INT  0x10
        SHL  BL, 1
        LOOP .PrintLoop2
        MOV  AL, 'b'
        INT  0x10
        POPA                	; Pop all general purpose registers to save them.
    	POPF
        RET
    ;------------------------------------------------------------------------------------------------------------
        ;RUNNING        db "System is up and running..", 0x0A, 0x0D, 0
    	RUNNING        db "", 0x0A, 0x0D, 0
    
        BUSY           db "Verbindung IDE Controller..", 0x0A, 0x0D, 0
    	CTRLSTATUS1    db "Status Register1:", 0
        EXITBUSY       db "IDE Controller ausgelastet!", 0x0A, 0x0D, 0
    
        NOTBUSY        db "Bereitschaftsabfrage IDE Controller..", 0x0A, 0x0D, 0
    	CTRLSTATUS2    db "Status Register2:", 0
        EXITREADY      db "IDE Controller ist nicht bereit!", 0x0A, 0x0D, 0
    
        READY          db "Selek. Master Device..", 0x0A, 0x0D, 0
        ID             db "Sende IDENTIFY DRIVE..", 0x0A, 0x0D, 0
    
    	IDENTIFICATION db "Device ID:", 0x0A, 0x0D, 0
    
        EMPLINE        db "", 0x0A, 0x0D, 0
        STATUSBUFFER:  times 64 db 0
        VALUE		   db 0
    ;------------------------------------------------------------------------------------------------------------
    ; Pad out file.
    times 1022 - ($-$$) db 0
    dw 0xAA55
    %ifdef IMAGE
        TIMES 1474048 DB 0x00	; Empty Disk Image 1.44MB
    %endif  
    ;------------------------------------------------------------------------------------------------------------
    


  • Achso, was mir gerade aufgefallen ist. In dem Code Spreche ich den secondary IDE controller an. In dem Kommentar dahinter kann man aber sehen, dass ich es auch schon mit dem primary versucht habe.



  • Ist zu lange her, als dass ich mich daran erinnern kann. Für solche Fragen und Infos schaust du am besten hier vorbei: http://www.lowlevel.eu/

    Da gibt es eine Wiki mit Infos unter andrem zu ATA und ein Forum wo sehr viel Leute sind die sich mit solchen Sachen auskennen.

    Wenn du dem Englisch nicht ganz abgeneigt bist, würde ich auch noch hier vorbei schauen: http://www.osdev.org/


Anmelden zum Antworten