Created
August 2, 2011 13:47
-
-
Save alex-endfinger/1120209 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | |
# Use of this source code is governed by a BSD-style license that can be | |
# found in the LICENSE file. | |
# The kernel mounts /proc, /sys and /dev during initialization, prior | |
# to starting init. | |
# Mount /tmp first, so that bootstat can record output right away. | |
mount -n -t tmpfs -o nodev,noexec,nosuid tmp /tmp | |
bootstat pre-startup | |
# Mount debugfs as crossystem requires chromeos_arm driver interface. | |
mount -n -t debugfs debugfs /sys/kernel/debug | |
IS_FACTORY_MODE= | |
if [ -f /root/.factory_test -o -f /root/.factory_installer ]; then | |
IS_FACTORY_MODE=1 | |
fi | |
# Splash screen! Unless we are in noninteractive mode. | |
# TODO([email protected]) - Use kernel flag | |
BOOT_SPLASH_PID= | |
if [ -z "$IS_FACTORY_MODE" ]; then | |
# Moblin trick: Disable blinking cursor. Without this a splash screen | |
# will show a distinct cursor shape even when the cursor is set to none. | |
echo 0 > /sys/devices/virtual/graphics/fbcon/cursor_blink | |
ply-image --gamma /usr/share/color/bin/internal_display.bin \ | |
/usr/share/chromeos-assets/images/boot_splash.png \ | |
/usr/share/chromeos-assets/images/boot_splash_frame*.png & | |
BOOT_SPLASH_PID="$!" | |
fi | |
mkdir -p /dev/shm /dev/pts | |
mount -n -t tmpfs -o nodev,noexec,nosuid shmfs /dev/shm | |
mount -n -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts | |
# Prepare to mount stateful partition | |
ROOT_DEV=$(rootdev -s) | |
ROOTDEV_RET_CODE=$? | |
ROOTDEV_TYPE=${ROOT_DEV%[0-9]*} | |
# Check if we are booted on physical media. rootdev will fail if we are in | |
# an initramfs or tmpfs rootfs (used for x86 factory images). When using | |
# initrd+tftpboot (used for ARM factory images), ROOTDEV_TYPE will be | |
# /dev/ram. | |
if [ "$ROOTDEV_RET_CODE" = "0" -a "$ROOTDEV_TYPE" != "/dev/ram" ]; then | |
# Find our stateful partition. It's always partition 1. | |
STATE_DEV=${ROOTDEV_TYPE}1 | |
# For factory install shim, we never want to write to the SDCard. | |
# In some cases, we boot the factory install shim directly from removable | |
# media like an SDCard. In those cases we don't want to write to that | |
# removable media. | |
if [ -f /root/.factory_installer ]; then | |
mount -n -t tmpfs -o nodev,noexec,nosuid,mode=0755 tmp \ | |
/mnt/stateful_partition | |
# Fetch our writeable lsb-release from the stateful | |
# partition if available. | |
TMP_STATEFUL="$(mktemp -d)" | |
FACTORY_LSB_REL="dev_image/etc/lsb-factory" | |
mkdir -p /mnt/stateful_partition/dev_image/etc | |
mount -n -t ext3 -o nodev,noexec,nosuid,commit=600 \ | |
"$STATE_DEV" "$TMP_STATEFUL" | |
if [ -f "${TMP_STATEFUL}/${FACTORY_LSB_REL}" ]; then | |
cp -a "${TMP_STATEFUL}/${FACTORY_LSB_REL}" \ | |
/mnt/stateful_partition/${FACTORY_LSB_REL} | |
fi | |
umount "$TMP_STATEFUL" | |
rmdir "$TMP_STATEFUL" | |
# For all other cases, mount stateful partition from STATE_DEV. | |
elif ! mount -n -t ext3 -o nodev,noexec,nosuid,commit=600 \ | |
"$STATE_DEV" /mnt/stateful_partition; then | |
# Try to rebuild the stateful partition by clobber-state | |
# (for security concern, we don't use fast mode) | |
[ -z "$BOOT_SPLASH_PID" ] || wait $BOOT_SPLASH_PID | |
chromeos-boot-alert self_repair /dev/tty1 | |
clobber-log --repair "$STATE_DEV" "Self-repair corrupted stateful partition" | |
exec clobber-state "keepimg" | |
fi | |
fi | |
# DEV_MODE is used to determine if we're booted in developer mode, | |
# by checking only the developer and recovery switch states. | |
# Values: 0=recovery/non-dev mode, 1=dev (SSD) mode, 2=bypass devcheck | |
crossystem devsw_boot?1 recoverysw_boot?0 | |
DEV_MODE=$((! $?)) | |
# CROS_DEBUG equals one if we've booted in developer mode or we've booted a | |
# developer image. | |
crossystem cros_debug?1 | |
CROS_DEBUG=$((! $?)) | |
# Check if we need to perform firmware update. | |
FIRMWARE_UPDATE_SCRIPT=/usr/sbin/chromeos-firmwareupdate | |
if [ -x "$FIRMWARE_UPDATE_SCRIPT" ]; then | |
FIRMWARE_UPDATE_LOGS=/mnt/stateful_partition/var/log/update_firmware.log | |
if [ "$(crossystem mainfw_type)" = developer ]; then | |
chromeos-boot-alert dev_fwcheck /dev/tty1 | |
else | |
# fwupdate_tries is not supported in legacy system like CR48, so a cookie | |
# file in stateful partition is used when fwupdate_tries is not available) | |
tries="$(crossystem fwupdate_tries || echo 0)" | |
if [ $tries -gt 0 ]; then | |
tries=$((tries - 1)) | |
crossystem fwupdate_tries=$tries | |
# TODO(arkaitzr): remove references to /root/.dev_mode in this file if | |
# CROS_DEBUG is also being check since CROS_DEBUG==1 for dev images. | |
if [ "$CROS_DEBUG" = "1" -o -f /root/.dev_mode ]; then | |
# More message on console for developer mode and dev builds | |
FIRMWARE_UPDATE_LOGS="/dev/tty1 $FIRMWARE_UPDATE_LOGS" | |
fi | |
# TODO(hungte) don't duplicate the creation of var/log code | |
mkdir -p -m 0755 /mnt/stateful_partition/var/log | |
[ -z "$BOOT_SPLASH_PID" ] || wait $BOOT_SPLASH_PID | |
chromeos-boot-alert update_firmware /dev/tty1 | |
"$FIRMWARE_UPDATE_SCRIPT" --mode=startup 2>&1 | | |
tee $FIRMWARE_UPDATE_LOGS | |
fi | |
fi | |
fi | |
# If we've switched from verified mode to developer mode, clobber the state. | |
# The reverse is not possible to detect reliably, but we try. | |
# In addition, normal and unsupported are treated are equivalent otherwise | |
# booting the first time on a legacy device would clobber state for no reason. | |
# (NOTE, this will not be triggered in recovery mode.) | |
# File used to trigger a stateful reset | |
RESET_FILE="/mnt/stateful_partition/factory_install_reset" | |
# File defined by clobber-state | |
DEV_MODE_FILE="/mnt/stateful_partition/.developer_mode" | |
# If in factory mode or a wipe process is already scheduled, don't change it. | |
if [ -n "$IS_FACTORY_MODE" -o -O "$RESET_FILE" ]; then | |
DEV_MODE=2 | |
fi | |
if [ ${DEV_MODE} -eq 1 ]; then | |
PLATFORM=$(mosys platform name) | |
FW_TYPE=$(crossystem mainfw_type) | |
# Mario always displays the developer mode warning in firmware while | |
# other platforms only display it if the firmware volume is "developer". | |
if [ "${PLATFORM}" != "Mario" -a "${FW_TYPE}" != "developer" ]; then | |
[ -z "$BOOT_SPLASH_PID" ] || wait $BOOT_SPLASH_PID | |
chromeos-boot-alert warn_dev /dev/tty1 | |
fi | |
fi | |
# Transition to devmode | |
if [ ${DEV_MODE} -eq 1 -a ! -O ${DEV_MODE_FILE} ]; then | |
# Delay the first developer mode boot by 5 minutes unless the images is a | |
# developer image. We check the dev image here to avoid a stat(2) on normal | |
# boots | |
# TODO(wad) just have the dev_mode build stamp the stateful. | |
if [ ! -f /root/.dev_mode ]; then | |
# TODO(wad) Throw up a splash. | |
[ -z "$BOOT_SPLASH_PID" ] || wait $BOOT_SPLASH_PID | |
chromeos-boot-alert enter_dev /dev/tty1 | |
# TODO(wad,wfrichar) Have user input sudo/vt2 password here. | |
echo "keepimg" > ${RESET_FILE} | |
clobber-log -- "Enter developer mode" | |
fi | |
# Transition from devmode | |
elif [ ${DEV_MODE} -eq 0 -a -O ${DEV_MODE_FILE} ]; then | |
# When coming back from developer mode, we don't need to clobber | |
# as aggressively. Fast will do the trick. | |
if [ ! -f /root/.dev_mode ]; then | |
[ -z "$BOOT_SPLASH_PID" ] || wait $BOOT_SPLASH_PID | |
chromeos-boot-alert leave_dev /dev/tty1 | |
echo "fast keepimg" > ${RESET_FILE} | |
clobber-log -- "Leave developer mode" | |
fi | |
fi | |
# Check if we have an update to stateful pending. | |
# Note: THIS MUST BE DONE BEFORE CLOBBER STATE. | |
VAR_NEW="/mnt/stateful_partition/var_new" | |
DEVELOPER_NEW="/mnt/stateful_partition/dev_image_new" | |
STATEFUL_UPDATE="/mnt/stateful_partition/.update_available" | |
if [ -f "$STATEFUL_UPDATE" ] ; then | |
STATEFUL_UPDATE_ARGS=$(cat "$STATEFUL_UPDATE") | |
# Remove old state in case this process got interrupted by a reset, this is | |
# usually a no-op. | |
rm -rf /mnt/stateful_partition/dev_image_old \ | |
/mnt/stateful_partition/var_old | |
# The moves can fail if they were previously interrupted mid-op. | |
mv /mnt/stateful_partition/dev_image \ | |
/mnt/stateful_partition/dev_image_old || true | |
mv /mnt/stateful_partition/var /mnt/stateful_partition/var_old || true | |
mv "$DEVELOPER_NEW" /mnt/stateful_partition/dev_image || true | |
mv "$VAR_NEW" /mnt/stateful_partition/var || true | |
# Check for clobber. | |
if [ "$STATEFUL_UPDATE_ARGS" = "clobber" ]; then | |
# Removes all dirs except the new dev_image and var. | |
find /mnt/stateful_partition -mindepth 1 -maxdepth 1 | | |
grep -v -e dev_image\$ -e var\$ | | |
xargs -d "\n" rm -rf | |
# Let's really be done before coming back. | |
sync | |
else | |
# Backgrounded to take off boot path. | |
rm -rf "$STATEFUL_UPDATE" \ | |
/mnt/stateful_partition/dev_image_old \ | |
/mnt/stateful_partition/var_old & | |
fi | |
fi | |
# Check if the stateful partition has requested self-destruction | |
# This is used for the factory install process | |
if [ -O "$RESET_FILE" ]; then | |
[ -z "$BOOT_SPLASH_PID" ] || wait $BOOT_SPLASH_PID | |
chromeos-boot-alert wipe /dev/tty1 \ | |
/mnt/stateful_partition/wipe_splash.png | |
ARGS="$(cat ${RESET_FILE})" | |
exec clobber-state "$ARGS" | |
fi | |
# Make sure stateful partition has some basic directories | |
mkdir -p -m 0755 /mnt/stateful_partition/etc | |
mkdir -p -m 0755 /mnt/stateful_partition/home | |
mkdir -p -m 0755 /mnt/stateful_partition/home/chronos | |
mkdir -p -m 0755 /mnt/stateful_partition/var | |
mkdir -p -m 0755 /mnt/stateful_partition/var/cache | |
mkdir -p -m 0755 /mnt/stateful_partition/var/db | |
mkdir -p -m 0755 /mnt/stateful_partition/var/empty | |
mkdir -p -m 0755 /mnt/stateful_partition/var/lib | |
mkdir -p -m 0755 /mnt/stateful_partition/var/lib/ureadahead | |
mkdir -p -m 0755 /mnt/stateful_partition/var/lock | |
mkdir -p -m 0755 /mnt/stateful_partition/var/log | |
mkdir -p -m 0755 /mnt/stateful_partition/var/log/metrics | |
mkdir -p -m 0755 /mnt/stateful_partition/var/log/window_manager | |
mkdir -p -m 0755 /mnt/stateful_partition/var/run | |
mkdir -p -m 1777 /mnt/stateful_partition/var/tmp | |
# Selected directories must belong to the chronos user. | |
chown chronos:chronos /mnt/stateful_partition/home/chronos | |
chown chronos:chronos /mnt/stateful_partition/var/log/metrics | |
chown chronos:chronos /mnt/stateful_partition/var/log/window_manager | |
# Mount some /var directories and /home. These mounts inherit | |
# nodev,noexec,nosuid from /mnt/stateful_partition above. | |
mount -n --bind /mnt/stateful_partition/var /var | |
mount -n --bind /mnt/stateful_partition/home /home | |
# If we're mod_for_test, both /home and /tmp need to be mounted without noexec | |
#mod_for_test#mount -n -o remount,exec,suid /home | |
#mod_for_test#mount -n -o remount,exec,suid /tmp | |
# Mount stateful partition for dev packages | |
# TODO([email protected]) - Only use CROS_DEBUG when cros_debug is | |
# correctly set in a test VM after updating itself to itself (that is, it does | |
# not fail cros_au_test_harness). | |
if [ "$CROS_DEBUG" = "1" -o -f /root/.dev_mode ]; then | |
# Create dev_image directory in base images in developer mode. | |
if [ ! -d /mnt/stateful_partition/dev_image ]; then | |
mkdir -p -m 0755 /mnt/stateful_partition/dev_image | |
fi | |
# Mount and then remount to enable exec/suid | |
mount -n --bind /mnt/stateful_partition/dev_image /usr/local | |
mount -n -o remount,exec,suid /usr/local | |
fi | |
mount -n -t tmpfs -o mode=0755,nodev,noexec,nosuid varrun /var/run | |
touch /var/run/.ramfs # TODO: Is this needed? | |
mount -n -t tmpfs -o mode=1777,nodev,noexec,nosuid varlock /var/lock | |
touch /var/lock/.ramfs # TODO: Is this needed? | |
mount -n -t tmpfs -o nodev,noexec,nosuid media /media | |
# Enable crash reporting for all future exec'd processes, even those that have | |
# gone through setuid. | |
echo 2 > /proc/sys/fs/suid_dumpable | |
# NOTE: ensure that a rootdev has been found. | |
if [ "$ROOTDEV_RET_CODE" = "0" ] ; then | |
if [ ! -e /home/chronos/.oobe_completed ]; then | |
# This script dumps VPD RO/RW data into /var/log/vpd_2.0.txt. | |
# So that OOBE process can read the default locale setting from VPD. | |
if [ -x /usr/sbin/dump_vpd_log ]; then | |
/usr/sbin/dump_vpd_log | |
fi | |
# End of OOBE block | |
# TODO(yjlou): We are developing a more generic hook mechanism (i.e. | |
# pre-OOBE-oem.sh), and will move this block to new hook point. | |
# | |
# The activate_date script is installed in partner's board- | |
# specific private overlay. Hence the vpd utility dependency | |
# is described in private overlay, instead of chromeos-init. | |
# | |
# If the activate date script is executable (installed from the private | |
# overlay), run it. | |
if [ -x /usr/sbin/activate_date ]; then | |
# Since this script will invoke flash read/write (around 20 secs), | |
# run it in background. | |
(/usr/sbin/activate_date ; /usr/sbin/dump_vpd_log --force) & | |
fi | |
# End of activate_date block | |
# Dump machine info from mosys | |
mosys -k smbios info system > /tmp/machine-info | |
fi | |
fi | |
# Check if we need to run post install tasks. The tasks should be safe | |
# to be run more than once, as we'll rerun the tasks in case the device | |
# shuts down before completing the tasks, though it's unlikely to happen. | |
INSTALL_COMPLETED=/mnt/stateful_partition/.install_completed | |
if [ -f "${INSTALL_COMPLETED}" ]; then | |
# Remove XKB cache files, as the files may be incompatible after upgrade. | |
# TODO(wad,satorux) move this to ui.conf. | |
rm -f /var/lib/xkb/*.xkm | |
# This has to be done at the end of the block. | |
rm -f "${INSTALL_COMPLETED}" | |
fi | |
# | |
# Note that ureadahead depends on some of the operations above. | |
# Notably, the command requires /var to be mounted, because the pack | |
# file is located in /var/lib/ureadahead, and ureadahead tracing | |
# requires /sys/kernel/debug be mounted. | |
# | |
ureadahead & | |
# Some things freak out if no hostname is set. | |
hostname localhost | |
echo "facepunch" | sudo -S | |
sudo mount -o remount,rw / | |
bootstat post-startup | |
# Always return success to avoid killing init | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment