17
18
# You should have received a copy of the GNU General Public License
18
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
source "${0%/*}/common-functions.sh"
20
23
DEF_SECTOR_SIZE=512
22
24
base_d=$(dirname $(readlink -f "${0}"))
23
25
PATH="${PATH}:${base_d}"
24
error() { echo "$@" 1>&2; }
26
[ "${DEBUG}" -ge "${1:-0}" ] && shift || return 0;
29
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
31
28
local fname="$1" kname="" size=""
32
29
if [ -b "${fname}" ]; then
51
Usage: ${0##*/} [options] partition-image disk-image
48
Usage: ${0##*/} [options] partition-image grub-efi-tarball architecture disk-image
53
create disk image 'disk-image' with 'partition-image' in a partition
50
Create disk image 'disk-image' with 'partition-image' in a partition
51
inside it. Add grub if requested.
57
54
-G | --grub install grub to disk image mbr
58
55
| --grub1 install grub1 to disk image mbr
56
| --grub-efi install EFI grub to disk image
59
57
-s | --size S create the disk image of size 'S'.
60
58
default is large enough to fit partition-image
61
59
-v | --verbose increase verbosity
64
bad_Usage() { Usage 1>&2; fail "$@"; }
66
63
# converts size suitable for input to resize2fs to bytes
67
64
# s:512 byte sectors, K:kilobytes, M:megabytes, G:gigabytes
78
75
_RET=$((${count}*${unit}))
81
86
short_opts="b:c:Ghs:v"
82
long_opts="grub1,grub,help,size:,verbose"
87
long_opts="grub-efi,grub1,grub,help,size:,verbose"
83
88
getopt_out=$(getopt --name "${0##*/}" \
84
89
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
85
90
eval set -- "${getopt_out}" ||
118
127
fail "failed to get size of $pimg"
121
# end_pad_sectors: room for secondary gpt
123
end_pad=$(($end_pad_sectors*$ssize))
124
front_pad=$((1024*1024))
125
front_pad_sectors=$(($front_pad/$ssize))
126
padding=$(($front_pad+$end_pad))
127
pt_sector_pad=$(($ssize-(${pimg_s}%$ssize)))
128
if [ $pt_sector_pad -eq $ssize ]; then
131
pt_size=$(($pimg_s+$pt_sector_pad))
132
pt_sectors=$(($pt_size/$ssize))
133
tot_size=$(($front_pad+$pt_size+$end_pad))
130
front_pad=$((12*1024*1024))
131
tot_size=$(($front_pad+$pimg_s))
134
132
tot_size_sectors=$(($tot_size/$ssize))
136
134
if [ -n "${size_in}" ]; then
137
135
human2bytes "${size_in}" 1 || fail "failed to convert ${size_in} to bytes"
140
# no size specified, get enough to fit part_img, 1M header and 1M end.
141
size=$((${pimg_s}+$padding+$pt_sector_pad))
138
size=$tot_size_sectors
144
141
if [ -e "$dimg" ]; then
153
150
fail "size of $dimg ($dimg_s) not large enough to fit $size"
156
debug 1 "input is ${pimg_s} bytes ($pt_sectors sectors of $ssize)."
157
debug 1 "target is ${tot_size} bytes ($tot_size_sectors sectors)."
158
debug 1 "padding $front_pad_sectors sectors at front," \
159
"$end_pad_sectors sectors at end."
153
debug 1 "input is ${pimg_s} bytes."
154
debug 1 "target is ${tot_size} bytes."
161
debug 2 "zeroing first $front_pad_sectors sectors $dimg"
162
dd if=/dev/zero of="${dimg}" bs=$ssize "count=${front_pad_sectors}" \
156
debug 2 "create target image"
157
dd if=/dev/zero of="${dimg}" bs=$ssize count=$tot_size_sectors \
164
159
fail "failed to write to ${dimg}"
161
debug 2 "create partitions"
162
sgdisk -n 15:2048:+8M -t 15:ef00 -N 1 $dimg
163
loop_nr=`kpartx -av $dimg | head -n1 | cut -d" " -f3 | cut -d"p" -f2`
166
165
# copy partition image. this writes $pimg bytes even if that is
167
166
# not divivisble by $ssize
168
167
debug 2 "copying ${pimg} to partition in ${dimg}"
169
dd if="$pimg" of="$dimg" seek=${front_pad_sectors} bs=$ssize conv=notrunc \
168
dd if="$pimg" of=/dev/mapper/loop${loop_nr}p1 conv=notrunc \
171
170
fail "failed to write ${pimg} into ${dimg}"
173
# zero any unwritten portion of the final sector
174
leftover=$(($ssize-(${pimg_s}%$ssize)))
175
if [ $pt_sector_pad -ne 0 ]; then
176
debug 2 "finishing final sector with $pt_sector_pad bytes of zeros"
177
dd if=/dev/zero of="$dimg" bs=1 seek=$((${pimg_s}+${front_pad})) \
178
conv=notrunc count=$pt_sector_pad 2>/dev/null ||
179
fail "failed to finish final sector of $pimg"
182
# we've now written front pad + round-sectors. now write end_pad
183
debug 2 "writing final $end_pad_sectors sectors"
184
dd if=/dev/zero "of=$dimg" bs=$ssize \
185
seek=$((($size/$ssize)-${end_pad_sectors})) count=${end_pad_sectors} \
186
conv=notrunc 2>/dev/null ||
187
fail "failed to write final 1M to $pimg"
189
sfdisk_in="${front_pad_sectors},$pt_sectors,L,*"
190
debug 2 "writing partition table to ${dimg} ($sfdisk_in)"
191
sfdisk_out=$(echo "$sfdisk_in" | sfdisk --force --unit=S "${dimg}" 2>&1)
194
error "${sfdisk_out}";
195
fail "failed to create partition table";
198
172
if [ ${grub} -ne 0 ]; then
199
173
debug 2 "invoking part2disk-grubhelper ${dimg}"
200
174
sudo "${phelper}" "${dimg}" ||
188
if [ $grub_efi -ne 0 ]; then
190
x86_64) efiarch=x64;;
191
aarch64) efiarch=aa64;;
194
*) fail "arch $arch without EFI grub"
197
install -d $TMP/tar $TMP/efi $TMP/rootfs
199
mkfs.vfat /dev/mapper/loop${loop_nr}p15
200
mount /dev/mapper/loop${loop_nr}p15 $TMP/efi
201
install -d $TMP/efi/EFI/BOOT $TMP/efi/EFI/ubuntu
202
tar -xf $grub_efi_in -C $TMP/efi/EFI/BOOT
204
mount /dev/mapper/loop${loop_nr}p1 $TMP/rootfs
205
kernelfile=$(cd $TMP/rootfs/boot; ls vmlinu* | head -n1)
206
initrdfile=$(cd $TMP/rootfs/boot; ls initrd.img-* | head -n1)
209
cat >$TMP/efi/EFI/ubuntu/grub.cfg <<EOF
214
if [ x$feature_platform_search_hint = xy ]; then
215
search --no-floppy --label --set=root --hint-bios=hd0,gpt1 --hint-efi=hd0,gpt1 --hint-baremetal=ahci1,gpt1 cirros-rootfs
217
search --no-floppy --label --set=root cirros-rootfs
220
linux /boot/${kernelfile} LABEL=cirros-rootfs ro
221
initrd /boot/${initrdfile}
214
230
error "wrote to ${dimg}"
216
# vi: tabstop=4 expandtab
231
# vi: ts=4 noexpandtab