]> spindle.queued.net Git - xodist/blob - mkext3.sh
suppress dd(1) stderr
[xodist] / mkext3.sh
1 #!/bin/sh -e
2 #
3 # Copyright © 2008  Andres Salomon <dilinger@queued.net>
4 #
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.
9 #
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.
14 #
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.
18
19 ROOT_SIZE="2048"
20 IMG_LABEL="DebXO"
21 IMG_NAME=""
22 ROOT_DIR=""
23
24 . functions.sh
25
26 # @img - fs image to attach loop device to
27 # @offset - if the image is partitioned, the offset to attach at
28 #
29 # sets $LOOP_DEV with the path of the newly attached loop device
30 attach_loop()
31 {
32         img="$1"
33         offset="$2"
34
35         LOOP_DEV=$(losetup -f)
36
37         if [ "$offset" != "" ]; then
38                 losetup -o "$offset" "$LOOP_DEV" "$img"
39         else
40                 losetup "$LOOP_DEV" "$img"
41         fi
42 }
43
44 # @dev - the loop device to detach
45 detach_loop()
46 {
47         losetup -d "$1"
48 }
49
50 # @img - fs image to mount
51 # @type - fs type to mount
52 # @offset - if the image is partitioned, the offset to mount at
53 #
54 # sets $MOUNT_POINT with the path of the newly created (and mounted) dir
55 mk_mount()
56 {
57         img="$1"
58         type="$2"
59         offset="$3"
60
61         if [ "$offset" != "" ]; then
62                 offset=",offset=$offset"
63         fi
64
65         MOUNT_POINT=$(mktemp)
66         rm -f $MOUNT_POINT
67         mkdir $MOUNT_POINT
68
69         mount "$img" "$MOUNT_POINT" -o loop$offset -t "$type"
70 }
71
72 # @mntpt - directory to umount and delete
73 rm_mount()
74 {
75         umount "$1"
76         rmdir "$1"
77 }
78
79 # @img - image name to create
80 # @size - image size
81 create_bootable_img()
82 {
83         img="$1"
84         size="$2"
85
86         # first, create a sparse image
87         minus_size=$(($size * 6 / 100))
88         size=$(($size - $minus_size))
89         dd if=/dev/zero of=$img bs=1M count=1 seek=$(($size - 1))
90
91         # fill in the partition table
92         parted -s "$img" "mklabel msdos"
93         parted -s "$img" "mkpart primary ext2 0 -1"
94         parted -s "$img" "set 1 boot on"
95 }
96
97 # @img - image name
98 # @mntpt - path to mounted root directory
99 grub_install()
100 {
101         img="$1"
102         mntpt="$2"
103
104         mkdir -p ${mntpt}/boot/grub
105         cp /usr/lib/grub/i386-pc/stage[12] ${mntpt}/boot/grub
106         cp /usr/lib/grub/i386-pc/e2fs_stage1_5 ${mntpt}/boot/grub
107
108         cat >${mntpt}/boot/grub/menu.lst<<EOF
109 default 0
110 timeout 5
111 color cyan/blue white/blue
112
113 title           $IMG_LABEL
114 root            (hd0,0)
115 kernel          /vmlinuz root=LABEL=${IMG_LABEL} ro
116 boot
117 EOF
118
119         # grub-install is pretty broken, so we do this manually
120         geom=`parted -s "$img" "unit chs" "print" | sed -ne 's/geometry: \([0-9]\+\),\([0-9]\+\),\([0-9]\+\)/:\1 \2 \3:/p' | cut -d: -f2`
121         grub --device-map=/dev/null <<EOF
122 device (hd0) $img
123 geometry (hd0) $geom
124 root (hd0,0)
125 setup (hd0)
126 EOF
127
128 }
129
130 # @img - image to create a filesystem on
131 # @label - fs label
132 # @root_dir - root directory to populate the fs with
133 mk_ext3_fs()
134 {
135         img="$1"
136         label="$2"
137         root_dir="$3"
138
139         # parted 1.8 added --machine for easier parsing; however,
140         # debian still has 1.7 in unstable.
141         partition_start=$(parted -s "$img" "unit B" "print" | sed -ne 's/^ 1[[:space:]]\+//p' | cut -dB -f1)
142
143         # create the filesystem
144         attach_loop "$img" "$partition_start"
145         mke2fs -q -L "$label" -m0 -j "$LOOP_DEV"
146         tune2fs -c0 -i0 "$LOOP_DEV"
147         detach_loop "$LOOP_DEV"
148
149         # populate the filesystem
150         mk_mount "$img" "ext3" "$partition_start"
151         cp -ra "$root_dir"/* "$MOUNT_POINT" || true
152         create_fstab "$MOUNT_POINT" "ext3"
153         grub_install "$img" "$MOUNT_POINT"
154         rm_mount "$MOUNT_POINT"
155 }
156
157 usage()
158 {
159         echo "" 1>&2
160         echo "Usage: $0 [<options>] <root directory> <img>" 1>&2
161         echo "" 1>&2
162         echo "Options:" 1>&2
163         echo "  -l <label>    Image label" 1>&2
164         echo "  -s <size>     Root filesystem size (in MB)" 1>&2
165         echo "" 1>&2
166         exit 1
167 }
168
169 while test $# != 0
170 do
171         case $1 in
172         -l)
173                 IMG_LABEL=$2
174                 shift
175                 ;;
176         -s)
177                 ROOT_SIZE=$2
178                 shift
179                 ;;
180         *)
181                 ROOT_DIR="$1"
182                 shift
183                 if [ "$#" = "1" ]; then
184                         IMG_NAME="$1"
185                 fi
186                 ;;
187         esac
188         shift
189 done
190
191 if [ "$ROOT_DIR" = "" ]; then
192         echo "" 1>&2
193         echo "*** No root directory specified!" 1>&2
194         usage
195 fi
196 if [ "$IMG_NAME" = "" ]; then
197         echo "" 1>&2
198         echo "*** No image name specified!" 1>&2
199         usage
200 fi
201 if [ ! -d "$ROOT_DIR" ]; then
202         echo "" 1>&2
203         echo "*** Unable to find root directory!" 1>&2
204         usage
205 fi
206
207 check_for_cmds losetup parted mke2fs tune2fs grub || exit 1
208 create_fstab ${ROOT_DIR} ext3
209 create_ofwboot ${ROOT_DIR} ext3
210
211 create_bootable_img ${IMG_NAME} ${ROOT_SIZE}
212 mk_ext3_fs ${IMG_NAME} ${IMG_LABEL} ${ROOT_DIR}
213
214 #mount ${IMG_NAME}.ext3 $MOUNT_POINT -o loop,offset=$OS_PART1_BEGIN -t ext3
215 #cp -r "$ROOT_DIR"/* $MOUNT_POINT
216 #umount $MOUNT_POINT