CSIT-472: Update of DPDK to 16.11 in Nested VM
[csit.git] / resources / tools / disk-image-builder / nested / build.sh
1 #!/bin/sh -e
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 mkdir -p ${BUILD_DIR}
50
51 echo Building version: ${VERSION}
52 echo $VERSION > ${BUILD_DIR}/VERSION
53 echo "NESTED_VERSION=${VERSION}" > ${BUILD_DIR}/VERSION_HIDDEN
54 img_name="${BUILD_DIR}/csit-nested-${VERSION}.img"
55
56 # Normally no need to touch the variables below
57 DISK_SECT_SIZE=512
58 DISK_HEADS=16
59 DISK_SECT_PER_TRACK=63
60 DISK_RESERVED_SECTORS=2048
61
62 MOUNT_TMPDIR="${BUILD_DIR}/tmp-mount"
63
64 set -e
65
66 # Download buildroot if not already there
67 wget -P ${BUILD_DIR} -N $BUILDROOT_URL
68 tar -C ${BUILD_DIR} -xzf ${BUILD_DIR}/$BUILDROOT_TARBALL
69
70 # Apply DPDK patch to buildroot. Do not fail if this patch has already been applied.
71 patch -N -d ${BUILDROOT_DIR} -p1 < buildroot-patches/dpdk.patch || /bin/true
72
73 cp -p buildroot-config $BUILDROOT_DIR/.config
74 cp -p kernel-defconfig $BUILDROOT_DIR/kernel-defconfig
75 make -C $BUILDROOT_DIR
76
77 if [ ! -f ${BUILDROOT_OUTPUT} ]
78 then
79   echo "Buildroot compiled OK, but root file system ${BUILDROOT_OUTPUT}"
80   echo "does not exist. Somethig is wrong. Exiting."
81   exit 1
82 fi
83
84 # If we got here, it means we downloaded (if applicable) and built (if
85 # applicable) buildroot OK.
86 #
87 # Now let's calculate the required disk size, and build an empty disk.
88
89 buildroot_size=$(stat -c%s ${BUILDROOT_OUTPUT})
90 desired_size=$(( ${buildroot_size} + ${DISK_FREE_SIZE} ))
91 rounded_size=$(( ((${desired_size}/${DISK_ROUND_TO_NEAREST})+1) * \
92                   ${DISK_ROUND_TO_NEAREST} ))
93
94 echo "Actual root FS size: ${buildroot_size}"
95 echo "Root FS size + desired free space (${DISK_FREE_SIZE}): ${desired_size}"
96 echo "Root FS size rounded to nearest ${DISK_ROUND_TO_NEAREST}:" \
97   "${rounded_size} ($(( ${rounded_size} / 1024 / 1024 )) MB)"
98
99 # In a normal world, we'd be creating a full-size empty image with "dd", an
100 # then use fdisk to partition it, and a tool like "kpartx" to map this into
101 # individual partitions. We'd then map the partition we're interested in.
102 # However, in order to avoid messing with /dev/mapper, we can also create
103 # our actual partition first, and then merge it with the MBR+partition table
104 # "prefix" to obtain our full disk.
105
106 sectors=$(( ${rounded_size} / ${DISK_SECT_SIZE} ))
107
108 disk_prefix=${img_name}.prefix
109 disk_main=${img_name}.main
110
111 dd if=/dev/zero of=${disk_prefix} bs=${DISK_SECT_SIZE} \
112   count=${DISK_RESERVED_SECTORS}
113 dd if=/dev/zero of=${disk_main} bs=${DISK_SECT_SIZE} \
114   count=$(( $sectors - ${DISK_RESERVED_SECTORS} ))
115
116 # Format and mount the root file system
117 mkfs.ext2 -F -L root ${disk_main}
118 mkdir -p ${MOUNT_TMPDIR}
119 sudo mount -o loop ${disk_main} ${MOUNT_TMPDIR}
120 trap "sudo umount ${MOUNT_TMPDIR}" EXIT
121
122 # Extract the root filesystem
123 echo "Extracting root filesystem..."
124 sudo tar -C ${MOUNT_TMPDIR} -xf ${BUILDROOT_OUTPUT}
125
126 # Apply any patches
127 echo "Applying patches/modifications"
128 mydir=$(pwd)
129 cd ${MOUNT_TMPDIR}
130 sudo run-parts -v  ${mydir}/image-patches
131 cd ${mydir}
132
133 # Copy version and changelog
134 sudo cp ${BUILD_DIR}/VERSION ${MOUNT_TMPDIR}/
135 sudo cp ${mydir}/CHANGELOG ${MOUNT_TMPDIR}/
136 # Also embed this into a hidden file that we can easily retrieve with
137 # "cat <disk image> | strings | grep NESTED_VERSION"
138 sudo cp ${BUILD_DIR}/VERSION_HIDDEN ${MOUNT_TMPDIR}/.VERSION.HIDDEN
139
140 # Unmount root filesystem
141 sudo umount ${MOUNT_TMPDIR}
142 trap EXIT
143 rmdir ${MOUNT_TMPDIR}
144
145 # Now create our larger disk
146 cat ${disk_prefix} ${disk_main} > ${img_name}
147 rm -f ${disk_prefix} ${disk_main}
148
149 # Create partition table on the disk
150 sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << _EOF | fdisk -H ${DISK_HEADS} -S ${DISK_SECT_PER_TRACK} ${img_name}
151   o # clear the in memory partition table
152   n # new partition
153   p # primary partition
154   1 # partition number 1
155   ${DISK_RESERVED_SECTORS} # Start a few KB into the disk, leave room for GRUB
156     # Default - all the way through the end of the disk
157   a # make a partition bootable
158   1 # bootable partition is partition 1
159   p # print the in-memory partition table
160   w # write the partition table
161   q # and we're done
162 _EOF
163
164 disk_cylinders=$(fdisk -l -H ${DISK_HEADS} -S ${DISK_SECT_PER_TRACK} ${img_name} | \
165   grep cylinders | \
166   sed -e 's/.* \([0-9][0-9]*\) cylinders.*/\1/')
167
168 echo "Disk has ${disk_cylinders} cylinders"
169
170 # Install GRUB bootloader on the disk image
171 ${BUILDROOT_DIR}/output/host/sbin/grub --device-map=/dev/null <<_EOF
172 device (hd0) ${img_name}
173 geometry (hd0) ${disk_cylinders} ${DISK_HEADS} ${DISK_SECT_PER_TRACK}
174 root (hd0,0)
175 setup (hd0)
176 quit
177 _EOF
178
179 echo
180 echo
181 echo
182 echo "Your image should be ready in:"
183 ls -l ${img_name}