Lines 39-50
print_version() {
Link Here
|
39 |
exit |
39 |
exit |
40 |
} |
40 |
} |
41 |
|
41 |
|
|
|
42 |
# Read 32-bit little-endian from GPT header and output its as decimal number. |
43 |
# GPT header begins in the second sector of the disk. $1 is offset. |
44 |
# |
42 |
read_gpt() { |
45 |
read_gpt() { |
43 |
local offset=$(($sector_size + $1)) |
46 |
local offset=$(($sector_size + $1)) |
44 |
dd if="$dev" bs=1 skip=$offset count=4 2>/dev/null | |
47 |
dd if="$dev" bs=1 skip=$offset count=4 2>/dev/null | |
45 |
hexdump '-e"%u"' |
48 |
hexdump '-e"%u"' |
46 |
} |
49 |
} |
47 |
|
50 |
|
|
|
51 |
# Read single byte from partition table element and output its as decimal number. |
52 |
# GPT partition table begins in the third sector of the disk. $1 is offset. |
53 |
# |
48 |
read_entry() { |
54 |
read_entry() { |
49 |
local offset=$(($sector_size * 2 + $1)) |
55 |
local offset=$(($sector_size * 2 + $1)) |
50 |
local x="$(dd if="$dev" bs=1 skip=$offset count=1 2>/dev/null)" |
56 |
local x="$(dd if="$dev" bs=1 skip=$offset count=1 2>/dev/null)" |
Lines 106-118
verbose "Device name: $dev"
Link Here
|
106 |
verbose "Partition number: $partition" |
112 |
verbose "Partition number: $partition" |
107 |
verbose "Sector size: $sector_size" |
113 |
verbose "Sector size: $sector_size" |
108 |
|
114 |
|
|
|
115 |
# |
116 |
# First, 2-bytes MBR-signature at address 510 (end of the first sector) is read. |
117 |
# It should be read as 0x55, 0xAA. |
118 |
# https://en.wikipedia.org/wiki/Master_boot_record#Sector_layout |
119 |
# |
109 |
magic="$(dd if="$dev" bs=2 skip=255 count=1 2>/dev/null | base64)" |
120 |
magic="$(dd if="$dev" bs=2 skip=255 count=1 2>/dev/null | base64)" |
110 |
[ "$magic" = "Vao=" ] || |
121 |
[ "$magic" = "Vao=" ] || |
111 |
fatal "Unknown partition table" |
122 |
fatal "Unknown partition table" |
112 |
|
123 |
|
113 |
magic="$(dd if="$dev" bs=8 skip=64 count=1 2>/dev/null)" |
124 |
# |
|
|
125 |
# Then 8-bytes GPT-signature "EFI PART" is checked at the beginning of the second |
126 |
# sector of the disk. |
127 |
# https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_table_header_(LBA_1) |
128 |
# |
129 |
magic="$(dd if="$dev" bs=1 skip=$sector_size count=8 2>/dev/null)" |
114 |
if [ "$magic" = "EFI PART" ]; then |
130 |
if [ "$magic" = "EFI PART" ]; then |
115 |
partition_table='gpt' |
131 |
partition_table='gpt' |
|
|
132 |
# Number of partition entries, 4 bytes little-endian. |
116 |
magic=$(read_gpt 80) |
133 |
magic=$(read_gpt 80) |
117 |
else |
134 |
else |
118 |
partition_table='msdos' |
135 |
partition_table='msdos' |
Lines 125-140
verbose "Partition table: $partition_table"
Link Here
|
125 |
fatal "invalid partition number: $partition" |
142 |
fatal "invalid partition number: $partition" |
126 |
|
143 |
|
127 |
if [ "$partition_table" = "msdos" ]; then |
144 |
if [ "$partition_table" = "msdos" ]; then |
|
|
145 |
# MBR partition table starts at offset 446. |
146 |
# Each element of the table occupying 16 bytes. |
128 |
magic=$((16 * ($partition - 1) + 446)) |
147 |
magic=$((16 * ($partition - 1) + 446)) |
129 |
magic="$(dd if="$dev" bs=1 skip=$magic count=1 2>/dev/null | base64)" |
148 |
magic="$(dd if="$dev" bs=1 skip=$magic count=1 2>/dev/null | base64)" |
|
|
149 |
# First byte of the element is 0x80 for the boot partition. |
150 |
# https://en.wikipedia.org/wiki/Master_boot_record#PTE |
130 |
[ "$magic" = "gA==" ] || |
151 |
[ "$magic" = "gA==" ] || |
131 |
fatal "partition not bootable" |
152 |
fatal "partition not bootable" |
132 |
mbr_bin='mbr.bin' |
153 |
mbr_bin='mbr.bin' |
133 |
else |
154 |
else |
|
|
155 |
# Size of a single partition entry, 4 bytes little-endian. |
134 |
magic=$(read_gpt 84) |
156 |
magic=$(read_gpt 84) |
|
|
157 |
# Attribute flags (8 bytes little-endian) starts at offset 48 of the entry. |
158 |
# https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries_(LBA_2-33) |
135 |
magic=$(($magic * ($partition - 1) + 48)) |
159 |
magic=$(($magic * ($partition - 1) + 48)) |
|
|
160 |
# We interested only low byte of the attribute flags and only bit "2" (mask 0x04). |
136 |
magic=$(read_entry $magic) |
161 |
magic=$(read_entry $magic) |
137 |
magic=$(($magic & 4)) |
162 |
magic=$(($magic & 4)) |
|
|
163 |
# If the bit "2" of the attribute flags is set, |
164 |
# partition is marked as bootable in the Legacy BIOS. |
138 |
[ "$magic" = "4" ] || |
165 |
[ "$magic" = "4" ] || |
139 |
fatal "partition not bootable" |
166 |
fatal "partition not bootable" |
140 |
mbr_bin='gptmbr.bin' |
167 |
mbr_bin='gptmbr.bin' |