Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: src/platform/installer/chromeos_install_functions.sh

Issue 445002: Switch to GPT partition format.
Patch Set: Address adlr comment Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/bin/sh
2
3 # Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 # Shell functions to help create a bootable image or install to a hard disk.
8 # NOTE: Please keep this file dash and busybox compliant.
9
10 # Variables that affect the install process. Set these as desired before
11 # sourcing this file.
12 MBR=${MBR:-/tmp/gpt.mbr}
13 GPT=${GPT:-gpt}
14 STATEFUL_PART_SIZE=${STATEFUL_PART_SIZE:-} # Defaults to automatic computation.
15 SWAP_PART_SIZE=${SWAP_PART_SIZE:-$((1024 * 1024 * 1024))}
16 DEFAULT_STATEFUL_PART_SIZE=${DEFAULT_STATEFUL_PART_SIZE:-$((512 * 1024 * 1024))}
17
18 # Given a path, return the size of the file or device at that path. This
19 # fills in the GET_SIZE_RESULT variable.
20 GET_SIZE_RESULT=
21 get_size() {
22 local path="$1"
23
24 GET_SIZE_RESULT=0
25 if [ -b "$path" ] ; then
26 local device="${path#/dev/}"
27 if [ -f "/sys/block/${device}/size" ] ; then
28 # device must be like 'sdb'
29 GET_SIZE_RESULT=$(cat "/sys/block/${device}/size")
30 else
31 # device must be like 'sdb3'
32 local part="$device"
33 local len=${#part}
34 device=$(printf "%0.$((len - 1))s" $part)
35 GET_SIZE_RESULT=$(cat "/sys/block/${device}/${part}/size")
36 fi
37 GET_SIZE_RESULT=$((GET_SIZE_RESULT * 512))
38 else
39 GET_SIZE_RESULT=$(stat -c%s "$path") # Bytes
40 fi
41 }
42
43 # A dd equivalent that tries to use a large block size.
44 do_copy() {
45 local in="$1" # Input file
46 local out="$2" # Output file
47 local seek_offset="$3" # Offset where to write the data, in bytes.
48 local skip_offset="$4" # Offset from where to read the data, in bytes.
49
50 # We use a 4M output block size
51 local bs=$((4 * 1024 * 1024))
52
53 local skip_count=$((skip_offset / 512))
54
55 # How much initial non-aligned data do we need to copy?
56 local begin_size=$((bs - (seek_offset % bs)))
57 local count=$((begin_size / 512))
58 local seek=$((seek_offset / 512))
59 sudo dd if="$in" of="$out" bs=512 \
60 skip=$skip_count seek=$seek count=$count conv=notrunc
61
62 # Now copy the rest of the data with output aligned at $bs
63 seek=$(( (seek_offset + begin_size) / bs ))
64 sudo dd if="$in" of="$out" ibs=512 obs=$bs \
65 skip=$((skip_count + count)) seek=$seek conv=notrunc
66 }
67
68 # Computes the required install size for the system. This does not include
69 # the stateful partition. The call fills in the SYSTEM_INSTALL_SIZE variable.
70 SYSTEM_INSTALL_SIZE=
71 get_system_install_size() {
72 local rootfs=$1
73 local type=$2 # Either 'minimal' or 'full'
74
75 # Approx space for GPT metadata
76 local gpt_size=$((34 * 1024))
77
78 # Determine the size of one rootfs partition.
79 get_size "$rootfs"
80 local root_size=$GET_SIZE_RESULT
81
82 # A minimal install has just the stateful and system partitions.
83 SYSTEM_INSTALL_SIZE=$((gpt_size + root_size))
84 if [ "$type" = "full" ] ; then
85 # A full install also includes a secondary system partition and swap.
86 SYSTEM_INSTALL_SIZE=$((SYSTEM_INSTALL_SIZE + root_size))
87 SYSTEM_INSTALL_SIZE=$((SYSTEM_INSTALL_SIZE + SWAP_PART_SIZE))
88 fi
89 }
90
91 # Computes the size of the stateful partition. If the STATEFUL_PART_SIZE is
92 # already set then we'll use that, otherwise it will default to the free
93 # space on a block device or a default value if output is to a file.
94 get_stateful_part_size() {
95 local rootfs=$1
96 local dest=$2
97 local type=$3
98
99 if [ -n "$STATEFUL_PART_SIZE" ] ; then
100 return; # Already computed or they set an override value.
101 fi
102 if [ -b "$dest" ] ; then
103 # For a block device, we'll default to using up all free space.
104 get_system_install_size "$rootfs" "$type"
105 get_size "$dest"
106 STATEFUL_PART_SIZE=$((GET_SIZE_RESULT - SYSTEM_INSTALL_SIZE))
107 else
108 # We'll use a default stateful part size.
109 STATEFUL_PART_SIZE=$((DEFAULT_STATEFUL_PART_SIZE))
110 fi
111 }
112
113 # Verifies that it is really OK to install to the destination.
114 do_verify() {
115 local rootfs=$1 # Path to file/device containing the system rootfs
116 local dest=$2 # Path to file/device on which the install will happen
117 local type=$3 # Either 'minimal' or 'full'
118
119 if [ -e "$dest" ] ; then
120 echo "This will erase all data at this destination: $dest"
121 read -p "Are you sure (y/N)? " SURE
122 if [ "$SURE" != "y" ] ; then
123 echo "Ok, better safe than sorry; you answered '$SURE'."
124 exit 1
125 fi
126
127 if [ -b "$dest" ] ; then
128 # Do we have enough room to install on the block device?
129 get_system_install_size "$rootfs" "$type"
130 get_stateful_part_size "$rootfs" "$dest" "$type"
131 local size_needed=$((SYSTEM_INSTALL_SIZE + STATEFUL_PART_SIZE))
132
133 get_size "$dest"
134 local dest_size=$GET_SIZE_RESULT
135 if [ $dest_size -lt $size_needed ] ; then
136 echo "Error: Destination device '$dest' is too small:"
137 echo " ($dest_size vs $size_needed)"
138 exit 1
139 fi
140 fi
141 fi
142 }
143
144 do_cleanup() {
145 sudo losetup -d "$LOOP_DEV"
146 }
147
148 # Given a rootfs, sets up the destination to boot it with proper partitions.
149 install_chromeos() {
150 local rootfs=$1 # Path to file/device containing the system rootfs
151 local dest=$2 # Path to file/device on which to create a bootable install
152 local label_prefix=$3 # Prefix character to use for file system labels
153 local type=$4 # Either 'minimal' or 'full'
154
155 # How big are each of our partitions?
156 get_size "$rootfs"
157 local system_part_size=$GET_SIZE_RESULT # bytes
158 get_stateful_part_size "$rootfs" "$dest" "$type"
159 local stateful_part_size=$STATEFUL_PART_SIZE
160 local swap_part_size=$SWAP_PART_SIZE
161
162 # If we output to a file, then create/truncate it to the proper length.
163 if [ ! -b "$dest" ] ; then
164 get_system_install_size "$rootfs" "$type"
165 local dest_size=$((SYSTEM_INSTALL_SIZE + stateful_part_size))
166 dd if=/dev/zero of="$dest" bs=1 count=1 seek=$((dest_size - 1))
167 fi
168
169 # -- Partitions --
170
171 # What partition should we make bootable by default?
172 local boot_part=
173
174 # Set up GPT partition format
175 sudo dd if=/dev/zero of="$dest" bs=1M count=1 conv=notrunc
176 sudo $GPT create -f "$dest"
177
178 # Add and label all partitions. The current partitioning scheme(s) are very
179 # likely to change. NOTE: The label is not the same as the file system label.
180 if [ "$type" = "minimal" ] ; then
181 # Part Label FS Usage
182 # 1 User Data (ext3/4) Statefule partition
183 # 2 System (ext3/4) Root file system
184 sudo $GPT add -i 1 -s $((stateful_part_size / 512)) -t linux "$dest"
185 sudo $GPT add -i 2 -s $((system_part_size / 512)) -t linux "$dest"
186
187 sudo $GPT label -i 1 -l "User Data" "$dest"
188 sudo $GPT label -i 2 -l "System" "$dest"
189
190 boot_part=2
191 else
192 # Part Label FS Usage
193 # 1 User Data (ext3/4) Statefule partition
194 # 2 Swap swap May be used for swap
195 # 3 System (ext3/4) Root file system
196 # 4 System2 (ext3/4) Root file system (alternate)
197 sudo $GPT add -i 1 -s $((stateful_part_size / 512)) -t linux "$dest"
198 sudo $GPT add -i 2 -s $((swap_size / 512)) -t linux-swap "$dest"
199 sudo $GPT add -i 3 -s $((system_part_size / 512)) -t linux "$dest"
200 sudo $GPT add -i 4 -s $((system_part_size / 512)) -t linux "$dest"
201
202 sudo $GPT label -i 1 -l "User Data" "$dest"
203 sudo $GPT label -i 2 -l "Swap" "$dest"
204 sudo $GPT label -i 3 -l "System" "$dest"
205 sudo $GPT label -i 4 -l "System2" "$dest"
206
207 boot_part=3
208 fi
209
210 # Set up a boot MBR for booting on legacy devices.
211 sudo $GPT boot -b "$MBR" -i $boot_part "$dest"
212
213 # -- System Image --
214
215 # We copy the system image a bit strangely here because we have observed
216 # cases in install to hard disk where people ctrl-c the operation and then
217 # are not longer able to properly boot a USB image. This is because when
218 # booting from USB we set the root device by LABEL, so if you partially
219 # copy the FS here without updating the label then a subsequent USB boot
220 # may try to use the wrong device and fail.
221
222 echo "Copying the system image. This might take a while..."
223 local offset_sectors=$(sudo $GPT -r show -l "$dest" | grep "\"System\"" \
224 | awk '{ print $1 }')
225
226 # Copy first 2 kibibytes of the root image to a temp file, set the label,
227 # and then copy it to the dest.
228 # NOTE: This hack won't work if we stop using an ext based FS
229 local superblock_offset=1024
230 local label_field_offset=120
231 local label_field_length=16
232 local tmp=$(mktemp)
233 sudo dd if="$rootfs" of="$tmp" bs=1024 count=2
234 sudo dd if=/dev/zero of="$tmp" bs=1 \
235 seek=$((superblock_offset + label_field_offset)) \
236 count=$label_field_length conv=notrunc
237 echo -n "${label_prefix}-ROOT" | sudo dd of="$tmp" \
238 seek=$((superblock_offset + label_field_offset)) \
239 bs=1 count=$((label_field_length - 1)) conv=notrunc
240 sudo dd if="$tmp" of="$dest" bs=512 seek=$offset_sectors conv=notrunc
241 rm "$tmp"
242
243 # Copy all but the first 2 kibibytes to the destination now.
244 do_copy "$rootfs" "$dest" $(( (offset_sectors * 512) + 2048)) 2048
245
246 # -- Stateful Partition --
247
248 echo "Formatting the user data partition..."
249 offset=$(sudo $GPT -r show -l "$dest" | grep "\"User Data\"" \
250 | awk '{ print $1 }')
251 LOOP_DEV=$(sudo losetup -f)
252 if [ -z "$LOOP_DEV" ]
253 then
254 echo "No free loop device. Free up a loop device or reboot. exiting."
255 exit 1
256 fi
257
258 trap do_cleanup EXIT
259
260 echo "Creating stateful partition..."
261 sudo losetup -o $((offset * 512)) "$LOOP_DEV" "$dest"
262 sudo mkfs.ext3 -F -b 4096 -L "${label_prefix}-STATE" \
263 "$LOOP_DEV" $((stateful_part_size / 4096))
264 sync
265 sudo losetup -d "$LOOP_DEV"
266 sync
267
268 trap - EXIT
269 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698