-
Notifications
You must be signed in to change notification settings - Fork 2
/
bootableusb
executable file
·243 lines (212 loc) · 5.54 KB
/
bootableusb
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#!/bin/bash
#+
# Use this script to create a bootable USB flash drive.
#-
source scripts/mistify-functions.sh
# Where buildmistify settings are maintained.
statedir=$projectdir/.buildmistify
# Default values some of which could be parameterized.
imagesdir=images
stagedir=usb
tmpdir=/tmp
mountdir=$tmpdir/$id/mnt
bootimage=$tmpdir/boot.img
usage () {
cat << EOF
Usage: ./$id [options]
This script installs the Mistify-OS images onto a target drive so that it
can be booted on the target. In most cases this is a USB flashdrive.
WARNING: This is a potentially destructive script which will destroy existing
content on the target device. To help avoid unintended destruction of data
this script first verifies that the target device is a removable device.
Options:
-b|--builddir <dir>
Where to find the target images. This location is read from the
file $statedir/builddir. NOTE: This is normally set by the buildmistify
script.
[builddir=`cat $statedir/builddir`]
-t|--targetdev <device>
The device on which to install the bootable images. This is typically
sdX where X indicates a removable device in the /dev directory. If this
is equal to "default" then this script will scan for removable devices
and use the highest ordered one. e.g. sdd will be used before sdc.
[targetdev=`cat $statedir/targetdev`]
--install
Install onto the target device. Otherwise only create the image.
EOF
}
#+
# Handle the command line options.
#-
a=`getopt -l "\
targetdev:,\
builddir:,\
install,\
help" \
-o "t:b:h" -- "$@"`
if [ $? -gt 0 ]; then
usage
exit 1
fi
eval set -- $a
while [ $# -ge 1 ]; do
case "$1" in
--)
shift
break
;;
-t|--targetdev)
targetdev=$2
shift
;;
-b|--builddir)
builddir=$2
shift
;;
--install)
install=yes
;;
-h|--help)
usage
exit 0
;;
# using getopt should avoid needing this catchall but just in case...
*)
error "Invalid option: $1"
usage
exit 1
;;
esac
shift
done
if [[ $# -ne 0 ]]; then
usage
exit 1
fi
is_removable () {
local _retval=$1
if [ -e "/sys/block/$1/removable" ]; then
r=`cat /sys/block/$1/removable`
if [ "$r" = "1" ]; then
return 0
fi
fi
return 1
}
#+
# Scan for a removable device starting with the highest and working down.
#-
find_removable_device () {
local _retval=$1
for d in sdi sdj sdh sdg sdf sde sdd sdc; do
message "Checking /dev/$d"
if is_removable $d; then
message "Device $d is removable."
eval $_retval=$d
return
fi
done
error "No removable devices found."
exit 1
}
function setup_img() {
[ -d $builddir/$stagedir ] || mkdir $builddir/$stagedir
cp $builddir/$imagesdir/bzImage.buildroot $builddir/$stagedir/bzImage
cp $builddir/$imagesdir/initrd.buildroot $builddir/$stagedir/initrd
}
function syslinux_config() {
#+
# TODO: For now this is simply a copy but in the future may want to use sed
# to customize the syslinux menu using parameters passed to this script
# from the command line.
#-
cp scripts/syslinux.cfg $1
}
function make_usb_img() {
mkdir -p $builddir/$stagedir/syslinux
syslinux_config $builddir/$stagedir/syslinux/syslinux.cfg
_size=`du -ms $builddir/$stagedir | awk '
function ceiling(x)
{
return (x == int(x)) ? x : int(x)+1
}
{printf "%s", ceiling($1/256)*256}
'`
_size=`printf "%sM" $_size`
echo _size=$_size
rm -f $bootimage
truncate -s $_size $bootimage
printf "0,32,b,*\n0,0\n0,0\n0,0\n;\n" | sfdisk $bootimage
run sudo scripts/makediskimage $mountdir $builddir/$stagedir $bootimage
#+
# No longer need root access.
#-
mv $bootimage $builddir/$imagesdir/mistify-usb.img
# TODO: Need to remove the mount directory.
}
message "Creating a bootable USB flashdrive."
#+
# Determine the location of the build directory.
# NOTE: The directory does not need to exist because the Buildroot make will
# create it if necessary.
#-
if [ -z "$builddir" ]; then
if [ -f $statedir/builddir ]; then
builddir=`cat $statedir/builddir`
else
error "No build directory specified."
exit 1
fi
fi
if [ ! -d "$builddir" ]; then
error "The build directory $builddir doesn't exist."
exit 1
fi
message "Build output directory is: $builddir"
#+
# Prepare the target image.
#-
setup_img
make_usb_img
message "USB image file is: $builddir/$imagesdir/mistify-usb.img"
if [ -z "$install" ]; then
exit 0
fi
#+
# Validate the target device.
#-
if [[ "$targetdev" == "default" ]]; then
find_removable_device targetdev
fi
if [ -z "$targetdev" ]; then
if [ -f $statedir/targetdev ]; then
targetdev=`cat $statedir/targetdev`
else
find_removable_device targetdev
fi
fi
if ! is_removable $targetdev; then
error "The target device $targetdev is not removable."
exit 1
fi
#+
# If the device is mounted then don't use it. As a precaution force the user
# to manually unmount it.
#-
if is_mounted /dev/$targetdev; then
error "The target device $targetdev is mounted."
fi
warning "This is destructive. Install onto /dev/$targetdev?"
select yn in "Yes" "No"; do
case $yn in
Yes )
echo $targetdev >$statedir/targetdev
message "Installing to /dev/$targetdev"
run dd if=$builddir/$imagesdir/mistify-usb.img | pv | sudo dd of=/dev/$targetdev
break;;
No )
message "Exiting"
exit 1;;
esac
done
exit 0