1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
package partition_table_raw;
use diagnostics;
use strict;
use common qw(:common :system :file);
use devices;
use c;
my @fields = qw(active start_head start_sec start_cyl type end_head end_sec end_cyl start size);
my $format = "C8 I2";
my $magic = "\x55\xAA";
my $nb_primary = 4;
my $offset = $common::SECTORSIZE - length($magic) - $nb_primary * common::psizeof($format);
my @MBR_signatures = (
[ 'empty', 0, "\0\0\0\0" ],
[ 'lilo', 0x2, "LILO" ],
[ 'lilo', 0x6, "LILO" ],
[ 'osbs', 0x2, "OSBS" ], #- http://www.prz.tu-berlin.de/~wolf/os-bs.html
[ 'pqmagic', 0xef, "PQV" ],
[ 'BootStar', 0x130, "BootStar:" ],
[ 'DocsBoot', 0x148, 'DocsBoot' ],
[ 'system_commander', 0x1ad, "SYSCMNDRSYS" ],
[ 'Be Os', 0x24, 'Boot Manager' ],
[ 'TimO', 0, 'IBM Thinkpad hibernation partition' ],
[ 'os2', 0x1c2, "\xA" ],
[ 'dos', 0xa0, "\x25\x03\x4E\x02\xCD\x13" ],
[ 'dos', 0x60, "\xBB\x00\x7C\xB8\x01\x02\x57\xCD\x13\x5F\x73\x0C\x33\xC0\xCD\x13" ], #- nt's
[ 'freebsd', 0xC0, "\x00\x30\xE4\xCD\x16\xCD\x19\xBB\x07\x00\xB4" ],
[ 'dummy', 0xAC, "\x0E\xB3\x07\x56\xCD\x10\x5E\xEB" ], #- caldera?
[ 'ranish', 0x100, "\x6A\x10\xB4\x42\x8B\xF4\xCD\x13\x8B\xE5\x73" ],
);
sub typeOfMBR($) { typeFromMagic(devices::make($_[0]), @MBR_signatures) }
sub typeOfMBR_($) { typeFromMagic($_[0], @MBR_signatures) }
sub compute_CHS($$) {
my ($hd, $e) = @_;
my @l = qw(cyl head sec);
@$e{map { "start_$_" } @l} = $e->{start} || $e->{type} ? CHS2rawCHS(sector2CHS($hd, $e->{start})) : (0,0,0);
@$e{map { "end_$_" } @l} = $e->{start} || $e->{type} ? CHS2rawCHS(sector2CHS($hd, $e->{start} + $e->{size} - 1)) : (0,0,0);
1;
}
sub CHS2rawCHS($$$) {
my ($c, $h, $s) = @_;
$c = min($c, 1023); #- no way to have a #cylinder >= 1024
($c & 0xff, $h, $s | ($c >> 2 & 0xc0));
}
# returns (cylinder, head, sector)
sub sector2CHS($$) {
my ($hd, $start) = @_;
my ($s, $h);
($start, $s) = divide($start, $hd->{geom}{sectors});
($start, $h) = divide($start, $hd->{geom}{heads});
($start, $h, $s + 1);
}
sub get_geometry($) {
my ($dev) = @_;
my $g = "";
local *F; sysopen F, $dev, 0 or return;
ioctl(F, c::HDIO_GETGEO(), $g) or return;
my %geom; @geom{qw(heads sectors cylinders start)} = unpack "CCSL", $g;
{ geom => \%geom, totalsectors => $geom{heads} * $geom{sectors} * $geom{cylinders} };
}
|