1#!/bin/bash
2
3print_usage() {
4  echo "Usage: $(basename $0) [options]"
5  echo -e "Builds QEMU and Linux kernel from source.\n"
6  echo -e "  --help\t\t\tDisplay this information."
7  echo -e "  --kernel {arm|arm64}\t\tBuild Linux kernel for the architecture."
8  echo -e "  --qemu\t\t\tBuild QEMU from source."
9  echo -e "  --clean\t\t\tRemove qemu.git and linux.git directories in current directory."
10  exit "$1"
11}
12
13update_repositories() {
14  echo -e "\nUpdating apt repositories. "
15  echo -e "\nPress 'y' to continue or any other key to exit..."
16  read -s -n 1 user_input
17  if [[ $user_input == 'Y' ]] || [[ $user_input == 'y' ]]; then
18    sudo apt update
19  else
20    exit
21  fi
22}
23
24check_dir_exists() {
25  user_input=
26  if [ -d "$1" ]; then
27    echo -e "\n$1 already exists in working directory and will not be updated."
28    echo -e "\nPress 'y' to continue or any other key to exit..."
29    read -s -n 1 user_input
30    if [[ $user_input != 'Y' ]] && [[ $user_input != 'y' ]]; then
31      exit
32    fi
33  fi
34}
35
36invalid_arg() {
37  echo "ERROR: Unrecognized argument: $1" >&2
38  print_usage 1
39}
40
41build_qemu() {
42  echo "Installing QEMU build dependencies ..."
43  sudo apt install git python3-dev libsdl1.2-dev build-essential libpixman-1-dev
44
45  # Checkout source code
46  check_dir_exists "qemu.git"
47  if [ ! -d "qemu.git" ]; then
48    git clone --depth 1 git://git.qemu.org/qemu.git qemu.git
49  fi
50
51  cd qemu.git
52  # We are going to build QEMU Arm and AArch64 system mode emulation.
53  # ./configure --help emits a list of other possible targets supported by QEMU.
54  ./configure --target-list=arm-softmmu,aarch64-softmmu
55  make -j`getconf _NPROCESSORS_ONLN`
56}
57
58build_linux() {
59  echo "Installing Linux kernel build dependencies ..."
60  sudo apt install git bison flex build-essential libssl-dev bc
61
62  check_dir_exists "linux.git"
63
64  if [ ! -d "linux.git" ]; then
65    git clone --depth 1 \
66    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux.git
67  fi
68
69  cd linux.git
70  make mrproper
71
72  if [[ "$1" == "arm" ]]; then
73    echo "Installing gcc-arm-linux-gnueabihf ..."
74    sudo apt install gcc-arm-linux-gnueabihf
75
76    # Configure kernel_branch=master arch=arm config=vexpress_defconfig
77    make O=../linux.build/arm ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- \
78    vexpress_defconfig
79
80    # Trigger Arm kernel build
81    make -j`getconf _NPROCESSORS_ONLN` O=../linux.build/arm ARCH=arm \
82    CROSS_COMPILE=arm-linux-gnueabihf-
83  elif [[ "$1" == "arm64" ]]; then
84    echo "Installing gcc-aarch64-linux-gnu ..."
85    sudo apt install gcc-aarch64-linux-gnu
86
87    # Configure kernel_branch=master arch=arm64 config=defconfig
88    make O=../linux.build/arm64 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
89    defconfig
90
91    # Trigger AArch64 kernel build
92    make -j`getconf _NPROCESSORS_ONLN` O=../linux.build/arm64 ARCH=arm64 \
93    CROSS_COMPILE=aarch64-linux-gnu-
94  else
95    echo "ERROR: Unrecognized architecture: $1" >&2
96    print_usage 1
97    exit
98  fi
99}
100
101clean() {
102  if [ -d "linux.git" ]; then
103    echo "Removing linux.git ..."
104    rm -rf linux.git
105  fi
106
107  if [ -d "linux.build" ]; then
108    echo "Removing linux.build ..."
109    rm -rf linux.build
110  fi
111
112  if [ -d "qemu.git" ]; then
113    echo "Removing qemu.git ..."
114    rm -rf qemu.git
115  fi
116
117  exit
118}
119
120# Parse options
121while [[ $# -gt 0 ]]; do
122  case "${END_OF_OPT}${1}" in
123    -h|--help)   print_usage 0 ;;
124    -k|--kernel)
125      if [ "$2" == "arm64" ] || [ "$2" == "arm" ]; then
126      KERNEL_ARCH=$2
127      else
128        invalid_arg "$2"
129      fi
130      shift;;
131    -q|--qemu)
132        QEMU=1;;
133    -c|--clean)  clean ;;
134    *)           invalid_arg "$1" ;;
135  esac
136  shift
137done
138
139update_repositories
140
141if [ "$KERNEL_ARCH" != "" ]; then
142  pushd .
143  build_linux $KERNEL_ARCH
144  popd
145fi
146
147if [[ $QEMU -eq 1 ]]; then
148  pushd .
149  build_qemu
150  popd
151fi
152