blob: 0e84f92a49c70a50f0034bc5b3992888b6c70636 [file] [log] [blame]
Bill Richardsoneff5b062010-03-30 14:17:34 -07001# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4#
5# This contains common constants and functions for installer scripts. This must
6# evaluate properly for both /bin/bash and /bin/sh, since it's used both to
7# create the initial image at compile time and to install or upgrade a running
8# image.
9
Bill Richardson40238cd2010-04-16 18:00:53 -070010# Here are the GUIDs we'll be using to identify various partitions. NOTE: The
11# first three fields are byte-reversed to work around a bug in our gpt tool.
12# We'll be replacing that tool with a new one, so it's easier to just work
13# around the bug for now.
14DATA_GUID='a2a0d0eb-e5b9-3344-87c0-68b6b72699c7'
15KERN_GUID='5d2a3afe-324f-a741-b725-accc3285a309'
16ROOTFS_GUID='02e2b83c-7e3b-dd47-8a3c-7ff2a13cfcec'
Bill Richardsoneff5b062010-03-30 14:17:34 -070017ESP_GUID='28732ac1-1ff8-d211-ba4b-00a0c93ec93b'
Bill Richardson40238cd2010-04-16 18:00:53 -070018FUTURE_GUID='3d750a2e-489e-b043-8337-b15192cb1b5e'
Bill Richardsoneff5b062010-03-30 14:17:34 -070019
20
21# The GPT tables describe things in terms of 512-byte sectors, but some
22# filesystems prefer 4096-byte blocks. These functions help with alignment
23# issues.
24
25# This returns the size of a file or device in 512-byte sectors, rounded up if
26# needed.
27# Invoke as: subshell
28# Args: FILENAME
29# Return: whole number of sectors needed to fully contain FILENAME
30numsectors() {
Jie Sun1f9d4122010-04-12 17:04:36 -070031 if [ -b "${1}" ]; then
Bill Richardsoneff5b062010-03-30 14:17:34 -070032 dev=${1##*/}
Jie Sun1f9d4122010-04-12 17:04:36 -070033 if [ -e /sys/block/$dev/size ]; then
34 cat /sys/block/$dev/size
35 else
36 part=${1##*/}
37 block=$(get_block_dev_from_partition_dev "${1}")
38 block=${block##*/}
39 cat /sys/block/$block/$part/size
40 fi
41 else
Bill Richardsoneff5b062010-03-30 14:17:34 -070042 local bytes=$(stat -c%s "$1")
43 local sectors=$(( $bytes / 512 ))
44 local rem=$(( $bytes % 512 ))
45 if [ $rem -ne 0 ]; then
46 sectors=$(( $sectors + 1 ))
47 fi
48 echo $sectors
Jie Sun1f9d4122010-04-12 17:04:36 -070049 fi
Bill Richardsoneff5b062010-03-30 14:17:34 -070050}
51
Bill Richardsond6b71b02010-04-14 12:46:14 -070052# Round a number of 512-byte sectors up to an integral number of 2Mb
53# blocks. Divisor is 2 * 1024 * 1024 / 512 == 4096.
Bill Richardsoneff5b062010-03-30 14:17:34 -070054# Invoke as: subshell
55# Args: SECTORS
56# Return: Next largest multiple-of-8 sectors (ex: 4->8, 33->40, 32->32)
57roundup() {
58 local num=$1
Bill Richardsond6b71b02010-04-14 12:46:14 -070059 local div=${2:-4096}
60 local rem=$(( $num % $div ))
Bill Richardsoneff5b062010-03-30 14:17:34 -070061
Andrew de los Reyes344709b2010-04-05 10:49:08 -070062 if [ $rem -ne 0 ]; then
Bill Richardsond6b71b02010-04-14 12:46:14 -070063 num=$(($num + $div - $rem))
Bill Richardsoneff5b062010-03-30 14:17:34 -070064 fi
65 echo $num
66}
67
Bill Richardsond6b71b02010-04-14 12:46:14 -070068# Truncate a number of 512-byte sectors down to an integral number of 2Mb
69# blocks. Divisor is 2 * 1024 * 1024 / 512 == 4096.
Bill Richardsoneff5b062010-03-30 14:17:34 -070070# Invoke as: subshell
71# Args: SECTORS
72# Return: Next smallest multiple-of-8 sectors (ex: 4->0, 33->32, 32->32)
73rounddown() {
74 local num=$1
Bill Richardsond6b71b02010-04-14 12:46:14 -070075 local div=${2:-4096}
76 local rem=$(( $num % $div ))
Bill Richardsoneff5b062010-03-30 14:17:34 -070077
Andrew de los Reyes344709b2010-04-05 10:49:08 -070078 if [ $rem -ne 0 ]; then
Bill Richardsoneff5b062010-03-30 14:17:34 -070079 num=$(($num - $rem))
80 fi
81 echo $num
82}
83
robotboya7684292010-04-21 14:46:00 -070084# Locate the gpt tool. It should already be installed in the build chroot,
85# but some of these functions may be invoked outside the chroot (by
Bill Richardsoneff5b062010-03-30 14:17:34 -070086# image_to_usb or similar), so we need to find it.
robotboya7684292010-04-21 14:46:00 -070087GPT=""
Yusuke Satod55cea92010-04-21 10:46:59 +090088
robotboya7684292010-04-21 14:46:00 -070089locate_gpt() {
90 if [ -z "$GPT" ]; then
91 GPT=$(which gpt 2>/dev/null) || /bin/true
92 if [ -z "$GPT" ]; then
93 if [ -x "${DEFAULT_CHROOT_DIR:-}/usr/bin/gpt" ]; then
94 GPT="${DEFAULT_CHROOT_DIR:-}/usr/bin/gpt"
95 else
96 echo "can't find gpt tool" 1>&2
97 exit 1
98 fi
99 fi
100 fi
101}
Bill Richardsoneff5b062010-03-30 14:17:34 -0700102
103# This installs a GPT into the specified device or file, using the given
Andrew de los Reyes31e39f12010-04-01 15:24:21 -0700104# components. If the target is a block device or the FORCE_FULL arg is "true"
105# we'll do a full install. Otherwise, it'll be just enough to boot.
Bill Richardsoneff5b062010-03-30 14:17:34 -0700106# Invoke as: command (not subshell)
Bill Richardson13dbcf22010-04-06 15:00:10 -0700107# Args: TARGET ROOTFS_IMG KERNEL_IMG STATEFUL_IMG PMBRCODE ESP_IMG FORCE_FULL
Bill Richardsoneff5b062010-03-30 14:17:34 -0700108# Return: nothing
109# Side effects: Sets these global variables describing the GPT partitions
Bill Richardsond6b71b02010-04-14 12:46:14 -0700110# (all units are 512-byte sectors):
111# NUM_ESP_SECTORS
Bill Richardsoneff5b062010-03-30 14:17:34 -0700112# NUM_KERN_SECTORS
Bill Richardsond6b71b02010-04-14 12:46:14 -0700113# NUM_OEM_SECTORS
114# NUM_RESERVED_SECTORS
Bill Richardsoneff5b062010-03-30 14:17:34 -0700115# NUM_ROOTFS_SECTORS
116# NUM_STATEFUL_SECTORS
Bill Richardson13dbcf22010-04-06 15:00:10 -0700117# START_ESP
Bill Richardsond6b71b02010-04-14 12:46:14 -0700118# START_KERN_A
119# START_KERN_B
120# START_OEM
121# START_RESERVED
122# START_ROOTFS_A
123# START_ROOTFS_B
124# START_STATEFUL
Bill Richardsoneff5b062010-03-30 14:17:34 -0700125install_gpt() {
126 local outdev=$1
127 local rootfs_img=$2
128 local kernel_img=$3
129 local stateful_img=$4
130 local pmbrcode=$5
Bill Richardson13dbcf22010-04-06 15:00:10 -0700131 local esp_img=$6
132 local force_full="${7:-}"
Tan Gao19a0fcf2010-05-19 14:19:55 -0700133 local recovery="${8:-}"
Bill Richardsoneff5b062010-03-30 14:17:34 -0700134
135 # The gpt tool requires a fixed-size target to work on, so we may have to
136 # create a file of the appropriate size. Let's figure out what that size is
Bill Richardsond6b71b02010-04-14 12:46:14 -0700137 # now. The full partition layout will look something like this (indented
138 # lines indicate reserved regions that do not have any useful content at the
139 # moment).
Bill Richardsoneff5b062010-03-30 14:17:34 -0700140 #
141 # PMBR (512 bytes)
142 # Primary GPT Header (512 bytes)
143 # Primary GPT Table (16K)
Bill Richardsond6b71b02010-04-14 12:46:14 -0700144 # Kernel C (placeholder for future use only) partition 6
145 # Rootfs C (placeholder for future use only) partition 7
146 # future use partition 9
147 # future use partition 10
148 # future use partition 11
Bill Richardsoneff5b062010-03-30 14:17:34 -0700149 # Kernel A partition 2
150 # Kernel B partition 4
Bill Richardsond6b71b02010-04-14 12:46:14 -0700151 # OEM Customization (16M) partition 8
152 # reserved space (64M)
153 # EFI System Partition (temporary) partition 12
Bill Richardsoneff5b062010-03-30 14:17:34 -0700154 # Stateful partition (as large as possible) partition 1
155 # Rootfs B partition 5
156 # Rootfs A partition 3
157 # Secondary GPT Table (16K)
158 # Secondary GPT Header (512 bytes)
159 #
160 # Please refer to the official ChromeOS documentation for the details and
161 # explanation behind the layout and partition numbering scheme. The short
Bill Richardsond6b71b02010-04-14 12:46:14 -0700162 # version is that 1) we want to avoid ever changing the purpose or number of
163 # an existing partition, 2) we want to be able to add new partitions later
164 # without breaking current scripts, and 3) we may someday need to increase
165 # the size of the rootfs during an upgrade, which means shrinking the size of
166 # the stateful partition on a live system.
Bill Richardsoneff5b062010-03-30 14:17:34 -0700167 #
Bill Richardsond6b71b02010-04-14 12:46:14 -0700168 # The EFI GPT spec requires that all valid partitions be at least one sector
169 # in size, and non-overlapping.
Bill Richardsoneff5b062010-03-30 14:17:34 -0700170
171 # Here are the size limits that we're currently requiring
172 local max_kern_sectors=32768 # 16M
173 local max_rootfs_sectors=2097152 # 1G
Bill Richardsond6b71b02010-04-14 12:46:14 -0700174 local max_oem_sectors=32768 # 16M
Bill Richardsoneff5b062010-03-30 14:17:34 -0700175 local max_reserved_sectors=131072 # 64M
Bill Richardson13dbcf22010-04-06 15:00:10 -0700176 local max_esp_sectors=32768 # 16M
Bill Richardsoneff5b062010-03-30 14:17:34 -0700177 local min_stateful_sectors=262144 # 128M, expands to fill available space
178
179 local num_pmbr_sectors=1
180 local num_gpt_hdr_sectors=1
Bill Richardsond6b71b02010-04-14 12:46:14 -0700181 local num_gpt_table_sectors=32 # 16K
Bill Richardsoneff5b062010-03-30 14:17:34 -0700182 local num_footer_sectors=$(($num_gpt_hdr_sectors + $num_gpt_table_sectors))
183 local num_header_sectors=$(($num_pmbr_sectors + $num_footer_sectors))
184
Bill Richardsond6b71b02010-04-14 12:46:14 -0700185 # In order to align to a 4096-byte boundary, there should be several empty
186 # sectors available following the header. We'll pack the single-sector-sized
187 # unused partitions in there.
188 local start_kern_c=$(($num_header_sectors))
189 local num_kern_c_sectors=1
190 local start_rootfs_c=$(($start_kern_c + 1))
191 local num_rootfs_c_sectors=1
192 local start_future_9=$(($start_rootfs_c + 1))
193 local num_future_sectors=1
194 local start_future_10=$(($start_future_9 + 1))
195 local start_future_11=$(($start_future_10 + 1))
196
197 local start_useful=$(roundup $(($start_future_11 + 1)))
Bill Richardsoneff5b062010-03-30 14:17:34 -0700198
robotboya7684292010-04-21 14:46:00 -0700199 locate_gpt
200
Bill Richardsoneff5b062010-03-30 14:17:34 -0700201 # What are we doing?
Andrew de los Reyes76658f02010-04-02 15:17:54 -0700202 if [ -b "$outdev" -o "$force_full" = "true" ]; then
Bill Richardsoneff5b062010-03-30 14:17:34 -0700203 # Block device, need to be root.
Andrew de los Reyes76658f02010-04-02 15:17:54 -0700204 if [ -b "$outdev" ]; then
Andrew de los Reyes31e39f12010-04-01 15:24:21 -0700205 local sudo=sudo
206 else
207 local sudo=""
208 fi
Bill Richardsoneff5b062010-03-30 14:17:34 -0700209
210 # Full install, use max sizes and create both A & B images.
211 NUM_KERN_SECTORS=$max_kern_sectors
212 NUM_ROOTFS_SECTORS=$max_rootfs_sectors
Bill Richardsond6b71b02010-04-14 12:46:14 -0700213 NUM_OEM_SECTORS=$max_oem_sectors
Bill Richardson13dbcf22010-04-06 15:00:10 -0700214 NUM_ESP_SECTORS=$max_esp_sectors
Bill Richardsoneff5b062010-03-30 14:17:34 -0700215 NUM_RESERVED_SECTORS=$max_reserved_sectors
216
217 # Where do things go?
218 START_KERN_A=$start_useful
Bill Richardsond6b71b02010-04-14 12:46:14 -0700219 local num_kern_a_sectors=$NUM_KERN_SECTORS
Bill Richardsoneff5b062010-03-30 14:17:34 -0700220 START_KERN_B=$(($START_KERN_A + $NUM_KERN_SECTORS))
Bill Richardsond6b71b02010-04-14 12:46:14 -0700221 local num_kern_b_sectors=$NUM_KERN_SECTORS
222 START_OEM=$(($START_KERN_B + $NUM_KERN_SECTORS))
223 START_RESERVED=$(($START_OEM + $NUM_OEM_SECTORS))
224 START_ESP=$(($START_RESERVED + $NUM_RESERVED_SECTORS))
225 START_STATEFUL=$(($START_ESP + $NUM_ESP_SECTORS))
Bill Richardsoneff5b062010-03-30 14:17:34 -0700226
227 local total_sectors=$(numsectors $outdev)
228 local start_gpt_footer=$(($total_sectors - $num_footer_sectors))
229 local end_useful=$(rounddown $start_gpt_footer)
230
231 START_ROOTFS_A=$(($end_useful - $NUM_ROOTFS_SECTORS))
Bill Richardsond6b71b02010-04-14 12:46:14 -0700232 local num_rootfs_a_sectors=$NUM_ROOTFS_SECTORS
Bill Richardsoneff5b062010-03-30 14:17:34 -0700233 START_ROOTFS_B=$(($START_ROOTFS_A - $NUM_ROOTFS_SECTORS))
Bill Richardsond6b71b02010-04-14 12:46:14 -0700234 local num_rootfs_b_sectors=$NUM_ROOTFS_SECTORS
Bill Richardsoneff5b062010-03-30 14:17:34 -0700235
236 NUM_STATEFUL_SECTORS=$(($START_ROOTFS_B - $START_STATEFUL))
237 else
238 # Just a local file.
239 local sudo=
240
Bill Richardsond6b71b02010-04-14 12:46:14 -0700241 # We're just going to fill partitions 1, 2, 3, 8, and 12. The others will
242 # be present but as small as possible. The disk layout isn't crucial here,
243 # because we won't be able to upgrade this image in-place as it's only for
244 # installation purposes.
Bill Richardsoneff5b062010-03-30 14:17:34 -0700245 NUM_STATEFUL_SECTORS=$(roundup $(numsectors $stateful_img))
Bill Richardsond6b71b02010-04-14 12:46:14 -0700246 NUM_KERN_SECTORS=$(roundup $(numsectors $kernel_img))
247 local num_kern_a_sectors=$NUM_KERN_SECTORS
248 local num_kern_b_sectors=1
249 NUM_ROOTFS_SECTORS=$(roundup $(numsectors $rootfs_img))
250 local num_rootfs_a_sectors=$NUM_ROOTFS_SECTORS
251 local num_rootfs_b_sectors=1
252 NUM_OEM_SECTORS=$max_oem_sectors
Bill Richardson13dbcf22010-04-06 15:00:10 -0700253 NUM_ESP_SECTORS=$(roundup $(numsectors $esp_img))
Bill Richardsond6b71b02010-04-14 12:46:14 -0700254 NUM_RESERVED_SECTORS=1
Bill Richardsoneff5b062010-03-30 14:17:34 -0700255
Tan Gao19a0fcf2010-05-19 14:19:55 -0700256 # For recovery image, use max sizes and create both A & B images
257 if [ ${FLAGS_recovery} -eq $FLAGS_TRUE ]; then
258 NUM_KERN_SECTORS=$max_kern_sectors
259 num_kern_a_sectors=$NUM_KERN_SECTORS
260 num_kern_b_sectors=$NUM_KERN_SECTORS
261
262 NUM_ROOTFS_SECTORS=$max_rootfs_sectors
263 num_rootfs_a_sectors=$NUM_ROOTFS_SECTORS
264 num_rootfs_b_sectors=$NUM_ROOTFS_SECTORS
265 fi
266
Bill Richardsoneff5b062010-03-30 14:17:34 -0700267 START_KERN_A=$start_useful
Bill Richardsond6b71b02010-04-14 12:46:14 -0700268 START_ROOTFS_A=$(($START_KERN_A + $NUM_KERN_SECTORS))
269 START_STATEFUL=$(($START_ROOTFS_A + $NUM_ROOTFS_SECTORS))
270 START_OEM=$(($START_STATEFUL + $NUM_STATEFUL_SECTORS))
271 START_ESP=$(($START_OEM + $NUM_OEM_SECTORS))
272 START_KERN_B=$(($START_ESP + $NUM_ESP_SECTORS))
Tan Gao19a0fcf2010-05-19 14:19:55 -0700273 START_ROOTFS_B=$(($START_KERN_B + $num_kern_b_sectors))
Bill Richardsond6b71b02010-04-14 12:46:14 -0700274 START_RESERVED=$(($START_ROOTFS_B + $num_rootfs_b_sectors))
Bill Richardsoneff5b062010-03-30 14:17:34 -0700275
276 # For minimal install, we're not worried about the secondary GPT header
277 # being at the end of the device because we're almost always writing to a
278 # file. If that's not true, the secondary will just be invalid.
Bill Richardsond6b71b02010-04-14 12:46:14 -0700279 local start_gpt_footer=$(($START_RESERVED + $NUM_RESERVED_SECTORS))
Bill Richardsoneff5b062010-03-30 14:17:34 -0700280 local end_useful=$start_gpt_footer
281
282 local total_sectors=$(($start_gpt_footer + $num_footer_sectors))
283
284 # Create the image file if it doesn't exist.
285 if [ ! -e ${outdev} ]; then
Bill Richardsond6b71b02010-04-14 12:46:14 -0700286 $sudo dd if=/dev/zero of=${outdev} bs=512 count=1 \
287 seek=$(($total_sectors - 1))
Bill Richardsoneff5b062010-03-30 14:17:34 -0700288 fi
289 fi
290
291 echo "Creating partition tables..."
292
293 # Zap any old partitions (otherwise gpt complains).
294 $sudo dd if=/dev/zero of=${outdev} conv=notrunc bs=512 \
295 count=$num_header_sectors
296 $sudo dd if=/dev/zero of=${outdev} conv=notrunc bs=512 \
297 seek=${start_gpt_footer} count=$num_footer_sectors
Bill Richardson13dbcf22010-04-06 15:00:10 -0700298
Bill Richardsoneff5b062010-03-30 14:17:34 -0700299 # Create the new GPT partitions. The order determines the partition number.
300 # Note that the partition label is in the GPT only. The filesystem label is
301 # what's used to populate /dev/disk/by-label/, and this is not that.
robotboya7684292010-04-21 14:46:00 -0700302
Bill Richardsoneff5b062010-03-30 14:17:34 -0700303 $sudo $GPT create ${outdev}
Bill Richardson13dbcf22010-04-06 15:00:10 -0700304
Bill Richardsoneff5b062010-03-30 14:17:34 -0700305 $sudo $GPT add -b ${START_STATEFUL} -s ${NUM_STATEFUL_SECTORS} \
Bill Richardsond6b71b02010-04-14 12:46:14 -0700306 -t ${DATA_GUID} ${outdev}
Bill Richardsoneff5b062010-03-30 14:17:34 -0700307 $sudo $GPT label -i 1 -l "STATE" ${outdev}
Bill Richardson13dbcf22010-04-06 15:00:10 -0700308
Bill Richardsond6b71b02010-04-14 12:46:14 -0700309 $sudo $GPT add -b ${START_KERN_A} -s ${num_kern_a_sectors} \
Bill Richardsoneff5b062010-03-30 14:17:34 -0700310 -t ${KERN_GUID} ${outdev}
311 $sudo $GPT label -i 2 -l "KERN-A" ${outdev}
Bill Richardson13dbcf22010-04-06 15:00:10 -0700312
Bill Richardsond6b71b02010-04-14 12:46:14 -0700313 $sudo $GPT add -b ${START_ROOTFS_A} -s ${num_rootfs_a_sectors} \
Bill Richardsoneff5b062010-03-30 14:17:34 -0700314 -t ${ROOTFS_GUID} ${outdev}
315 $sudo $GPT label -i 3 -l "ROOT-A" ${outdev}
Bill Richardson13dbcf22010-04-06 15:00:10 -0700316
Bill Richardsond6b71b02010-04-14 12:46:14 -0700317 $sudo $GPT add -b ${START_KERN_B} -s ${num_kern_b_sectors} \
318 -t ${KERN_GUID} ${outdev}
319 $sudo $GPT label -i 4 -l "KERN-B" ${outdev}
Bill Richardson13dbcf22010-04-06 15:00:10 -0700320
Bill Richardsond6b71b02010-04-14 12:46:14 -0700321 $sudo $GPT add -b ${START_ROOTFS_B} -s ${num_rootfs_b_sectors} \
322 -t ${ROOTFS_GUID} ${outdev}
323 $sudo $GPT label -i 5 -l "ROOT-B" ${outdev}
Bill Richardsoneff5b062010-03-30 14:17:34 -0700324
Bill Richardsond6b71b02010-04-14 12:46:14 -0700325 $sudo $GPT add -b ${start_kern_c} -s ${num_kern_c_sectors} \
326 -t ${KERN_GUID} ${outdev}
327 $sudo $GPT label -i 6 -l "KERN-C" ${outdev}
328
329 $sudo $GPT add -b ${start_rootfs_c} -s ${num_rootfs_c_sectors} \
330 -t ${ROOTFS_GUID} ${outdev}
331 $sudo $GPT label -i 7 -l "ROOT-C" ${outdev}
332
333 $sudo $GPT add -b ${START_OEM} -s ${NUM_OEM_SECTORS} \
Bill Richardson40238cd2010-04-16 18:00:53 -0700334 -t ${DATA_GUID} ${outdev}
Bill Richardsond6b71b02010-04-14 12:46:14 -0700335 $sudo $GPT label -i 8 -l "OEM" ${outdev}
336
337 $sudo $GPT add -b ${start_future_9} -s ${num_future_sectors} \
338 -t ${FUTURE_GUID} ${outdev}
339 $sudo $GPT label -i 9 -l "reserved" ${outdev}
340
341 $sudo $GPT add -b ${start_future_10} -s ${num_future_sectors} \
342 -t ${FUTURE_GUID} ${outdev}
343 $sudo $GPT label -i 10 -l "reserved" ${outdev}
344
345 $sudo $GPT add -b ${start_future_11} -s ${num_future_sectors} \
346 -t ${FUTURE_GUID} ${outdev}
347 $sudo $GPT label -i 11 -l "reserved" ${outdev}
348
Bill Richardson13dbcf22010-04-06 15:00:10 -0700349 $sudo $GPT add -b ${START_ESP} -s ${NUM_ESP_SECTORS} \
350 -t ${ESP_GUID} ${outdev}
Bill Richardsond6b71b02010-04-14 12:46:14 -0700351 $sudo $GPT label -i 12 -l "EFI-SYSTEM" ${outdev}
Bill Richardson13dbcf22010-04-06 15:00:10 -0700352
Bill Richardsoneff5b062010-03-30 14:17:34 -0700353 # Create the PMBR and instruct it to boot ROOT-A
354 $sudo $GPT boot -i 3 -b ${pmbrcode} ${outdev}
Bill Richardson13dbcf22010-04-06 15:00:10 -0700355
Bill Richardsoneff5b062010-03-30 14:17:34 -0700356 # Display what we've got
357 $sudo $GPT -r show -l ${outdev}
358
359 sync
360}
361
362
363# Helper function, please ignore and look below.
364_partinfo() {
365 local device=$1
366 local partnum=$2
367 local start size part x n
robotboya7684292010-04-21 14:46:00 -0700368
369 locate_gpt
370
Bill Richardsoneff5b062010-03-30 14:17:34 -0700371 sudo $GPT -r -S show $device \
372 | grep 'GPT part -' \
373 | while read start size part x x x n x; do \
374 if [ "${part}" -eq "${partnum}" ]; then \
375 echo $start $size; \
376 fi; \
377 done
378 # The 'while' is a subshell, so there's no way to indicate success.
379}
380
381# Read GPT table to find information about a specific partition.
382# Invoke as: subshell
383# Args: DEVICE PARTNUM
384# Returns: offset and size (in sectors) of partition PARTNUM
385partinfo() {
386 # get string
Andrew de los Reyes344709b2010-04-05 10:49:08 -0700387 local X="$(_partinfo $1 $2)"
Bill Richardsoneff5b062010-03-30 14:17:34 -0700388 # detect success or failure here
389 [ -n "$X" ]
390 echo $X
391}
392
393# Read GPT table to find the starting location of a specific partition.
394# Invoke as: subshell
395# Args: DEVICE PARTNUM
396# Returns: offset (in sectors) of partition PARTNUM
397partoffset() {
398 # get string
Andrew de los Reyes344709b2010-04-05 10:49:08 -0700399 local X="$(_partinfo $1 $2)"
Bill Richardsoneff5b062010-03-30 14:17:34 -0700400 # detect success or failure here
401 [ -n "$X" ]
402 echo ${X% *}
403}
404
405# Read GPT table to find the size of a specific partition.
406# Invoke as: subshell
407# Args: DEVICE PARTNUM
408# Returns: size (in sectors) of partition PARTNUM
409partsize() {
410 # get string
Andrew de los Reyes344709b2010-04-05 10:49:08 -0700411 local X="$(_partinfo $1 $2)"
Bill Richardsoneff5b062010-03-30 14:17:34 -0700412 # detect success or failure here
413 [ -n "$X" ]
414 echo ${X#* }
415}
416
Jie Sun1f9d4122010-04-12 17:04:36 -0700417# Extract the whole disk block device from the partition device.
418# This works for /dev/sda3 (-> /dev/sda) as well as /dev/mmcblk0p2
419# (-> /dev/mmcblk0).
420get_block_dev_from_partition_dev() {
421 local partition=$1
422 if ! (expr match "$partition" ".*[0-9]$" >/dev/null) ; then
423 echo "Invalid partition name: $partition" >&2
424 exit 1
425 fi
426 # Remove the last digit.
427 local block=$(echo "$partition" | sed -e 's/\(.*\)[0-9]$/\1/')
428 # If needed, strip the trailing 'p'.
429 if (expr match "$block" ".*[0-9]p$" >/dev/null); then
430 echo "${block%p}"
431 else
432 echo "$block"
433 fi
434}
435
436# Extract the partition number from the partition device.
437# This works for /dev/sda3 (-> 3) as well as /dev/mmcblk0p2 (-> 2).
438get_partition_number() {
439 local partition=$1
440 if ! (expr match "$partition" ".*[0-9]$" >/dev/null) ; then
441 echo "Invalid partition name: $partition" >&2
442 exit 1
443 fi
444 # Extract the last digit.
445 echo "$partition" | sed -e 's/^.*\([0-9]\)$/\1/'
446}
447
448# Construct a partition device name from a whole disk block device and a
449# partition number.
450# This works for [/dev/sda, 3] (-> /dev/sda3) as well as [/dev/mmcblk0, 2]
451# (-> /dev/mmcblk0p2).
452make_partition_dev() {
453 local block=$1
454 local num=$2
455 # If the disk block device ends with a number, we add a 'p' before the
456 # partition number.
457 if (expr match "$block" ".*[0-9]$" >/dev/null) ; then
458 echo "${block}p${num}"
459 else
460 echo "${block}${num}"
461 fi
462}
463
464# Construct a PMBR for the arm platform, Uboot will load PMBR and "autoscr" it.
465# Arguments List:
466# $1 : Kernel Partition Offset.
467# $2 : Kernel Partition Size ( in Sectors ).
468# $3 : DEVICE
469# Return file path of the generated PMBR.
470
471make_arm_mbr() {
472 # Create the U-Boot script to copy the kernel into memory and boot it.
473 local KERNEL_OFFSET=$(printf "0x%08x" ${1})
474 local KERNEL_SECS_HEX=$(printf "0x%08x" ${2})
475 local DEVICE=${3}
robotboyd3cfe222010-04-30 09:51:23 -0700476 local EXTRA_BOOTARGS=${4}
Jie Sun1f9d4122010-04-12 17:04:36 -0700477
478 BOOTARGS="root=/dev/mmcblk${DEVICE}p3"
479 BOOTARGS="${BOOTARGS} init=/sbin/init"
480 BOOTARGS="${BOOTARGS} console=ttySAC2,115200"
481 BOOTARGS="${BOOTARGS} mem=1024M"
482 BOOTARGS="${BOOTARGS} rootwait"
robotboyd3cfe222010-04-30 09:51:23 -0700483 BOOTARGS="${BOOTARGS} ${EXTRA_BOOTARGS}"
Jie Sun1f9d4122010-04-12 17:04:36 -0700484
485 MBR_SCRIPT="/var/tmp/mbr_script"
486 echo -e "echo\necho ---- ChromeOS Boot ----\necho\n" \
487 "setenv bootargs ${BOOTARGS}\n" \
488 "mmc read ${DEVICE} C0008000 $KERNEL_OFFSET $KERNEL_SECS_HEX\n" \
489 "bootm C0008000" > ${MBR_SCRIPT}
490 MKIMAGE="/usr/bin/mkimage"
491 if [ -x "$MKIMAGE" ]; then
492 MBR_SCRIPT_UIMG="${MBR_SCRIPT}.uimg"
493 "$MKIMAGE" -A "arm" -O linux -T script -a 0 -e 0 -n "COS boot" \
494 -d ${MBR_SCRIPT} ${MBR_SCRIPT_UIMG} >&2
495 else
496 echo "Error: u-boot mkimage not found or not executable." >&2
497 exit 1
498 fi
499 echo ${MBR_SCRIPT_UIMG}
500}
Bill Richardson05c4e342010-05-14 17:00:21 -0700501
502
503# The scripts that source this file typically want to use the root password as
504# confirmation, unless the --run_as_root flag is given.
505dont_run_as_root() {
506 if [ $(id -u) -eq "0" -a "${FLAGS_run_as_root}" -eq "${FLAGS_FALSE}" ]
507 then
508 echo "Note: You must be the 'chronos' user to run this script. Unless"
509 echo "you pass --run_as_root and run as root."
510 exit 1
511 fi
512}
Paul Stewart04f3ef12010-05-27 15:56:42 -0700513
514list_usb_disks() {
515 local sd
516 for sd in /sys/block/sd*; do
517 if readlink ${sd}/device | grep -q usb &&
518 [ "$(cat ${sd}/removable)" = 1 ]; then
519 echo ${sd##*/}
520 fi
521 done
522}
523
524get_disk_info() {
525 # look for a "given" file somewhere in the path upwards from the device
526 local dev_path=/sys/block/${1}/device
527 while [ -d "${dev_path}" -a "${dev_path}" != "/sys" ]; do
528 if [ -f "${dev_path}/${2}" ]; then
529 cat "${dev_path}/${2}"
530 return
531 fi
532 dev_path=$(readlink -f ${dev_path}/..)
533 done
534 echo '[Unknown]'
535}