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.
26 # @img - fs image to attach loop device to
27 # @offset - if the image is partitioned, the offset to attach at
29 # sets $LOOP_DEV with the path of the newly attached loop device
35 LOOP_DEV=$(losetup -f)
37 if [ "$offset" != "" ]; then
38 losetup -o "$offset" "$LOOP_DEV" "$img"
40 losetup "$LOOP_DEV" "$img"
44 # @dev - the loop device to detach
50 # @img - image name to create
55 # get the total size by summing all the partition sizes (listed in fstab comments)
56 partition_sizes=`grep '^LABEL=' configs/${CONFIG_TYPE}/fstab-ext3 | \
57 sed 's/.*#[[:space:]]\+\([0-9]\+\)$/\1/' | xargs echo | tr ' ' +`
58 size=$(($partition_sizes))
60 # there's some partition overhead; pad the image so that parted doesn't whine
61 overhead=`echo | awk "{ printf(\"%d\n\", 0.014 * $size); }"`
62 size=$((size + overhead))
64 # first, create a sparse image
65 minus_size=$(($size * 6 / 100))
66 size=$(($size - $minus_size))
67 dd if=/dev/zero of=$img bs=1M count=1 seek=$(($size - 1))
69 # fill in the partition table
70 parted -s "$img" "mklabel msdos"
72 grep '^LABEL=' configs/${CONFIG_TYPE}/fstab-ext3 | \
73 sed 's/.*#[[:space:]]\+\([0-9]\+\)$/\1/' | while read s; do
75 parted -s "$img" "mkpart primary ext2 $prior $end"
78 parted -s "$img" "set 1 boot on"
82 # @mntpt - path to mounted root directory
88 mkdir -p ${mntpt}/boot/grub
89 cp /usr/lib/grub/i386-pc/stage[12] ${mntpt}/boot/grub
90 cp /usr/lib/grub/i386-pc/e2fs_stage1_5 ${mntpt}/boot/grub
92 cat >${mntpt}/boot/grub/menu.lst<<EOF
95 color cyan/blue white/blue
98 label=`sed -ne 's/^LABEL=\(.\+\)[[:space:]]\+\/[[:space:]]\+.*/\1/p' configs/${CONFIG_TYPE}/fstab-ext3`
100 grep -q ' ${mntpt}/boot ' /proc/mounts && prefix=/boot
101 for kern in ${mntpt}/boot/vmlinuz-*; do
102 v=$(basename $kern | sed 's/vmlinuz-//')
103 if [ "${v}" = '*' ]; then
104 echo "*** Error: no kernel images found in /boot!" 1>&2
107 cat >>${mntpt}/boot/grub/menu.lst<<EOF
109 title Debian GNU/Linux, kernel ${v}
111 kernel ${prefix}/vmlinuz-${v} root=LABEL=${label} ro
112 initrd ${prefix}/initrd.img-${v}
115 if [ "$installer_added" = "0" ]; then
117 cat >>${mntpt}/boot/grub/menu.lst<<EOF
119 title Debian GNU/Linux Installer
121 kernel ${prefix}/vmlinuz-${v} root=LABEL=${label} ro installer
122 initrd ${prefix}/initrd.img-${v}
129 # grub-install is pretty broken, so we do this manually
130 geom=`parted -s "$img" "unit chs" "print" | sed -ne 's/geometry: \([0-9]\+\),\([0-9]\+\),\([0-9]\+\)/:\1 \2 \3:/p' | cut -d: -f2`
131 grub --batch --device-map=/dev/null <<EOF
140 # @img - image to create a filesystem on
141 # @root_dir - root directory to populate the fs with
147 # create root mount point
148 mount_point_root=$(mktemp)
149 rm -f $mount_point_root
150 mkdir $mount_point_root
153 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
154 while read name mntpt fstype extra; do
155 partition_start=$(parted -m -s "$img" "unit B" "print" | grep "^$i" | cut -d: -f2 | cut -dB -f1)
156 partition_size=$(parted -m -s "$img" "unit B" "print" | grep "^$i" | cut -d: -f4 | cut -dB -f1)
159 # create the filesystems/swap
160 attach_loop "$img" "$partition_start"
161 if [ "$fstype" = "ext3" ]; then
162 mke2fs -q -b $bs -L "$name" -m0 -j "$LOOP_DEV" $((partition_size / bs))
163 tune2fs -c0 -i0 "$LOOP_DEV" # XXX: this is from OLPC days; do we still want this?
164 elif [ "$fstype" = "ext2" ]; then
165 mke2fs -q -b $bs -L "$name" -m0 "$LOOP_DEV" $((partition_size / bs))
166 tune2fs -c0 -i0 "$LOOP_DEV"
167 elif [ "$fstype" = "swap" ]; then
168 mkswap -L "$name" "$LOOP_DEV" $((partition_size / bs))
170 detach_loop "$LOOP_DEV"
172 # mount the root partition if it's found
173 if [ "$mntpt" = "/" ]; then
174 mount "$img" "${mount_point_root}" -o loop,offset=$partition_start -t $fstype
180 # mount the rest of the partitions (working around /boot coming before /)
181 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
182 while read name mntpt fstype extra; do
184 # / is already mounted
185 if [ "$mntpt" = "/" ]; then
189 # if $mntpt doesn't start with '/', don't mount it
190 if [ "${mntpt##/}" = "$mntpt" ]; then
194 # parted 1.8 added --machine for easier parsing; however,
195 # debian still has 1.7 in unstable.
196 partition_start=$(parted -s "$img" "unit B" "print" | sed -ne "s/^ $i[[:space:]]\+//p" | cut -dB -f1)
198 [ -d "${mount_point_root}${mntpt}" ] || mkdir -p "${mount_point_root}${mntpt}"
199 mount "$img" "${mount_point_root}${mntpt}" -o loop,offset=$partition_start -t $fstype
202 # populate the filesystem
203 cp -ra "$root_dir"/* "$mount_point_root" || true
204 grub_install "$img" "$mount_point_root"
206 # umount the filesystem
207 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
208 while read name mntpt fstype extra; do
210 # don't unmount / yet
211 if [ "$mntpt" = "/" ]; then
215 # if $mntpt doesn't start with '/', it's not mounted
216 if [ "${mntpt##/}" = "$mntpt" ]; then
220 umount "${mount_point_root}${mntpt}"
223 umount "${mount_point_root}"
224 rmdir "${mount_point_root}"
230 echo "Usage: $0 [<options>] <root directory> <img>" 1>&2
233 echo " --config-type <config> directory name in configs/ to use" 1>&2
234 echo " --help display this help screen" 1>&2
244 [ -d ./configs/${CONFIG_TYPE} ] || {
245 echo "Error: can't find directory './configs/${CONFIG_TYPE}/'!" 1>&2
256 if [ "$#" = "1" ]; then
264 if [ "$ROOT_DIR" = "" ]; then
266 echo "*** No root directory specified!" 1>&2
269 if [ "$IMG_NAME" = "" ]; then
271 echo "*** No image name specified!" 1>&2
274 if [ ! -d "$ROOT_DIR" ]; then
276 echo "*** Unable to find root directory!" 1>&2
280 check_for_cmds losetup parted mke2fs tune2fs grub || exit 1
282 # create image's /etc/fstab
283 if [ ! -f ./configs/${CONFIG_TYPE}/fstab-ext3 ]; then
284 echo "*** Unable to find fstab-ext3!" 1>&2
287 sed 's/[[:space:]]#.*//' ./configs/${CONFIG_TYPE}/fstab-ext3 > ${ROOT_DIR}/etc/fstab
289 # TODO: this needs to go into an OFW package; here it's a hack
290 # create image's /boot/olpc.fth
291 if [ -f ./configs/${CONFIG_TYPE}/olpc.fth-ext3 ]; then
292 cp ./configs/${CONFIG_TYPE}/olpc.fth-ext3 ${ROOT_DIR}/boot/olpc.fth
295 create_bootable_img ${IMG_NAME}
296 mk_ext3_fs ${IMG_NAME} ${ROOT_DIR}
298 #mount ${IMG_NAME}.ext3 $MOUNT_POINT -o loop,offset=$OS_PART1_BEGIN -t ext3
299 #cp -r "$ROOT_DIR"/* $MOUNT_POINT