;=----------------------------------------------------------------------------=; ; GNU GPL OS/K ; ; ; ; Authors: spectral` ; ; NeoX ; ; ; ; Desc: Basic Read Only ATA Long mode Driver ; ; (x86_64 architecture only) ; ;=----------------------------------------------------------------------------=; [BITS 64] ;; BPB %define OEMName bp+0x03 ; Disk label %define bytesPerSector bp+0x0b ; Bytes per sector %define sectorsPerCluster bp+0x0d ; Sectors per cluster %define reservedSectors bp+0x0e ; Reserved sectors %define fats bp+0x10 ; Number of fats %define rootDirEntries bp+0x11 ; Number of entries in root dir %define sectors bp+0x13 ; Logical sectors %define mediaType bp+0x15 ; Media descriptor byte %define fatSectors bp+0x16 ; Sectors per FAT %define sectorsPerTrack bp+0x18 ; Sectors per track %define heads bp+0x1a ; Number of sides/heads %define hiddenSectors bp+0x1c ; Hidden sectors %define hugeSectors bp+0x20 ; LBA sectors %define biosBootdrvNum bp+0x24 ; Bootdrv number %define reserved bp+0x25 ; This is not used %define bootSignature bp+0x26 ; Bootdrv signature %define volumeId bp+0x27 ; Volume ID %define volumeLabel bp+0x2b ; Volume Label %define fatTypeLabel bp+0x36 ; File system type ;; GLOBAL DATA Bootdrv db 0 end db "[End of Sector]", 0x0A, 0x0D, 0x0 buffer: times 513 db "_" ;; TEXT ata_read: ;-----------------------------------------------------------------------; ; x64/LM ATA Reading function ; ; bl : number of sectors to read XXX ; ; bh : the first sector to read ; ;-----------------------------------------------------------------------; ; Technical infos about the ports (Intel Doc): ; ; Port Access Mode Misc ; ; 1f0 r/w Data register, the bytes of the disk itself ; 1f1 r Error register that can be handled ; 1f2 r/w Sector count, how many sectors to read ; 1f3 r/w Sector number, the actual sector wanted ; 1f4 r/w Cylinder low, cylinders is 0-1024 ; 1f5 r/w Cylinder high, this makes up the rest of the 1024 ; 1f6 r/w Drive/head ; bit 7 = 1 ; bit 6 = 0 ; bit 5 = 1 ; bit 4 = 0 drive 0 select ; = 1 drive 1 select ; bit 3-0 head select bits ; 1f7 r Status register ; bit 7 = 1 controller is executing a command ; bit 6 = 1 drive is ready ; bit 5 = 1 write fault ; bit 4 = 1 seek complete ; bit 3 = 1 sector buffer requires servicing ; bit 2 = 1 disk data read corrected ; bit 1 = 1 index - set to 1 each revolution ; bit 0 = 1 previous command ended in an error ; 1f7 w Command register ; commands: ; 50h format track ; 20h read sectors with retry ; 21h read sectors without retry ; 22h read long with retry ; 23h read long without retry ; 30h write sectors with retry ; 31h write sectors without retry ; 32h write long with retry ; 33h write long without retry ; push rax push rbx push rcx push rdx push rdi mov dx, 0x1f6 ; Drive and head port mov al, 0x0a0 ; Drive 0, head 0 out dx,al mov dx, 0x1f2 ; Sector count port mov al, bl ; Read bl(s) sector out dx, al mov dx, 0x1f3 ; Sector number port mov al, bh ; Read from sector n°bh out dx, al mov dx, 0x1f4 ; Cylinder low port mov al, 0 ; Cylinder 0 out dx, al mov dx, 0x1f5 ; Cylinder high port mov al, 0 ; The rest of the cylinder 0 out dx, al mov dx, 0x1f7 ; Command port mov al, 0x20 ; Read with retry. out dx, al still_going: in al, dx test al, 8 ; This means the sector buffer requires ;servicing. jz still_going ; Don't continue until the sector buffer ;is ready. mov cx, 512/2 ; One sector /2 because it copies words mov rdi, QWORD buffer mov dx, 0x1f0 ; Data port - data comes in and out of here. rep insw pop rdi mov bl, 0x0F mov esi, buffer call dump mov bl, 0x0A mov esi, end call write pop rdx pop rcx pop rbx pop rax ret