|
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' |