How to read the data from the first sector of HDD

Hello ,

I would like to write the code which will read and write the data from the all Sectors of the HDD two connected to IDE and two connected to SATA using C as language on Linux OS.In HDD the space is devided into different no. of sectors and as per my knowledge each sector is of 512k in size. iN Linux the file name used for IDE hdd is /dev/hda and for the SATA HDA it is /dva/sda. Further if i want to specify the first partition then the file name would be /dev/hda0.

But i don't know how to address the first sector.Like suppose i want to read the data from the first sector then how to address that.

As per my knowledge there r two ways of addressing of each sector, one is LBA and other is CHS.Can any one please help and suggest the way or code to read the data from the first sector??

Reply to
Nutty
Loading thread data ...

Hello,

An IDE drive is called /dev/hdx, SCSI drives are called /dev/sdx. There x is a letter a-z. SATA drives are recognized as SCSI-drives, as well as USB disks (I'm not sure about firewire, but believe they are also recognized as SCSI drives).

The first partition is called /dev/hdx1 (not zero), the first primary partitions have the numbers 1-4. Logical partitions get number greater than

  1. The first sector of e.g. the first partition on the first IDE disk are the first 512 bytes of /dev/hda1.

Take the first 512 Bytes of /dev/hda. This is the MBR, including the partition table.

I can't program in C, so I can only give you a dd-command (should be part of your distribution).

dd if=/dev/hda of=file bs=512 count=1 takes the first sector of the first IDE disk into "file"

dd if=/dev/hda2 of=file bs=512 count=1 takes the first sector of the second(!) partition of the first IDE disk into "file"

I hope it is understandable and helped a bit.

Regards

Reply to
Sebastian

Hello Sebastian ,

Thanks a lot !!!!

May be i m wrong, but i just wantd to clarify one thing, how many sectors are there in one partition???

Actually i would like to write the C program in order to

  1. Locate the first sector
  2. Read the data from the first sector of HDD ( if it is a used sector ). Then i wanted to save that data into some temp. buffer/file.
  3. Write some new data to that sector.( to check the write operation )
  4. Then read back that data and compare the data with original one that written to. (to check read operation )
  5. Put the original data ( read in the step 2 ) to that sector.
  6. Locate the next sector.......

In the above fashion i would like to test the all the sectors of the entire HDD. In linux each device is treated as a file,now suppose i wat to check all the sectors then how to address each sector in the linux as a file name. Like for first partition the file name should be /dev/hda1. But what for the first sector, second sector........How to address that???

Thanks and Regards, Nutty.

Reply to
Nutty

DO NOT DO THAT!

Modifying sectors (even temporarily) in a mounted Linux filesystem is calling for a major disaster. The kernel may modify the very same sectors as your program, without any notice to your code, and you're going to write incorrect data back.

In the worst case, you're going to shoot holes in the very program you're just running. Think of the system paging your code out between your change write and the corrective write. When the kernel reads your code page back in, to continue execution, it's something entirely different.

Please get a good book on the kernel internals, e.g.

Understanding the Linux Kernel, published by O'Reilly,

and read and understand the virtual memory system before attempting to continue.

--

Tauno Voipio
tauno voipio (at) iki fi
Reply to
Tauno Voipio

The first sector of a disk is always used (the "boot sector" containing the lowest level boot code, the lowest level partition table and other things).

To know if a sector is used, you need to understand all file systems that are used in all partitions of the disk. There are quite a lot different file systems Linux can use, even custom made ones.

You can do this only if a file system that uses that particular partition is not mounted. I don't know whether the Kernel prevents tins (even for admins) otherwise, but if not it will result in a major crash destroying the data in the partition.

-Michael

Reply to
Michael Schnell

Hello,

[...]

Nice I could help :-)

That is written down insiede the partition table (which lies on the first sector of the disk). This is only true for PC platform, I'm not sure about other systems (like Amiga, Atari, whatever).

Be sure (a) to unmount any(!!) filesystem, otherwise you would probably destroy it. I can program neither in C nor am I able to write shell scripts (only "batch" files), but I would try something like this:

(1) i=0 (2) dd if=/dev/hdx of=/tmp/oldsector bs=512 count=1 skip=i if this fails, your disk is defective or end of disk is reached (6) (3) dd if=/tmp/newsector of=/dev/hdx bs=512 count=1 skip=i (4) dd if=/dev/hdx of=/tmp/readsector bs=512 count=1 skip=i (5) dd if=/tmp/oldsector of=/dev/hdx bs=512 count=1 skip=i (6) increment i; jump to (2)

This is a very, very slow way of testing your hard disk. Easier is to use existing hard-disk check tools. Also be ALWAYS sure your program would never aborted, as the data on your disk are destroyed that way, too. And think about disk caching (some intelligent cache algorithm could lead to no sector being written, as the data are still the same)

dd (read its manpage) can read any sector, it uses the arguments if

Reply to
Sebastian

Heck, you guys are spoil sports. How is the guy supposed to learn without trial (and error!).

In the linux device naming system /dev/hda is the raw full, device. You can access this with dd to read and write absolute sectors. It is up to you to decode the MBR-boot sector, partition tables etc. People doing embedded tend to build a file as a "disk image" which then is somehow copied to the embedded "disk" as a means of mastering embedded disk drives.

/dev/hda1 would be the raw partition 1 that sits on /dev/hda likewise /dev/hda2 to /dev/hda63 on ide drives are for partitions 2 to 63. A second hard drive is by tradition /dev/hdb.../dev/hdz etc. Scsi disks are also traditionally named /dev/sda and dev/sda1 to dev/sda16 for the 16 possible scsi disk partitions. With devfs and now udev, people can be much more creative (and obscure) with disk drive names.

Every raw partition will also have a file system for general use under linux - yet more fun decoding in a user program. If you want to completely decode and use a raw hard drive, it is possible and indeed done everytime the linux OS accesses the file system.

Regards, Steve

There is no "x" in my email address.

Reply to
Steve Calfee

Hi Steve,

good to see you here :)

-Michael

Reply to
Michael Schnell

Hello Michael & Steve,

Thanks a lot for ur kind support!!!!!!!!!!!

destroy it.

Can u please clarify on this??

I understand ur point and thanks for the routine but can I use the dd command in my C program, if yes then how to use that??

Steve , can u please clarify this???

Please guide me!!!!!!!!

Thanks & Regards, Nutty

Reply to
Nutty

Linux caches disk content in memory and modifies only the memory if something is written to the disk. The disk is updated (perhaps many minutes) later. So you easily overwrite something Linux just wrote with very old stuff. This is especially true with the file system management information and thus trashes the complete file system.

You can either "call" command line utilities in a C program by the appropriate Kernel API or look up the dd source code and use it in your Program (Forcing this program to be released under GPL).

Please look up the structure of the MBR in the Internet.

-Michael

Reply to
Michael Schnell

Hello Michael , Thanks a lot..... Where to find the the dd source code ??

Can i use the bios_disk() function in the linux. The corresponding Header Flie is Bios.h How to "call" command line utilities in a C program??

Please guide me...

Thanks & Regards, Nutty,

Reply to
Nutty

I have no link right here (at home), but searching the Internet should come up with many locations. (I'd recommend _using_ dd, anyway)

No. Linux is 32 bit and the PCBIOS calls need to be done in a 16 way. Moreover this will not help with the corruption problem at all

Using the appropriate API via the standard C libraries.

Sorry, I have no link right here (at home), but searching the Internet should come up with many locations. Maybe someone else might jump in.

-Michael

Reply to
Michael Schnell

Hello Michael,

Sorry for the delay, actually inbetween, i was working on the serial port diagnostic.

Well, now i again switch over to HDD. On net i got one document related to the IDE controller. specifying the different registers.From that document, i think it is possible to read and write the perticular sector by writing and reading the contents of the registers using the commands "inb" and "outb"

#define HDD_STATUS_REGISTER 0x1F7 #define HDD_SECTOR_NUMBER_REGISTER 0x1F3 #define HDD_SECTOR_COUNT_REGISTER 0x1F2 #define HDD_CYLINDER_HIGH_REGISTER 0x1F5 #define HDD_CYLINDER_LOW_REGISTER 0x1F4 #define HDD_HEAD_REGISTER 0x1F6 #define COMMAND_READ_SECTOR 0x20 /*20H Read sector with retry. NB: 21H = read sector without retry. For this command you have to load the complete circus of cylinder/head/sector first. When the command completes (DRQ goes active) you can read 256 words (16-bits) from the disk's data register.

*/

#define HDD_DATA_REGISTER 0x1F0 #define HDD_DATA_READY 0x08 /*3rd bit of HDD_STATUS_REG*/ #define HDD_BUSY 0x80 /*

7th bit of HDD_STATUS_REG*/ unsigned int lbaAddress; short numSectors; void readSectors( ) { int i,j; unsigned short buff[256];

ioperm(HDD_DATA_REGISTER,7,0);

while((inportb(HDD_STATUS_REGISTER) & HDD_BUSY)); /*Before doing anything with a device you have to wait till it indicates that it is ready (RDY bit in the status register)*/

outportb(HDD_SECTOR_NUMBER_REGISTER,lbaAddress & 0xff ); outportb(HDD_SECTOR_COUNT_REGISTER,numSectors); outportb(HDD_CYLINDER_HIGH_REGISTER,(lbaAddress>>16) & 0xff ); outportb(HDD_CYLINDER_LOW_REGISTER,(lbaAddress>>8) & 0xff ); outportb(HDD_HEAD_REGISTER, 0xE0 | ((lbaAddress>>24) & 0x0f) ); outportb(HDD_CONTROL_REGISTER,COMMAND_READ_SECTOR); for(i=0;i

Reply to
Nutty

Under Linux, you can do:

int fd = open("/dev/hda", O_RDWR); read(fd, buf, count);

No need to access the hardware directly. (you must be root to open /dev/hda)

regards Wolfgang

Reply to
Wolfgang Mües

It's absolutely inappropriate to do something like this.

Hardware access is should be done in Kernel drivers.

If there already are drivers for that purpose you need to use them.

There is a perfectly working IDE driver in any Linux version that can read and write any sector of the disk. So it would be silly to access the hardware of the IDE controller while Linux is running.

What you are suggesting has nothing to do with Linux. So you can't seek help for this here.

I thinks the suggestions provided here are clear and easy enough to do:

- unmount all file systems of the disk - use the hdx driver to read and write whatever you want.

-Michael

Reply to
Michael Schnell

You can't access any hardware from user mode (programs) in Linux, only from Kernel drivers.

-Michael

Reply to
Michael Schnell

Hello Wolfgang,

Thanks a lot!!!!

Actually i do't want to do any thing from the kernal mode, i do't want to do anything with the existing driver and this is one of the client requirement. Actually the device is ready with the driver for all the hardware devices, i have to just write the code to test the hardware without using the driver. That is the reason i m not using the open(), but can u tell under the same condition can i use the open(),read(),write() from the user application layer without touching the existing drivers??

Reply to
Nutty

This is a silly intention in the Linux world. You can _either_ use Linux and do the stuff the Linux way (and seek help here) _or_ not use Linux and access the hardware in any way you want (and seek help elsewhere).

Perhaps you should read a little bit about what Linux is. open(),read(),write() etc are the APIs the drivers provide for user space applications. So if doing one of them, you are accessing a driver that is installed in the running Linux system.

-Michael

Reply to
Michael Schnell

This seems silly to me.

Do you want to test the hardware, or do you want to test the driver?

If you want to test the hardware, there is no cause to not use the driver.

If you want to test the driver, you have to do very different testing procedures, including code analysis.

regards

Wolfgang

Reply to
Wolfgang Mües

Not strictly true. I've written user land software to access the "lpt" port on a "stardard" PC, and much code to access peripherals on various non-IA86 based SBCs.

However the sentiment is correct - your really shouldn't do this unless you have to. There are usually restrictions in place to prevent you doing it accidently.

Reply to
Jim Jackson

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.