1#!/bin/sh
2
3# Copyright 2014 Google Inc.
4#
5# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
8
9usage() {
10    cat >&2 <<EOF
11arm64_download - this script downloads the Linaro's ARMv8 Aarch64
12toolchain and minimal embedded Linux system as well as ARM's
13foundation model.  The required files are mirrored on Google Cloud.
14
15If the files are already located in the working directory, the
16download can be skipped if the checksums match.
17
18The script then starts a emulated Arm64 Linux system in the
19background.  After the boot is complete, you can SSH into the system
20at port 8022 via user@localhost.  The SSH key will be downloaded into
21the working directery as well.
22
23Requires gsutil, xz, tar, and gunzip.
24
25Usage:
26  $0 WORKING_DIRECTORY
27  ssh-add WORKING_DIRECTORY/key
28  ...wait...
29  ssh -p 8022 user@localhost
30EOF
31    return 1
32}
33
34try() {
35    # print an error on nonzero return code
36    "$@"
37    local ret=$?
38    if [ $ret != 0 ] ; then
39        echo "'$@' failed and returned ${ret}." >&2
40        return $ret
41    fi
42}
43
44download_necessary_software_to_dir() (
45    cd "$1"
46    local location="chromium-skia-gm/arm64env"
47    try gsutil cp "gs://${location}/md5sum.txt" . || return
48    if md5sum -c --quiet "md5sum.txt"; then
49        return 0
50    fi
51    try gsutil cp "gs://${location}/*" . || return
52)
53
54install_compiler() {
55    local working_dir="$1"
56    local toolchain="gcc-linaro-aarch64-linux-gnu-4.8-2013.12_linux"
57    (
58        try cd "$working_dir" || return
59        try test -f "${toolchain}.tar.xz" || return
60        try xz --decompress --stdout < "${toolchain}.tar.xz" | \
61            try tar xf - || return
62    )
63    local dir="${working_dir}/${toolchain}"
64    try test -d "$dir" || return
65    try test -x "${dir}/bin/aarch64-linux-gnu-gcc" || return
66    try test -x "${dir}/bin/aarch64-linux-gnu-g++" || return
67}
68
69install_runtime() {
70    local working_dir="$1"
71
72    local firmware='img-foundation.axf'
73    local rootfs='vexpress64-openembedded_lamp-armv8-gcc-4.8_20131215-557'
74    local compressed_rootfs="${rootfs}.img.CLEAN_AND_CONFIGURED.xz"
75    local compressed_foundation_model='FM000-KT-00035-r0p8-52rel06.tgz'
76    local keyfile='CLEAN_AND_CONFIGURED_key'
77
78    try cp "${working_dir}/$firmware" "${working_dir}/firmware" || return
79
80    try xz --decompress --stdout \
81        < "${working_dir}/${compressed_rootfs}" \
82        > "${working_dir}/rootfs" || return
83    try test -f "${working_dir}/rootfs" || return
84
85    (
86        try cd "$working_dir" || return
87        try test -f "$compressed_foundation_model" || return
88        try gunzip -c "$compressed_foundation_model" | try tar xf - || return
89        try test -d "Foundation_v8pkg" || return  #  Assert.
90    )
91
92    try cp "${working_dir}/${keyfile}" "${working_dir}/key" || return
93    chmod 'go=' "${working_dir}/key"
94}
95
96start_arm64_image() {
97    local working_dir="$1"
98    local foundation_dir="${working_dir}/Foundation_v8pkg"
99    local foundation="${foundation_dir}/models/Linux64_GCC-4.1/Foundation_v8"
100    local firmware="${working_dir}/firmware"
101    local rootfs="${working_dir}/rootfs"
102
103    try test -d "$foundation_dir" || return
104    try test -x "$foundation" || return
105    try test -f "$firmware" || return
106    try test -f "$rootfs" || return
107
108    for PID in $(ps -o 'pid=' -C 'Foundation_v8') ; do
109        kill $PID
110    done
111
112    DISPLAY='' nohup \
113    "$foundation" \
114        --image="${firmware}" \
115        --cores=4 \
116        --block-device="${rootfs}" \
117        --network="nat" \
118        --network-nat-subnet="192.168.31.0/24" \
119        --network-nat-ports="8022=22" \
120        > /dev/null 2>&1 &
121    echo 'Waiting for foundation model to boot...'
122    while ! ssh -i "${working_dir}/key" \
123        -o NoHostAuthenticationForLocalhost=yes \
124        -p 8022 user@localhost true 2> /dev/null; do
125        sleep 5
126    done
127    echo 'Listening to SSH on port 8022.'
128}
129
130arm64_download() {
131    local working_directory="$1"
132    try mkdir -p "$working_directory" || return
133
134    try download_necessary_software_to_dir "$working_directory" || return
135
136    try install_compiler "$working_directory" || return
137
138    try install_runtime "$working_directory" || return
139
140    try start_arm64_image "$working_directory" || return
141}
142
143for command in gsutil xz tar md5sum gunzip; do
144    try command -v "$command" > /dev/null || usage || exit
145done
146
147if [ -z "$1" ] ; then
148    usage || exit
149fi
150try arm64_download "$1"
151