3 # Copyright © 2008-2009 Andres Salomon <dilinger@collabora.co.uk>
5 # This file is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 # @img - fs image to attach loop device to
28 # @offset - if the image is partitioned, the offset to attach at
30 # sets $LOOP_DEV with the path of the newly attached loop device
36 LOOP_DEV=$(losetup -f)
38 if [ "$offset" != "" ]; then
39 losetup -o "$offset" "$LOOP_DEV" "$img"
41 losetup "$LOOP_DEV" "$img"
45 # @dev - the loop device to detach
51 # @img - image name to create
56 # get the total size by summing all the partition sizes (listed in fstab comments)
57 partition_sizes=`grep '^LABEL=' configs/${CONFIG_TYPE}/fstab-ext3 | \
58 sed 's/.*#[[:space:]]\+\([0-9]\+\)$/\1/' | xargs echo | tr ' ' +`
59 size=$(($partition_sizes))
61 # there's some partition overhead; pad the image so that parted doesn't whine
62 overhead=`echo | awk "{ printf(\"%d\n\", 0.014 * $size); }"`
63 size=$((size + overhead))
65 # first, create a sparse image
66 minus_size=$(($size * 6 / 100))
67 size=$(($size - $minus_size))
68 dd if=/dev/zero of=$img bs=1M count=1 seek=$(($size - 1))
70 # fill in the partition table
71 parted -s "$img" "mklabel msdos"
73 grep '^LABEL=' configs/${CONFIG_TYPE}/fstab-ext3 | \
74 sed 's/.*#[[:space:]]\+\([0-9]\+\)$/\1/' | while read s; do
76 parted -s "$img" "mkpart primary ext2 $prior $end"
79 parted -s "$img" "set 1 boot on"
83 # @mntpt - path to mounted root directory
89 mkdir -p ${mntpt}/boot/grub
90 cp /usr/lib/grub/i386-pc/stage[12] ${mntpt}/boot/grub
91 cp /usr/lib/grub/i386-pc/e2fs_stage1_5 ${mntpt}/boot/grub
93 cat >${mntpt}/boot/grub/menu.lst<<EOF
96 color cyan/blue white/blue
99 label=`sed -ne 's/^LABEL=\(.\+\)[[:space:]]\+\/[[:space:]]\+.*/\1/p' configs/${CONFIG_TYPE}/fstab-ext3`
101 grep -q ' ${mntpt}/boot ' /proc/mounts && prefix=/boot
102 for kern in ${mntpt}/boot/vmlinuz-*; do
103 v=$(basename $kern | sed 's/vmlinuz-//')
104 if [ "${v}" = '*' ]; then
105 echo "*** Error: no kernel images found in /boot!" 1>&2
108 cat >>${mntpt}/boot/grub/menu.lst<<EOF
110 title Debian GNU/Linux, kernel ${v}
112 kernel ${prefix}/vmlinuz-${v} root=LABEL=${label} ro
113 initrd ${prefix}/initrd.img-${v}
116 if [ "$installer_added" = "0" ]; then
118 cat >>${mntpt}/boot/grub/menu.lst<<EOF
120 title Debian GNU/Linux Installer
122 kernel ${prefix}/vmlinuz-${v} root=LABEL=${label} ro installer
123 initrd ${prefix}/initrd.img-${v}
130 # grub-install is pretty broken, so we do this manually
131 geom=`parted -s "$img" "unit chs" "print" | sed -ne 's/geometry: \([0-9]\+\),\([0-9]\+\),\([0-9]\+\)/:\1 \2 \3:/p' | cut -d: -f2`
132 grub --batch --device-map=/dev/null <<EOF
141 # @img - image to create a filesystem on
142 # @root_dir - root directory to populate the fs with
148 # create root mount point
149 mount_point_root=$(mktemp)
150 rm -f $mount_point_root
151 mkdir $mount_point_root
154 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
155 while read name mntpt fstype extra; do
156 partition_start=$(parted -m -s "$img" "unit B" "print" | grep "^$i" | cut -d: -f2 | cut -dB -f1)
157 partition_size=$(parted -m -s "$img" "unit B" "print" | grep "^$i" | cut -d: -f4 | cut -dB -f1)
160 # create the filesystems/swap
161 attach_loop "$img" "$partition_start"
162 if [ "$fstype" = "ext3" ]; then
163 mke2fs -q -b $bs -L "$name" -m0 -j "$LOOP_DEV" $((partition_size / bs))
164 tune2fs -c0 -i0 "$LOOP_DEV" # XXX: this is from OLPC days; do we still want this?
165 elif [ "$fstype" = "ext2" ]; then
166 mke2fs -q -b $bs -L "$name" -m0 "$LOOP_DEV" $((partition_size / bs))
167 tune2fs -c0 -i0 "$LOOP_DEV"
168 elif [ "$fstype" = "swap" ]; then
169 mkswap -L "$name" "$LOOP_DEV" $((partition_size / bs))
171 detach_loop "$LOOP_DEV"
173 # mount the root partition if it's found
174 if [ "$mntpt" = "/" ]; then
175 mount "$img" "${mount_point_root}" -o loop,offset=$partition_start -t $fstype
181 # mount the rest of the partitions (working around /boot coming before /)
182 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
183 while read name mntpt fstype extra; do
185 # / is already mounted
186 if [ "$mntpt" = "/" ]; then
190 # if $mntpt doesn't start with '/', don't mount it
191 if [ "${mntpt##/}" = "$mntpt" ]; then
195 # parted 1.8 added --machine for easier parsing; however,
196 # debian still has 1.7 in unstable.
197 partition_start=$(parted -s "$img" "unit B" "print" | sed -ne "s/^ $i[[:space:]]\+//p" | cut -dB -f1)
199 [ -d "${mount_point_root}${mntpt}" ] || mkdir -p "${mount_point_root}${mntpt}"
200 mount "$img" "${mount_point_root}${mntpt}" -o loop,offset=$partition_start -t $fstype
203 # populate the filesystem
204 cp -ra "$root_dir"/* "$mount_point_root" || true
205 if [ "$SKIP_GRUB" != "y" ]; then
206 grub_install "$img" "$mount_point_root"
209 # umount the filesystem
210 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
211 while read name mntpt fstype extra; do
213 # don't unmount / yet
214 if [ "$mntpt" = "/" ]; then
218 # if $mntpt doesn't start with '/', it's not mounted
219 if [ "${mntpt##/}" = "$mntpt" ]; then
223 umount "${mount_point_root}${mntpt}"
226 umount "${mount_point_root}"
227 rmdir "${mount_point_root}"
233 echo "Usage: $0 [<options>] <root directory> <img>" 1>&2
236 echo " --config-type <config> directory name in configs/ to use" 1>&2
237 echo " --help display this help screen" 1>&2
238 echo " --skip-grub don't install GRUB on image" 1>&2
248 [ -d ./configs/${CONFIG_TYPE} ] || {
249 echo "Error: can't find directory './configs/${CONFIG_TYPE}/'!" 1>&2
263 if [ "$#" = "1" ]; then
271 if [ "$ROOT_DIR" = "" ]; then
273 echo "*** No root directory specified!" 1>&2
276 if [ "$IMG_NAME" = "" ]; then
278 echo "*** No image name specified!" 1>&2
281 if [ ! -d "$ROOT_DIR" ]; then
283 echo "*** Unable to find root directory!" 1>&2
287 check_for_cmds losetup parted mke2fs tune2fs || exit 1
288 if [ "$SKIP_GRUB" != "y" ]; then
289 check_for_cmds grub || exit 1
292 # create image's /etc/fstab
293 if [ ! -f ./configs/${CONFIG_TYPE}/fstab-ext3 ]; then
294 echo "*** Unable to find fstab-ext3!" 1>&2
297 sed 's/[[:space:]]#.*//' ./configs/${CONFIG_TYPE}/fstab-ext3 > ${ROOT_DIR}/etc/fstab
299 # TODO: this needs to go into an OFW package; here it's a hack
300 # create image's /boot/olpc.fth
301 if [ -f ./configs/${CONFIG_TYPE}/olpc.fth-ext3 ]; then
302 cp ./configs/${CONFIG_TYPE}/olpc.fth-ext3 ${ROOT_DIR}/boot/olpc.fth
305 create_bootable_img ${IMG_NAME}
306 mk_ext3_fs ${IMG_NAME} ${ROOT_DIR}
308 #mount ${IMG_NAME}.ext3 $MOUNT_POINT -o loop,offset=$OS_PART1_BEGIN -t ext3
309 #cp -r "$ROOT_DIR"/* $MOUNT_POINT