How to find the maximum size of a hard disk?
How to find the maximum size of a hard disk?
Using the tutorial on OS Dever for LBA HD access I have created LBA 48 functions to load and save a sector on the hard disk. However, how can I tell how much space is available? Is there any port IO to do this?
Also, am I right in think that trying to access a sector out of bounds results in an out of bounds fault?
Thanks,
Lster
Also, am I right in think that trying to access a sector out of bounds results in an out of bounds fault?
Thanks,
Lster
It easy. Read ATA/ATAPI scpecification.
if disk support LBA48 then
Do comand "READ NATIVE MAX ADDRESS EXT"=$27
Wite comand complete.
Read from registers "LBA Low", "LBA Mid" , "LBA High"
Set HOB to 1. And read again "LBA Low", "LBA Mid" , "LBA High".
Command Block
Control Block
if disk not support LBA48 use
READ NATIVE MAX ADDRESS=0F8h
if disk support LBA48 then
Do comand "READ NATIVE MAX ADDRESS EXT"=$27
Wite comand complete.
Read from registers "LBA Low", "LBA Mid" , "LBA High"
Set HOB to 1. And read again "LBA Low", "LBA Mid" , "LBA High".
Command Block
Code: Select all
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Register | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Error |na |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Sector Count |Reserved |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|LBA Low |HOB=0 |Native max address LBA (7:0) |
|LBA Low |HOB=1 |Native max address LBA (31:24) |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|LBA Mid |HOB=0 |Native max address LBA (15:8) |
|LBA Mid |HOB=1 |Native max address LBA (39:32) |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|LBA High|HOB=0 |Native max address LBA (23:16) |
|LBA High|HOB=1 |Native max address LBA (47:40) |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Device |obs | na | obs | DEV | Reserved |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Status |BSY |DRDY | DF | na | DRQ | na | na | ERR |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
Code: Select all
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Register | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Device Control | HOB | r | r | r | r | SRST| nIEN| 0 |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
READ NATIVE MAX ADDRESS=0F8h
Code: Select all
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Register | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Error |na |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Sector Count |na |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|LBA Low |Native max address LBA (7:0) |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|LBA Mid |Native max address LBA (15:8) |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|LBA High |Native max address LBA (23:16) |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Device |obs | na | obs | DEV | LBA (27:24) |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
|Status |BSY |DRDY | DF | na | DRQ | na | na | ERR |
+---------------+-----+-----+-----+-----+-----+-----+-----+-----+
Yes rightly.Also, am I right in think that trying to access a sector out of bounds results in an out of bounds fault?
Sorry, my bed english. =)
You must use the "READ NATIVE MAX ADDRESS" command with the value of 0xF8. You have to write this value to the COMMAND register of either the Primary or the Secondary IDE controller. The Primary IDE Controller's base port is located at 0x01F0 and the Secondary IDE's base port is at 0x0170.
The offset of the COMMAND register from the base port of either the Primary or the Secondary IDE Controllers is +7. So if you want to find the COMMAND register of the Primary IDE Controller just do this:
0x01F0 + 7 = 0x01F7 = The COMMAND register of the Primary IDE Controller
Now you have to specify which IDE Device on the selected IDE Controller you want to send the "READ NATIVE MAX ADDRESS" to. This is done by setting or clearing the DEV bit in the Device/Head register of the selected IDE Controller. If DEV is 0 then it means DRIVE0 and if it is set, it will be DEV1.
After sending the "READ NATIVE MAX ADDRESS" to the IDE Controller, you will be given the MAX LBA address in various IDE registers like the Sector Number (LBA 0:7) and etc. I recommend that you read the ATA specifications at T13.
Good luck.
The offset of the COMMAND register from the base port of either the Primary or the Secondary IDE Controllers is +7. So if you want to find the COMMAND register of the Primary IDE Controller just do this:
0x01F0 + 7 = 0x01F7 = The COMMAND register of the Primary IDE Controller
Now you have to specify which IDE Device on the selected IDE Controller you want to send the "READ NATIVE MAX ADDRESS" to. This is done by setting or clearing the DEV bit in the Device/Head register of the selected IDE Controller. If DEV is 0 then it means DRIVE0 and if it is set, it will be DEV1.
After sending the "READ NATIVE MAX ADDRESS" to the IDE Controller, you will be given the MAX LBA address in various IDE registers like the Sector Number (LBA 0:7) and etc. I recommend that you read the ATA specifications at T13.
Good luck.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
It my mistake 27 is hexadecimal
Test for error don't add.
Code: Select all
#define DRDY 0x40
#define BSY 0x80
#define HOB 0x80
#define Sector_Count 2
#define LBA_Low 3
#define LBA_Mid 4
#define LBA_High 5
#define Device 6
#define Status 7
#define Command 7
#define Device_Control 2
unsigned int d=0x1F0; //for example
unsigned int dd=0x3F4;
char Dev=0; // 0-Master 1-Slave
char LBA48=0;
unsigned long long Max_LBA;
outportb(d+6, (Dev << 4) + (1 << 6)); //Select Device and set LBA
while (inportb(d+Status) & DRDY == 0) ;
// Test device is ready to do comand
if (LBA48 !=0) {
outportb(d+Command, 0x27); //READ NATIVE MAX ADDRESS EXT
while (inportb(d+Status) & BSY != 0) {};
// wait command completed
Max_LBA = (unsigned long long )inportb(d+LBA_Low);
Max_LBA += (unsigned long long )inportb(d+LBA_Mid) <<8;
Max_LBA += (unsigned long long )inportb(d+LBA_High) <<16;
outportb(dd+Device_Control, HOB); // Set HOB to 1
Max_LBA += (unsigned long long )inportb(d+LBA_Low)<<24;
Max_LBA += (unsigned long long )inportb(d+LBA_Mid) <<32;
Max_LBA += (unsigned long long )inportb(d+LBA_High) <<40;
} else {
outportb(d+Command, 0xF8); //READ NATIVE MAX ADDRESS
while (inportb (d+Status) & BSY != 0) ;
// wait command completed
Max_LBA = (unsigned long long )inportb(d+LBA_Low);
Max_LBA += (unsigned long long )inportb(d+LBA_Mid) <<8;
Max_LBA += (unsigned long long )inportb(d+LBA_High) <<16;
Max_LBA += ((unsigned long long )inportb(d+Device) & 0xF) <<24;
}
Last edited by Pavia on Sun Aug 05, 2007 11:49 am, edited 1 time in total.
Sorry, my bed english. =)
I think there is a problem then - though I can't see what it is. My code gives me huge numbers that I am sure are wrong. I am testing using Qemu so isn't my HD the image file I create? In which case it should only be 234 sectors.
This is my code:
...
It's aim is to use LBA 48 to find the maximum sector for the first HD. I'm confused - what's wrong with my code?
Thank you lots,
Lster
This is my code:
...
It's aim is to use LBA 48 to find the maximum sector for the first HD. I'm confused - what's wrong with my code?
Thank you lots,
Lster
Last edited by Lprogster on Sun Aug 05, 2007 9:54 am, edited 1 time in total.
Hi,
I'm just curious, but did you check if the hard drive actually supports LBA-48? I'd assume that a 117 KB hard disk might not support it....![Wink ;)](./images/smilies/icon_wink.gif)
Cheers,
Brendan
I'm just curious, but did you check if the hard drive actually supports LBA-48? I'd assume that a 117 KB hard disk might not support it....
![Wink ;)](./images/smilies/icon_wink.gif)
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.