LinuxQuestions.org (/questions/)
-   Slackware (http://www.linuxquestions.org/questions/slackware-14/)
-   -   SOLVED: Trying to "reverse engineer" a calculation: any number hackers out there? (http://www.linuxquestions.org/questions/slackware-14/solved-trying-to-reverse-engineer-a-calculation-any-number-hackers-out-there-468158/)

 drkstr 07-27-2006 04:14 AM

SOLVED: Trying to "reverse engineer" a calculation: any number hackers out there?

Here is the solution for calculating the last sector used in the partition table, usefull for when the number of Heads on the disk is not 255. This is handy if you are ever need to write to the partition table manually (such as in a perl script).

Quote:
 Originally Posted by cwwilson721 For all Newbies reading this thread: Don't forget the following: Messing with partition info can corrupt your data! If you do mess it up, odds are it is unrecoverable without a high degree of skill. Sacrifice a chicken to the hdd gods first. KFC will do it for you for a fee... (Last was done tongue in cheek. You don't need to sacrifice a chicken. Pizza works just as well. However, I've had mixed results w/lasagna. Use at your own risk...)
note: I am not an expert so I can't guarantee this is correct, but it did work for me.

================

first use 'sfdisk -l' to get your disk geometry.

let H = the number of Heads on the disk
let C = the number of cylinders on the disk
let T = 63 (I believe this is a constant)
let L = the Last sector written on the partition table

the equation to find the last sector you should use is as follows:

Code:

let T = 63
let H = 255
let C = the number of cylinders on your disk

h*C*T
let Z =    -----
H*T
then

L = |Z| * H * T

note: |Z| represents "the whole number part of Z" in mathimatical terms.

================

That's all there is to it.

If you want to see how this is derived, read on. Otherwise, happy disk witting!

first, let's find out which sector sfdisk used by dumping the partition table:

Code:

root@lpt:~# sfdisk -d /dev/hda
# partition table of /dev/hda
unit: sectors

/dev/hda1 : start=      63, size= 16595082, Id=83
/dev/hda2 : start= 18555075, size=  1076355, Id=82
/dev/hda3 : start= 16595145, size=  1959930, Id=83
/dev/hda4 : start=        0, size=        0, Id= 0

We can get the last disk used by adding up the total sectors:
63 + 16595082 + 1076355 + 1959930 = Last Sector Used = 19631430

Now let's find the actual number of sectors on the disk:

Code:

root@lpt:~# sfdisk -l /dev/hda | grep Disk
Disk /dev/hda: 19485 cylinders, 16 heads, 63 sectors/track

The total sectors is found with:
C*H*T = 19640880

note the variance between the two (remember this number)
19640880 - 19631430 = 9450 sectors

Now let's also note that the two numbers both share a common factor of the number of Tracks (63)
19640880/T=311760

19631430/T=311610

Hmm, this is interesting. Now lets try getting all of the factors to see what we can come up with.

factor(19631430)
2 * 3^3 * 5 * 7 * 13 * 17 * 47

Lets try and get 3 usefull numbers from this (Tracks, Cylinders, and Heads)
Now we know 63 is a factor so let's pull it out. We can also see 255 as a factor, so let's pull that out as well. From what's left, we can see the geometry that was actually written to the disk 1222 cylinders, 255 heads, and 63 Tracks.
(3^2 * 7)(3 * 5 * 17)(2 * 13 * 47)

This is all well and good, but what if we need to find out the last sector we should write to when it is unknown? So we derive the information we just used into an equation.

In order to figure out the last sector that will be written, we need to find out how many cylinders there are based on a 255 head disk geometry.

Consider the Following proof:

Code:

let S = Total Sectors
let L = Last sector written

S - L
----- = V
(H*T)

or

S - V(H*T) = L

(V represents the variance between S and L in terms of cylinders per H*T)

Since H and T are factors of L, and T is also a factor of S, we could say that

[L/(H*T)] is the whole number part of [S/(H*T)] which we will call |Z|

then we could also say that

S
---  - V = |Z|
H*T

or

S - V(H*T) = |Z|(H*T)

or

L=|Z|(H*T)

Hopefully this will be of some use to someone. I figured since I spent all the time doing this, I might as well share it with anyone who needs it.

regards,
...drkstr

note: everything form here to post # 09 was written before the above text

** original question **
I have been racking my brain over the past 3 hours trying to "reverse engineer" (for lack of a better term) the way sfdisk calculates the last sector it uses in the partition table. Any of you number hackers out there feel like giving me a hand? Here is an example output from a 'sfdisk -d /dev/hda' on my computer.
Code:

/dev/hda1 : start=      63, size= 16595082, Id=83
/dev/hda2 : start= 18555075, size=  1076355, Id=82
/dev/hda3 : start= 16595145, size=  1959930, Id=83
/dev/hda4 : start=        0, size=        0, Id= 0

and here is the disk geometry
Code:

/dev/hda:
19485 cylinders, 16 heads, 63 sectors/track
Units = cylinders of 516096 bytes, blocks of 1024 bytes, counting from 0

What I need to know is how sfdisk comes up with the last sector sfdisk writes to since it is not the last sector of the disk

Now I don't really know a lot about disk geometry so I've just been plugging numbers in the calculator to see if I can reproduce the numbers with an equation.

I've noticed that both the total sectors on the disk, and the last sector written by sfdisk have a common factor of 63 (Number of tracks) Does this have anything to do with how the last sector written to is calculated, or am I just way off? Is it possible to compute the number I need with an equation?

Any input will be greatly appreciated!
...drkstr
** original question **

 synapse 07-27-2006 06:30 AM

Hi

Doesnt the first sector belong to the boot sector and so it is not counted at all?
therefore the sectors will be the last -1

 Randux 07-27-2006 07:46 AM

Hi Aaron, I don't understand what you're asking here. There's a lot of info but the question isn't clear (to me). Please spell out what you are trying to understand.

P.S. You see that sfdisk counts starting from sector 63, right (in the first example you posted) but from 0 in the second. In the first example this means the the first track (sectors 0 - 62, inclusive) is bypassed. This is the MBR, as synapse alluded to, but what he said about sectors - 1 isn't true- it's sectors - 63.

 drkstr 07-27-2006 10:02 AM

sorry, this was a bit confusing. I realize I didn't really explain well what I was trying to do.

What I am need to be able to do is edit the output of the partition table dump (the first example) so I overwrite the existing partition table by piping it back through sfdisk. In order to do this I need to be able to calculate how they come up with each number in the dump. All of them are pretty strait forward except for the "total number of sectors included in the partition table".

note: I know over writing the partition table "live" sounds like a bad idea, but it actually works. I've tested it by using cfdisk to change the partition table, then dumped it with sfdisk and piped it back in. When I was done I was able to restore the partition table back from the original (which I dumped to a file before changing anything). This all worked without rebooting or losing any data.

The very last sector it uses is not (total disk size) - (63 sectors) it is actually (total disk size - 9450 sectors) I strongly belive that the number of sectors used by the partition table can be figured out mathmaticly since it is not an arbitrary number (it can be devided evenly by both the number of heads or the number of tracks).

Quote:
 P.S. You see that sfdisk counts starting from sector 63, right (in the first example you posted) but from 0 in the second. In the first example this means the the first track (sectors 0 - 62, inclusive) is bypassed.
The first example is the actual partition table dumped by sfdisk, where the second example is the total disk size (MBR included).
Quote:
 This is the MBR, as synapse alluded to, but what he said about sectors - 1 isn't true- it's sectors - 63.
But then why is the varience from total sectors written to total sectors on the disk 9450 sectors instead of 63?

thanks for everyones interest!
...drkstr

 drkstr 07-27-2006 12:23 PM

Well I think I might have figured it out after a little bit of sleep.

Sfdisk wrote the partition table by a factor of 255 heads instead of 16.

Sfdisk calculation:
LastSector = 63+16595082+1076355+1959930 = 19631430.
SectersPerTrack = 63.
LastSector / Heads / SectersPerTrack = 1,222. Cylinders

Actual disk geometry (correct terminology?):
SectersPerTrack = 63.
Cylinders = 19485.
ActualSectors = Heads * SectorsPerTrack * Cylinders = 19640880.

When converted to a 255 Head geometry
ActualSectors / 255. / SectersPerTrack = 1222.58823 WrongCylinders… Uh oh!

Therefore sfdisk wrote to the last whole cylinder based on a 255. Head geometry.

To confirm: (WrongCylinders – 1222.) * 63. * 255. = 9450. Sectors

Which is the exact variance I was getting in Sectors.

In order to use the full hard drive space, it looks like I will need to read in the # of heads from the disk, and specify this number before calling sfdisk.

Thanks everyone for the help! Your comments were able to get me thinking in the right direction.

regards,
…drkstr

 Randux 07-27-2006 12:35 PM

Good going. I was going to point out that your second set of numbers was in cyls but your first set was in sectors. You can change this in fdisk (don't know about sfdisk/cfdisk, since I don't use those) by going into "expert" mode.

 drkstr 07-27-2006 01:16 PM

Quote:
 Good going. I was going to point out that your second set of numbers was in cyls but your first set was in sectors. You can change this in fdisk (don't know about sfdisk/cfdisk, since I don't use those) by going into "expert" mode.
So it's possible I wasn't getting any varience at all, just comparing apples to oarenges?

...drkstr

 Randux 07-27-2006 01:34 PM

I'm sorry, I don't have time to go over the calculations at the moment, but I did notice from the two examples you pasted that the units were different. Also I think most people find the geometry defined in terms of 255 heads like you mentioned later. I don't know why it's shown as 16 in the initial example you pasted.

 drkstr 07-27-2006 01:55 PM

Quote:
 I'm sorry, I don't have time to go over the calculations at the moment, but I did notice from the two examples you pasted that the units were different. Also I think most people find the geometry defined in terms of 255 heads like you mentioned later. I don't know why it's shown as 16 in the initial example you pasted.
That's ok, I think I have the calculations pretty much worked out. I'm pretty sure you just confirmed in words what I found in numbers. Which is a big help since I'm always trying to ask why.

I think the problem might have been with the fact that I was working with an old hard drive on a laptop from 2001. The same 'fdisk -l' command run on my server gives the units as 255 Heads which is what led me to think that sfdisk was not using the correct geometry for my disk.

I'm just happy to have it figured out. Now I can get back to writing code again.

...drkstr

 drkstr 07-28-2006 02:27 AM

Looks like I can mathmaticly determain the last sector used by the partition table. I wrote a brief proof in hopes it can be of use to anyone else.

regards,
...drkstr

 Randux 07-28-2006 04:52 AM

Nice job. Maybe put it in lq bookmarks......

 XavierP 07-28-2006 12:30 PM

 gnashley 07-29-2006 07:42 AM

Several things I see:

You have a null number of sectors for the first partition.
The partitions are mixed physically and logically -as if some had been created, then some removed or resized or recreated.

Logical cylinder boundaries. One of the things that sucks about DOS fdisk is that you can't be very specicfic about partition sizes -some sizes are uncreatable. Linux tools are better of course, they'll warn you sometimes like this:
'number of heads/tracks/sectors doesn't match logical cylinder boundaries'

If the point is to 'occupy' all the available space on the disk, then you need to get down to block-size also so you can ask for the proper number of K's for the partition. Most of choose a 'rounded' size like 100MB or 128MB. The logical cylinder boundaries may not match these fiures. When they don't, the last unused sectors are skipped. The next partition starts at a new logical cylinder boundary.

If you want to see how sfdisk or whatever does it you could try reading the sources.

 drkstr 07-29-2006 12:37 PM

Thanks gnashley.

Logical partitions has presented a problem for me which I have chosen not to deal with at the moment. Currently, I will be able to delete a "group" of logical partitions (IE. the primary extended partition), or one of the true primary partitions. Furthermore, the new partitions will only be created on one of the 4 primary slots, and fail if there are not enough available.

Quote:
 If the point is to 'occupy' all the available space on the disk, then you need to get down to block-size also so you can ask for the proper number of K's for the partition.
This will be the focus down the road, but right now, I am just trying to modify the partition table dump with numbers that will be safe to pipe back into sfdisk.

I'm not quite sure I've achieved this yet, but I will find out shortly ;)

thanks!
...drkstr

 cwwilson721 07-29-2006 12:53 PM