Cannot read data from hard disk
-
- Posts: 5
- Joined: Mon Sep 19, 2011 6:18 pm
Cannot read data from hard disk
I am trying to load a file (my kernel) from disk. I think I've followed the instructions at http://wiki.osdev.org/ATA_PIO_Mode correctly, but my data is never loaded. Instead, the destination memory space is filled with zeros. I am checking the error bit, etc. but they are always clear.
I am using the 28-bit LBA address method. My file begins at byte 2048 on the drive. I am just reading one sector for now. Am I correct in thinking that my LBA address should be 5 [EDIT: should have been 4 because LBA addresses start with 0 instead of 1] and my sectorcount should be 1?
I am confused by the statement "A sectorcount of 0 means 256 sectors = 128K," to the point that I don't really trust it. 128K seems like a huge amount of data for what appears to be the smallest possible read size. Is there any way that I can read just a few sectors?
Any help would be appreciated.
I am using the 28-bit LBA address method. My file begins at byte 2048 on the drive. I am just reading one sector for now. Am I correct in thinking that my LBA address should be 5 [EDIT: should have been 4 because LBA addresses start with 0 instead of 1] and my sectorcount should be 1?
I am confused by the statement "A sectorcount of 0 means 256 sectors = 128K," to the point that I don't really trust it. 128K seems like a huge amount of data for what appears to be the smallest possible read size. Is there any way that I can read just a few sectors?
Any help would be appreciated.
Last edited by ElasticRaven on Fri Sep 23, 2011 8:27 pm, edited 1 time in total.
Re: Cannot read data from hard disk
A read of 0 sectors wouldn't be very useful, so 0 is reused as the largest read size. So instead of being able to read up to 255 sectors at a time you can read up to 256 sectors at a time. This is common for a lot of IO on a lot of different devices where 0 doesn't make much sense.ElasticRaven wrote:I am confused by the statement "A sectorcount of 0 means 256 sectors = 128K," to the point that I don't really trust it. 128K seems like a huge amount of data for what appears to be the smallest possible read size. Is there any way that I can read just a few sectors?
Re: Cannot read data from hard disk
It goes like thisElasticRaven wrote:I am confused by the statement "A sectorcount of 0 means 256 sectors = 128K," to the point that I don't really trust it. 128K seems like a huge amount of data for what appears to be the smallest possible read size. Is there any way that I can read just a few sectors?
Any help would be appreciated.
Code: Select all
int read_sectors(uint8_t sectorcount) {
if (sectorcount == 0) {
read 256 sectors
}
else {
read sectorcount sectors
}
}
If a trainstation is where trains stop, what is a workstation ?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Cannot read data from hard disk
Actually the BIOS would do things more like the following:
Now see what happens if you pass in sector_count=0 at the start
Code: Select all
do
{
read_sector();
sector_count--;
} while (sector_count)
-
- Posts: 5
- Joined: Mon Sep 19, 2011 6:18 pm
Re: Cannot read data from hard disk
Ok, thanks. So sectorcount makes sense, but what about the LBA address? It's just the sector number from the beginning of the disk, right? I'm still getting a bunch of zeros.
I'm calling it with
But 'X' gets replaced by 0x0, when it should be replaced by 'E' (since I'm reading an ELF file).
Code: Select all
ATARead:
;read bl sectors from primary ATA controller master into [edi]
;starting at LBA [esi]
push edi
push eax
push ecx
push edx
mov dx,0x1F7 ;status register
.busy_loop:
in al,dx ;set AL to status register
and al,10000000b ;check MSB of al (BSY)
jnz .busy_loop ;poll again if BSY=1
mov dx,0x1F7 ;status register
.drdy_loop:
in al,dx ;set al to status register
and al,01000000b ;check 2nd bit of al (DRDY)
jz .drdy_loop ;poll again if DRDY=0
mov dx,0x1F6 ;device/head register
mov ecx,esi ;copy lba address
shr ecx,24
and ecx,0x0F ;highest 4 bits of LBA
mov al,0xE0 ;device 0 (master)
or al,cl ;ORed with highest 4 bits of LBA
out dx,al ;select device
mov dx,0x1F1 ;features/error info register
mov al,0
out dx,al ;clear features/error info register (ignored anyway)
mov dx,0x1F2 ;sector count register
mov al,bl ;sector count
out dx,al ;set sector sount
mov eax,esi ;load lba
mov dx,0x1F3 ;low lba register
out dx,al ;set low lba address
shr eax,8 ;al becomes middle lba address
mov dx,0x1F4 ;middle lba register
out dx,al ;set middle lba address
shr eax,8 ;al becomes high lba address
mov dx,0x1F5 ;high lba register
out dx,al ;set high lba address
mov dx,0x1F7 ;command register
mov al,0x20 ;read sectors command
out dx,al ;send read sectors command
mov dx,0x3F6 ;alternate status register
in al,dx ;wait 100ns
mov dx,0x3F6 ;alternate status register
in al,dx ;wait 100ns
mov dx,0x3F6 ;alternate status register
in al,dx ;wait 100ns
mov dx,0x3F6 ;alternate status register
in al,dx ;wait 100ns
mov dx,0x1F7 ;status register
.bsy_loop2:
in al,dx ;set al to status register
and al,10000000b ;check BSY bit
jnz .bsy_loop2 ;poll again if BSY=1
mov dx,0x1F7 ;status register
.drq_loop:
in al,dx ;set al to status register
and al,00000001b ;check ERR bit
jnz .err ;error
in al,dx ;set al to status register
and al,00001000b ;check DRQ bit
jz .drq_loop ;poll again if DRQ=0
mov dx,0x1F0 ;data register
mov ecx,256d ;number of words to read
cld ;clear direction flag so insw increments edi
rep insw ;read words from data register
jmp .end
.err:
push esi
mov esi,ReadErrorString
call PrintStringVideo32
pop esi
jmp .end
.end:
pop edx
pop ecx
pop eax
pop edi
ret
Code: Select all
mov esi,5 ;sector number
mov edi,0x00010000 ;destination address
mov bl,1 ;sector count
mov byte [edi+1],'X'
call ATARead ;read from disk
mov al,[edi+1]
call PrintCharVideo32
Last edited by ElasticRaven on Fri Sep 23, 2011 8:28 pm, edited 2 times in total.
Re: Cannot read data from hard disk
Should this not be 0xA0
Code: Select all
mov al,0xE0 ;device 0 (master)
or al,cl ;ORed with highest 4 bits of LBA
out dx,al ;select device
-
- Posts: 5
- Joined: Mon Sep 19, 2011 6:18 pm
Re: Cannot read data from hard disk
I tried both 0xE0 and 0xA0. The wiki page I linked to says use 0xE0 (it says use 0xA0 for IDENTIFY, though).guyfawkes wrote:Should this not be 0xA0Code: Select all
mov al,0xE0 ;device 0 (master) or al,cl ;ORed with highest 4 bits of LBA out dx,al ;select device
EDIT: Figured it out.
Re: Cannot read data from hard disk
First of all: I am sorry to bump a four year old thread, but this is the only one I could find, that matches my problem.
The good thing about a forum, is that answers and knowledge is not lost. Not even years after that knowledge has been revealed.
The bad thing is when the answers and solutions are never posted. This is, in my opinion, against the purpose of a forum.
Now I'm reading this thread, knowing that the dear Mr(s). ElasticRaven has the solution to my problem. Unfortunately that very same user is no longer active on this forum, making it rather difficult for me to find him. The last time he paid us a visit was Fri Oct 07, 2011 11:37 am. He might as well be gone forever.
And the worst part?
I WILL NEVER KNOW HIS SECRET.
The good thing about a forum, is that answers and knowledge is not lost. Not even years after that knowledge has been revealed.
The bad thing is when the answers and solutions are never posted. This is, in my opinion, against the purpose of a forum.
Now I'm reading this thread, knowing that the dear Mr(s). ElasticRaven has the solution to my problem. Unfortunately that very same user is no longer active on this forum, making it rather difficult for me to find him. The last time he paid us a visit was Fri Oct 07, 2011 11:37 am. He might as well be gone forever.
And the worst part?
I WILL NEVER KNOW HIS SECRET.
Daniel Broder Jensen
UNICORN OS
Re: Cannot read data from hard disk
There was truly never any more appropriate time for this xkcd to appear.
[nx] kernel: http://github.com/zhiayang/nx