Add documentation and files related to initial host setup
[csit.git] / resources / tools / disk-image-builder / nested / build.sh
1 #!/bin/sh
2
3 # Copyright (c) 2016 Cisco and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # Note: In order to limit the damage this script can do, it is recommended
17 # to NOT run as root.
18
19 #
20 # 1. Download buildroot
21 # 2. Build buildroot kernel and root file system as per
22 #    config files included in this package
23 # 3. Create empty disk image and extract buildroot root
24 #    file system onto it, make it bootable
25 # 4. Apply any patches/additions included in this package
26 #
27 BUILD_DIR="$(dirname $0)/build"
28
29 BUILDROOT_NAME='buildroot-2016.02'
30 BUILDROOT_DIR="${BUILD_DIR}/${BUILDROOT_NAME}"
31 BUILDROOT_TARBALL="${BUILDROOT_NAME}.tar.gz"
32 BUILDROOT_URL="https://buildroot.org/downloads/${BUILDROOT_TARBALL}"
33 BUILDROOT_OUTPUT="${BUILDROOT_DIR}/output/images/rootfs.tar"
34
35 DISK_FREE_SIZE=8388608              # Min. free space on disk (8 MB)
36 DISK_ROUND_TO_NEAREST=16777216      # Round disk size up to nearest (16 MB)
37
38 VERSION=$(cat $(dirname $0)/CHANGELOG  | grep '^## ' | head -1 | sed -e 's/.*\[\(.*\)\].*/\1/')
39 if [ "${VERSION}" = "" ]
40 then
41   echo "Unable to determine build version from CHANGELOG file. Make sure"
42   echo "that there is an entry for the most recent version in CHANGELOG,"
43   echo "and that the entry is formated like"
44   echo
45   echo "## [1.0] - 2016-05-16"
46   exit 1
47 fi
48
49 echo Building version: ${VERSION}
50 echo $VERSION > ${BUILD_DIR}/VERSION
51 echo "NESTED_VERSION=${VERSION}" > ${BUILD_DIR}/VERSION_HIDDEN
52 img_name="${BUILD_DIR}/csit-nested-${VERSION}.img"
53
54 # Normally no need to touch the variables below
55 DISK_SECT_SIZE=512
56 DISK_HEADS=16
57 DISK_SECT_PER_TRACK=63
58 DISK_RESERVED_SECTORS=2048
59
60 MOUNT_TMPDIR="${BUILD_DIR}/tmp-mount"
61
62 set -e
63
64 # Download buildroot if not already there
65 wget -P ${BUILD_DIR} -N $BUILDROOT_URL
66 tar -C ${BUILD_DIR} -xzf ${BUILD_DIR}/$BUILDROOT_TARBALL
67
68 cp -p buildroot-config $BUILDROOT_DIR/.config
69 cp -p kernel-defconfig $BUILDROOT_DIR/kernel-defconfig
70 make -C $BUILDROOT_DIR
71
72 if [ ! -f ${BUILDROOT_OUTPUT} ]
73 then
74   echo "Buildroot compiled OK, but root file system ${BUILDROOT_OUTPUT}"
75   echo "does not exist. Somethig is wrong. Exiting."
76   exit 1
77 fi
78
79 # If we got here, it means we downloaded (if applicable) and built (if
80 # applicable) buildroot OK.
81 #
82 # Now let's calculate the required disk size, and build an empty disk.
83
84 buildroot_size=$(stat -c%s ${BUILDROOT_OUTPUT})
85 desired_size=$(( ${buildroot_size} + ${DISK_FREE_SIZE} ))
86 rounded_size=$(( ((${desired_size}/${DISK_ROUND_TO_NEAREST})+1) * \
87                   ${DISK_ROUND_TO_NEAREST} ))
88
89 echo "Actual root FS size: ${buildroot_size}"
90 echo "Root FS size + desired free space (${DISK_FREE_SIZE}): ${desired_size}"
91 echo "Root FS size rounded to nearest ${DISK_ROUND_TO_NEAREST}:" \
92   "${rounded_size} ($(( ${rounded_size} / 1024 / 1024 )) MB)"
93
94 # In a normal world, we'd be creating a full-size empty image with "dd", an
95 # then use fdisk to partition it, and a tool like "kpartx" to map this into
96 # individual partitions. We'd then map the partition we're interested in.
97 # However, in order to avoid messing with /dev/mapper, we can also create
98 # our actual partition first, and then merge it with the MBR+partition table
99 # "prefix" to obtain our full disk.
100
101 sectors=$(( ${rounded_size} / ${DISK_SECT_SIZE} ))
102
103 disk_prefix=${img_name}.prefix
104 disk_main=${img_name}.main
105
106 dd if=/dev/zero of=${disk_prefix} bs=${DISK_SECT_SIZE} \
107   count=${DISK_RESERVED_SECTORS}
108 dd if=/dev/zero of=${disk_main} bs=${DISK_SECT_SIZE} \
109   count=$(( $sectors - ${DISK_RESERVED_SECTORS} ))
110
111 # Format and mount the root file system
112 mkfs.ext2 -F -L root ${disk_main}
113 mkdir -p ${MOUNT_TMPDIR}
114 sudo mount -o loop ${disk_main} ${MOUNT_TMPDIR}
115 trap "sudo umount ${MOUNT_TMPDIR}" EXIT
116
117 # Extract the root filesystem
118 echo "Extracting root filesystem..."
119 sudo tar -C ${MOUNT_TMPDIR} -xf ${BUILDROOT_OUTPUT}
120
121 # Apply any patches
122 echo "Applying patches/modifications"
123 mydir=$(pwd)
124 cd ${MOUNT_TMPDIR}
125 sudo run-parts -v  ${mydir}/patches
126 cd ${mydir}
127
128 # Copy version and changelog
129 sudo cp ${BUILD_DIR}/VERSION ${MOUNT_TMPDIR}/
130 sudo cp ${mydir}/CHANGELOG ${MOUNT_TMPDIR}/
131 # Also embed this into a hidden file that we can easily retrieve with
132 # "cat <disk image> | strings | grep NESTED_VERSION"
133 sudo cp ${BUILD_DIR}/VERSION_HIDDEN ${MOUNT_TMPDIR}/.VERSION.HIDDEN
134
135 # Unmount root filesystem
136 sudo umount ${MOUNT_TMPDIR}
137 trap EXIT
138 rmdir ${MOUNT_TMPDIR}
139
140 # Now create our larger disk
141 cat ${disk_prefix} ${disk_main} > ${img_name}
142 rm -f ${disk_prefix} ${disk_main}
143
144 # Create partition table on the disk
145 sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << _EOF | fdisk -H ${DISK_HEADS} -S ${DISK_SECT_PER_TRACK} ${img_name}
146   o # clear the in memory partition table
147   n # new partition
148   p # primary partition
149   1 # partition number 1
150   ${DISK_RESERVED_SECTORS} # Start a few KB into the disk, leave room for GRUB
151     # Default - all the way through the end of the disk
152   a # make a partition bootable
153   1 # bootable partition is partition 1
154   p # print the in-memory partition table
155   w # write the partition table
156   q # and we're done
157 _EOF
158
159 disk_cylinders=$(fdisk -l -H ${DISK_HEADS} -S ${DISK_SECT_PER_TRACK} ${img_name} | \
160   grep cylinders | \
161   sed -e 's/.* \([0-9][0-9]*\) cylinders.*/\1/')
162
163 echo "Disk has ${disk_cylinders} cylinders"
164
165 # Install GRUB bootloader on the disk image
166 ${BUILDROOT_DIR}/output/host/sbin/grub --device-map=/dev/null <<_EOF
167 device (hd0) ${img_name}
168 geometry (hd0) ${disk_cylinders} ${DISK_HEADS} ${DISK_SECT_PER_TRACK}
169 root (hd0,0)
170 setup (hd0)
171 quit
172 _EOF
173
174 echo
175 echo
176 echo
177 echo "Your image should be ready in:"
178 ls -l ${img_name}