#!/bin/sh # Replicant GTA04 installer # # Copyright (C) 2012-2014 Paul Kocialkowski, GPLv2 # # Based on mkcard.sh v0.5 # Copyright (C) 2009 Graeme Gregory , GPLv2 # Parts of the procudure base on the work of Denys Dmytriyenko # http://wiki.omap.com/index.php/MMC_Boot_Format # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Environment # export LC_ALL=C # # Globals # DRIVE="" DRIVE_NAME="" DRIVE_SIZE="" DRIVE_CYLINDERS="" DRIVE_PART="" SYSTEM_ZIP="replicant-4.2-gta04.zip" BOOTABLE_ZIP="bootable.zip" FILES_BASE="." MOUNT_BASE="/media" # # Functions # # Display display_help() { echo "Usage: $0 [COMMAND] [DRIVE]" echo "" echo "It is expected that the following files are located in $FILES_BASE:" echo " $BOOTABLE_ZIP for setup" echo " $SYSTEM_ZIP for install" echo "" echo "Commands:" echo " setup - setup the drive and copy the base files" echo " install - install the system on the drive" echo "" echo "Optional arguments:" echo " [DRIVE] - drive node to use" } display_banner() { echo "Replicant GTA04 installer" echo "" } display_complete() { echo "" echo "Process completed, you can now remove the card!" } # Drive drive_select_list() { drives_dir="/dev/disk/by-id/" count=0 list=$( ls "$drives_dir" ) for drive in $list do drive_nopart=$( echo "$drive" | sed "s/-part[0-9]*$//g" ) if [ "$drive" = "$drive_nopart" ] then ls $drives_dir/$drive-part* 2> /dev/null > /dev/null if [ $? -eq 0 ] then count=$(( $count + 1 )) name=$( echo "$drive" | sed "s/^[^-]*-\(.*\)$/\1/g" ) case "$1" in "show") echo "$count - $name" ;; "store") if [ $count -eq $2 ] then DRIVE=$( readlink -f "$drives_dir/$drive" ) DRIVE_NAME="$name" fi ;; esac fi fi done } drive_select() { echo "Available devices:" drive_select_list "show" echo -n "Choice: " read choice drive_select_list "store" $choice echo "" } drive_umount() { list=$( mount | grep $DRIVE | sed "s|$DRIVE[0-9]* on \([^ ]*\) .*|\1|g" ) for mount_point in $list do echo "Unmounting $mount_point" umount "$mount_point" if [ $? != 0 ] then echo "Unmounting $mount_point failed, arborting!" exit 1 fi done } drive_part() { if [ -e "${DRIVE}p1" ] then DRIVE_PART="${DRIVE}p" else DRIVE_PART="${DRIVE}" fi } # Setup setup_drive_confirm() { if [ "$DRIVE" = "" ] then echo "Invalid drive block" exit 1 fi list=$( mount | grep $DRIVE | sed "s|$DRIVE[0-9]* on \([^ ]*\) .*|\1|g" ) echo "This is going to erase the following drive:" if [ "$DRIVE_NAME" != "" ] then echo "- $DRIVE_NAME ($DRIVE)" else echo "- $DRIVE" fi for mount_point in $list do mount_point_check=$( dirname $mount_point | grep -P "^/mnt|mount" ) if [ "$mount_point_check" != "" ] then echo "" echo "Warning: the drive is mounted as $mount_point!" echo "This is probably not the drive you want to use!" fi done echo "" echo -n "Are you sure? [Y/N] " read confirm if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ] then echo "" return else exit 0 fi } setup_drive_empty() { drive_umount # Backup dd if="$DRIVE" of=".drive_start_backup" bs=1024 count=1024 dd if=/dev/zero of="$DRIVE" bs=1024 count=1024 if [ $? != 0 ] then echo "Emptying the drive failed, aborting!" exit 1 fi } setup_drive_rescue() { if [ -f ".drive_start_backup" ] then echo -n "Something went wrong, do you want to restore drive start backup? [Y/N] " if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ] then dd if=".drive_start_backup" of="$DRIVE" bs=1024 count=1024 fi fi } setup_drive_infos() { DRIVE_SIZE=$( fdisk -l "$DRIVE" | grep Disk | grep bytes | awk '{print $5}' ) DRIVE_CYLINDERS=$( echo "$DRIVE_SIZE/255/63/512" | bc ) } setup_drive_partition() { boot_size=$( echo "(50 * 1024 * 1024) / ($DRIVE_SIZE/$DRIVE_CYLINDERS)" | bc ) system_size=$( echo "(350 * 1024 * 1024) / ($DRIVE_SIZE/$DRIVE_CYLINDERS)" | bc ) cache_size=$( echo "(100 * 1024 * 1024) / ($DRIVE_SIZE/$DRIVE_CYLINDERS)" | bc ) { echo ",$boot_size,c,*" echo ",$system_size,83,-" echo ",$cache_size,83,-" echo ",,83,-" } | sfdisk -D -H 255 -S 63 -C "$DRIVE_CYLINDERS" "$DRIVE" if [ $? != 0 ] then drive_rescue exit 1 fi sleep 1 drive_part mkfs.vfat -F 32 -n "boot" "${DRIVE_PART}1" mkfs.ext4 -L "system" "${DRIVE_PART}2" mkfs.ext4 -L "cache" "${DRIVE_PART}3" mkfs.ext4 -L "data" "${DRIVE_PART}4" sleep 1 } setup_boot_install() { echo "Installing boot files" drive_part mkdir -p "$MOUNT_BASE/boot" mount "${DRIVE_PART}1" "$MOUNT_BASE/boot" unzip -o "$FILES_BASE/$BOOTABLE_ZIP" "**" -d "$MOUNT_BASE/boot/" if [ -f "$MOUNT_BASE/boot/splash.rgb16z" ] then gunzip < "$MOUNT_BASE/boot/splash.rgb16z" > "$MOUNT_BASE/boot/splash.rgb16" fi dir=$( pwd ) echo "Syncing boot files" cd "$MOUNT_BASE/boot" sync cd "$dir" umount "$MOUNT_BASE/boot" rmdir "$MOUNT_BASE/boot" } setup_drive_eject() { rm -rf ".drive_start_backup" eject "$DRIVE" } # Install install_package_extract_dir() { destination="$MOUNT_BASE"$( dirname "$2") if [ $# -lt 2 ] then return fi unzip -o "$FILES_BASE/$SYSTEM_ZIP" "$1/**" -d "$destination" } install_package_extract_file() { destination="$MOUNT_BASE"$( dirname "$2") if [ $# -lt 2 ] then return fi unzip -o "$FILES_BASE/$SYSTEM_ZIP" "$1" -d "$destination" } install_symlink() { source="" if [ $# -lt 2 ] then return fi for path in $@ do if [ "$source" = "" ] then source="$path" continue fi unlink "$MOUNT_BASE$path" ln -s "$source" "$MOUNT_BASE$path" done } install_set_perm() { uid="" gid="" mode="" if [ $# -lt 4 ] then return fi for value in $@ do if [ "$uid" = "" ] then uid="$value" continue fi if [ "$gid" = "" ] then gid="$value" continue fi if [ "$mode" = "" ] then mode="$value" continue fi chown "$uid:$gid" "$MOUNT_BASE$value" chmod "$mode" "$MOUNT_BASE$value" done } install_set_perm_recursive() { uid="" gid="" dir_mode="" file_mode="" if [ $# -lt 4 ] then return fi for value in $@ do if [ "$uid" = "" ] then uid="$value" continue fi if [ "$gid" = "" ] then gid="$value" continue fi if [ "$dir_mode" = "" ] then dir_mode="$value" continue fi if [ "$file_mode" = "" ] then file_mode="$value" continue fi find "$MOUNT_BASE$value" -type d -exec chown "$uid:$gid" {} \; -exec chmod "$dir_mode" {} \; find "$MOUNT_BASE$value" -type f -exec chown "$uid:$gid" {} \; -exec chmod "$file_mode" {} \; done } install_command() { command=$( echo "$1" | sed "s/[ \t]*\([^(]*\)(.*/\1/g" ) arguments=$( echo "$1" | sed -e "s/[^(]*(\([^)]*\));.*/\1/g" -e "s/[ \t]*,[ \t]*/ /g" | tr -d '"') case "$command" in "package_extract_dir") install_package_extract_dir $arguments ;; "package_extract_file") install_package_extract_file $arguments ;; "symlink") install_symlink $arguments ;; "set_perm") install_set_perm $arguments ;; "set_perm_recursive") install_set_perm_recursive $arguments ;; esac } install_script() { unzip -p "$FILES_BASE/$SYSTEM_ZIP" "META-INF/com/google/android/updater-script" | while read line do end_test=$( echo "$line" | grep -P "\);$" ) COMMAND="$COMMAND$line" if [ "$end_test" != "" ] then install_command "$COMMAND" COMMAND="" fi done } install_drive_mount() { drive_part drive_umount mkdir -p "$MOUNT_BASE/boot" mount "${DRIVE_PART}1" "$MOUNT_BASE/boot" mkdir -p "$MOUNT_BASE/system" mount "${DRIVE_PART}2" "$MOUNT_BASE/system" } install_drive_umount() { drive_part dir=$( pwd ) echo "Syncing files" cd "$MOUNT_BASE/boot" sync cd "$dir" cd "$MOUNT_BASE/system" sync cd "$dir" umount "$MOUNT_BASE/boot" rmdir "$MOUNT_BASE/boot" umount "$MOUNT_BASE/system" rmdir "$MOUNT_BASE/system" } install_drive_eject() { eject "$DRIVE" } # # Main # if [ $# -lt 1 ] || [ $# -gt 2 ] then display_help exit 1 fi if [ $# -gt 1 ] then DRIVE=$2 fi display_banner if [ "$DRIVE" = "" ] then drive_select fi case $1 in "setup") setup_drive_confirm drive_umount setup_drive_empty setup_drive_infos setup_drive_partition setup_boot_install setup_drive_eject display_complete ;; "install") install_drive_mount install_script install_drive_umount install_drive_eject display_complete ;; *) display_help exit 1 ;; esac