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
97 label=`sed -ne 's/^LABEL=\(.\+\)[[:space:]]\+\/[[:space:]]\+.*/\1/p' configs/${CONFIG_TYPE}/fstab-ext3`
99 grep -q ' ${mntpt}/boot ' /proc/mounts && prefix=/boot
100 for kern in ${mntpt}/boot/vmlinuz-*; do
101 v=$(basename $kern | sed 's/vmlinuz-//')
102 if [ "${v}" = '*' ]; then
103 echo "*** Error: no kernel images found in /boot!" 1>&2
106 cat >>${mntpt}/boot/grub/menu.lst<<EOF
108 title Debian GNU/Linux, kernel ${v}
110 kernel ${prefix}/vmlinuz-${v} root=LABEL=${label} ro
111 initrd ${prefix}/initrd.img-${v}
116 # grub-install is pretty broken, so we do this manually
117 geom=`parted -s "$img" "unit chs" "print" | sed -ne 's/geometry: \([0-9]\+\),\([0-9]\+\),\([0-9]\+\)/:\1 \2 \3:/p' | cut -d: -f2`
118 grub --device-map=/dev/null <<EOF
127 # @img - image to create a filesystem on
128 # @root_dir - root directory to populate the fs with
134 # create root mount point
135 mount_point_root=$(mktemp)
136 rm -f $mount_point_root
137 mkdir $mount_point_root
140 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
141 while read name mntpt fstype extra; do
142 partition_start=$(parted -m -s "$img" "unit B" "print" | grep "^$i" | cut -d: -f2 | cut -dB -f1)
143 partition_size=$(parted -m -s "$img" "unit B" "print" | grep "^$i" | cut -d: -f4 | cut -dB -f1)
146 # create the filesystems/swap
147 attach_loop "$img" "$partition_start"
148 if [ "$fstype" = "ext3" ]; then
149 mke2fs -q -b $bs -L "$name" -m0 -j "$LOOP_DEV" $((partition_size / bs))
150 tune2fs -c0 -i0 "$LOOP_DEV" # XXX: this is from OLPC days; do we still want this?
151 elif [ "$fstype" = "ext2" ]; then
152 mke2fs -q -b $bs -L "$name" -m0 "$LOOP_DEV" $((partition_size / bs))
153 tune2fs -c0 -i0 "$LOOP_DEV"
154 elif [ "$fstype" = "swap" ]; then
155 mkswap -L "$name" "$LOOP_DEV" $((partition_size / bs))
157 detach_loop "$LOOP_DEV"
159 # mount the root partition if it's found
160 if [ "$mntpt" = "/" ]; then
161 mount "$img" "${mount_point_root}" -o loop,offset=$partition_start -t $fstype
167 # mount the rest of the partitions (working around /boot coming before /)
168 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
169 while read name mntpt fstype extra; do
171 # / is already mounted
172 if [ "$mntpt" = "/" ]; then
176 # if $mntpt doesn't start with '/', don't mount it
177 if [ "${mntpt##/}" = "$mntpt" ]; then
181 # parted 1.8 added --machine for easier parsing; however,
182 # debian still has 1.7 in unstable.
183 partition_start=$(parted -s "$img" "unit B" "print" | sed -ne "s/^ $i[[:space:]]\+//p" | cut -dB -f1)
185 [ -d "${mount_point_root}${mntpt}" ] || mkdir -p "${mount_point_root}${mntpt}"
186 mount "$img" "${mount_point_root}${mntpt}" -o loop,offset=$partition_start -t $fstype
189 # populate the filesystem
190 cp -ra "$root_dir"/* "$mount_point_root" || true
191 grub_install "$img" "$mount_point_root"
193 # umount the filesystem
194 sed -ne 's/^LABEL=//p' configs/${CONFIG_TYPE}/fstab-ext3 | \
195 while read name mntpt fstype extra; do
197 # don't unmount / yet
198 if [ "$mntpt" = "/" ]; then
202 # if $mntpt doesn't start with '/', it's not mounted
203 if [ "${mntpt##/}" = "$mntpt" ]; then
207 umount "${mount_point_root}${mntpt}"
210 umount "${mount_point_root}"
211 rmdir "${mount_point_root}"
217 echo "Usage: $0 [<options>] <root directory> <img>" 1>&2
220 echo " --config-type <config> directory name in configs/ to use" 1>&2
221 echo " --help display this help screen" 1>&2
231 [ -d ./configs/${CONFIG_TYPE} ] || {
232 echo "Error: can't find directory './configs/${CONFIG_TYPE}/'!" 1>&2
243 if [ "$#" = "1" ]; then
251 if [ "$ROOT_DIR" = "" ]; then
253 echo "*** No root directory specified!" 1>&2
256 if [ "$IMG_NAME" = "" ]; then
258 echo "*** No image name specified!" 1>&2
261 if [ ! -d "$ROOT_DIR" ]; then
263 echo "*** Unable to find root directory!" 1>&2
267 check_for_cmds losetup parted mke2fs tune2fs grub || exit 1
269 # create image's /etc/fstab
270 if [ ! -f ./configs/${CONFIG_TYPE}/fstab-ext3 ]; then
271 echo "*** Unable to find fstab-ext3!" 1>&2
274 sed 's/[[:space:]]#.*//' ./configs/${CONFIG_TYPE}/fstab-ext3 > ${ROOT_DIR}/etc/fstab
276 # TODO: this needs to go into an OFW package; here it's a hack
277 # create image's /boot/olpc.fth
278 if [ -f ./configs/${CONFIG_TYPE}/olpc.fth-ext3 ]; then
279 cp ./configs/${CONFIG_TYPE}/olpc.fth-ext3 ${ROOT_DIR}/boot/olpc.fth
282 create_bootable_img ${IMG_NAME}
283 mk_ext3_fs ${IMG_NAME} ${ROOT_DIR}
285 #mount ${IMG_NAME}.ext3 $MOUNT_POINT -o loop,offset=$OS_PART1_BEGIN -t ext3
286 #cp -r "$ROOT_DIR"/* $MOUNT_POINT