Cannot read data from hard disk

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
ElasticRaven
Posts: 5
Joined: Mon Sep 19, 2011 6:18 pm

Cannot read data from hard disk

Post by ElasticRaven »

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.
Last edited by ElasticRaven on Fri Sep 23, 2011 8:27 pm, edited 1 time in total.
intx13
Member
Member
Posts: 112
Joined: Wed Sep 07, 2011 3:34 pm

Re: Cannot read data from hard disk

Post by intx13 »

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?
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.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Cannot read data from hard disk

Post by gerryg400 »

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?

Any help would be appreciated.
It goes like this

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 ?
User avatar
Combuster
Member
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

Post by Combuster »

Actually the BIOS would do things more like the following:

Code: Select all

do
{
    read_sector();
    sector_count--;
} while (sector_count)
Now see what happens if you pass in sector_count=0 at the start :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
ElasticRaven
Posts: 5
Joined: Mon Sep 19, 2011 6:18 pm

Re: Cannot read data from hard disk

Post by ElasticRaven »

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.

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
I'm calling it with

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
But 'X' gets replaced by 0x0, when it should be replaced by 'E' (since I'm reading an ELF file).
Last edited by ElasticRaven on Fri Sep 23, 2011 8:28 pm, edited 2 times in total.
guyfawkes
Member
Member
Posts: 93
Joined: Mon Jul 18, 2011 9:47 am

Re: Cannot read data from hard disk

Post by guyfawkes »

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
ElasticRaven
Posts: 5
Joined: Mon Sep 19, 2011 6:18 pm

Re: Cannot read data from hard disk

Post by ElasticRaven »

guyfawkes wrote: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
I tried both 0xE0 and 0xA0. The wiki page I linked to says use 0xE0 (it says use 0xA0 for IDENTIFY, though).

EDIT: Figured it out.
danielbj
Member
Member
Posts: 36
Joined: Thu Dec 16, 2010 3:08 pm

Re: Cannot read data from hard disk

Post by danielbj »

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.

Daniel Broder Jensen
UNICORN OS
User avatar
zhiayang
Member
Member
Posts: 368
Joined: Tue Dec 27, 2011 7:57 am
Libera.chat IRC: zhiayang

Re: Cannot read data from hard disk

Post by zhiayang »

There was truly never any more appropriate time for this xkcd to appear.
Image
Post Reply