summaryrefslogtreecommitdiff
path: root/compat/bin/get-compat-kernels
blob: 269dfd262d777e631b05a7bdc6ca9d3a7c23e9bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
#!/bin/bash
#
# Copyright (C) 2012, Luis R. Rodriguez <mcgrof@frijolero.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# You can use this script to install all mainline kernels used
# to test compile the Linux kernel compatibility module. You can
# then use ckmake to cross compile against all supported kernels.

# Pretty colors
GREEN="\033[01;32m"
YELLOW="\033[01;33m"
NORMAL="\033[00m"
BLUE="\033[34m"
RED="\033[31m"
PURPLE="\033[35m"
CYAN="\033[36m"
UNDERLINE="\033[02m"

KERNELS=""
KPATH="http://kernel.ubuntu.com/~kernel-ppa/mainline/"

FORCE="0"
KSRC_PREFIX=
# Check whether we're running as root or not
# If we're root stuff things into /usr/src and /lib/modules
# else, use $HOME/compat-ksrc for enabling user-mode builds.
if [[ "$EUID" != "0" ]]; then
	KSRC_PREFIX="$HOME/compat-ksrc"
else
	KSRC_PREFIX="${PWD}/compat-ksrc"
fi


# Create target directories if they doesn't exist
mkdir -p $KSRC_PREFIX/{usr/src,lib/modules}

# List of currently supported kernels that will be downloaded
KERNELS="$KERNELS ${KPATH}/v2.6.24/linux-headers-2.6.24-020624_2.6.24-020624_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.25/linux-headers-2.6.25-020625_2.6.25-020625_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.26/linux-headers-2.6.26-020626_2.6.26-020626_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.27/linux-headers-2.6.27-020627_2.6.27-020627_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.28.10/linux-headers-2.6.28-02062810_2.6.28-02062810_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.29.6/linux-headers-2.6.29-02062906_2.6.29-02062906_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.30.10/linux-headers-2.6.30-02063010_2.6.30-02063010_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.31.13-karmic/linux-headers-2.6.31-02063113_2.6.31-02063113_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.32.60-lucid/linux-headers-2.6.32-02063260_2.6.32-02063260.201210082135_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.33.20-maverick/linux-headers-2.6.33-02063320_2.6.33-02063320.201111071735_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.34.14-maverick/linux-headers-2.6.34-02063414_2.6.34-02063414.201301162135_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.35.13-original-maverick/linux-headers-2.6.35-02063513_2.6.35-02063513.201107261012_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.36.4-natty/linux-headers-2.6.36-02063604_2.6.36-02063604.201102180911_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.37.6-natty/linux-headers-2.6.37-02063706_2.6.37-02063706.201103281005_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.38.8-natty/linux-headers-2.6.38-02063808_2.6.38-02063808.201106040910_all.deb"
KERNELS="$KERNELS ${KPATH}/v2.6.39.4-oneiric/linux-headers-2.6.39-02063904_2.6.39-02063904.201108040905_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.0.65-oneiric/linux-headers-3.0.65-030065_3.0.65-030065.201302171435_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.1.10-precise/linux-headers-3.1.10-030110_3.1.10-030110.201201181135_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.2.38-precise/linux-headers-3.2.38-030238_3.2.38-030238.201302060135_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.3.8-quantal/linux-headers-3.3.8-030308_3.3.8-030308.201206041356_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.4.32-quantal/linux-headers-3.4.32-030432_3.4.32-030432.201302171531_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.5.7-quantal/linux-headers-3.5.7-030507_3.5.7-030507.201210130556_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.6.11-raring/linux-headers-3.6.11-030611_3.6.11-030611.201212171335_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.7.9-raring/linux-headers-3.7.9-030709_3.7.9-030709.201302171607_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.8-raring/linux-headers-3.8.0-030800_3.8.0-030800.201302181935_all.deb"
KERNELS="$KERNELS ${KPATH}/v3.9-rc1-raring/linux-headers-3.9.0-030900rc1_3.9.0-030900rc1.201303060659_all.deb"

# Number of kernels
NUM_KERNELS=$(echo $KERNELS | wc -w)

# ~ 101 MiB for installed space on $KSRC_PREFIX/usr/src/ and $KSRC_PREFIX/lib/modules/
SPACE_PER_KERNEL="101"

# ~13 MiB of both deb files
SPACE_PER_KERNEL_DEB="13"

function get_ubuntu_kernels() {

	ARCH=$(uname -m)
	TARGET=""

	case $ARCH in
	"x86_64")
		TARGET="amd64"
		;;
	"i686")
		TARGET="i386"
		;;
	*)
		echo -e "Unsupported architecture"
		exit
		;;
	esac

	mkdir -p debs
	cd debs

	for i in $KERNELS; do
		FILE=$(basename $i)
		PKG=$(echo $FILE | awk -F"_" '{print $1}')

		# Do not download if installed or deb exists
		if [[ ! -d $KSRC_PREFIX/usr/src/$PKG && ! -f $FILE ]]; then
			# Download the _all.deb
			wget -c $i

			# Download the generic-ARCH headers
			GENERIC_DEB=`echo $i | sed -e "s:\(.*\)_\(.*\)_all.deb:\1-generic_\2_$TARGET.deb:"`
			wget -c $GENERIC_DEB
		fi
	done

	# List of downloaded debs
	DEB_LIST=`ls linux-*.deb 2>/dev/null`

	if [[ -z $DEB_LIST ]]; then
		echo "All kernel sources are found in $KSRC_PREFIX/usr/src."
		exit
	fi

	# Create a temporary directory first
	TEMP_DIR=`mktemp -d`

	for deb in $DEB_LIST; do
		DIR_NAME=$(echo $deb | awk -F"_" '{print $1}')
		if [[ ! -d $KSRC_PREFIX/usr/src/$DIR_NAME ]]; then
			echo "Extracting $deb..."
			ar p $deb data.tar.gz | tar xz --exclude=usr/share -C $TEMP_DIR
		fi
	done

	# Move the extracted folders into the system
	if [[ -d $TEMP_DIR/lib/modules ]]; then

		# Relink lib/modules/*/build/ directories relatively to make it work
		# for regular user based workflows
		if [[ -n $KSRC_PREFIX ]]; then
			echo "Adjusting build/ symlinks for non-root installation..."

			for kernel in $(ls -d $TEMP_DIR/lib/modules/*generic); do
				unlink $kernel/build
				ln -s ../../../usr/src/linux-headers-`basename $kernel` $kernel/build
			done
		fi

		mv $TEMP_DIR/lib/modules/* $KSRC_PREFIX/lib/modules
	fi
	if [[ -d $TEMP_DIR/usr/src ]]; then
		# Because of a bug in make < 3.82, mixed implicit and normal
		# rules do not cause harm. Since the bug is fixed in the new make
		# we have to adjust older kernel's Makefiles to fix the bug.
		sed -i 's#^/ %/:#%/:#' $TEMP_DIR/usr/src/linux-headers-2.6.2[45678]-0*/Makefile &>/dev/null

		mv $TEMP_DIR/usr/src/* $KSRC_PREFIX/usr/src
	fi

	# Remove the temporary directory
	rm -rf $TEMP_DIR
}

function rebuild_header_binary_deps() {
	if [[ ! -d ${KSRC_PREFIX}/lib/modules/ ]]; then
		echo "You do not seem to have any vanilla kernels available to fix"
		exit 1
	fi

	COUNT=$(ls -d ${KSRC_PREFIX}/lib/modules/*generic | wc -l)
	if [[ $COUNT -le 0 ]]; then
		echo "You do not seem to have any vanilla kernels available to fix"
		exit 1
	fi

	for kernel in $(ls -d ${KSRC_PREFIX}/lib/modules/*generic | grep -E "/3.[2-9]|/[4-9]"); do
		echo $kernel

		count=0
		while [[ $count -ne 4 ]]; do
			for i in basic mod genksyms; do
				if [[ $count -eq 0 ]]; then
					make -C ${kernel}/build/ M=scripts/${i}/ clean > /dev/null 2>&1
				fi
				make -C ${kernel}/build/ M=scripts/${i}/ > /dev/null 2>&1
			done
			let count=$count+1
		done
	done
}

function usage() {
	echo -e "Usage: $0 [ -r ] [ -f ] "
	echo -e "-r Rebuilds binaries required in kernel headers. Use"
	echo -e "   this option if you've already ran this script and"
	echo -e "   just need to fix the libc versions against which"
	echo -e "   the binaries in the headers files are linked against. "
	echo -e "   This was added since kernels >= 3.4 require"
	echo -e "   a glibc >= 2.14 for memcpy(), and not all Linux"
	echo -e "   distributions have such versions of glibc."
	echo -e ""
	echo -e "-f Force running, do not ask"
}

if [[ $# -gt 3 ]]; then
	usage
	exit 1
fi

if [[ $1 == "-r" ]]; then
	rebuild_header_binary_deps
	exit
fi

if [[ $1 == "-f" ]]; then
	FORCE="1"
	shift
fi

# Check for the availability of 'ar' before continuing
which ar 2>&1 > /dev/null
if [[ $? -ne 0 ]]; then
	echo -e "${GREEN}ar${NORMAL} is not avilable, typically this is available through a package called binutils"
	echo -e "Install binutils and run this script again..."
	exit 1
fi

echo -e ""

if [[ ! -n $KSRC_PREFIX ]]; then
	echo -e "** Running as a privileged user!"
	echo -e "** You are trying to force using ${BLUE}${KSRC_PREFIX}/lib/modules${NORMAL} and ${BLUE}${KSRC_PREFIX}/usr/src${NORMAL} ..."
	echo -e "** This is a terrible idea. Consider running as a regular user."
	echo -e ""
	read -p "Do you still want to continue (y/N)? "
	if [[ "${REPLY}" != "y" ]]; then
		echo -e "Bailing out !"
		exit 1
	fi
fi

echo -e "This will download ${YELLOW}${NUM_KERNELS}${NORMAL} kernel headers to allow you to"
echo -e "cross compile any module over these kernels with ${GREEN}ckmake${NORMAL}."
echo -e "The download payload is about ${YELLOW}~ $((${SPACE_PER_KERNEL_DEB} * ${NUM_KERNELS})) ${CYAN}MiB${NORMAL}, once uncompressed"
echo -e "it will stash kernel header files under ${BLUE}$KSRC_PREFIX/usr/src/${NORMAL}"
echo -e "and ${BLUE}$KSRC_PREFIX/lib/modules/${NORMAL} and consume about ~ ${YELLOW}$((${NUM_KERNELS} * ${SPACE_PER_KERNEL})) ${RED}MiB${NORMAL} of space."
echo -e ""
echo -e "The kernel headers used are from ${PURPLE}${UNDERLINE}Vanilla${NORMAL} kernels"
echo -e "from the Ubuntu mainline / vanilla kernel PPA and are extracted"
echo -e "using ${GREEN}ar${NORMAL} and ${GREEN}tar${NORMAL}:"
echo -e ""
echo -e "${BLUE}http://kernel.ubuntu.com/~kernel-ppa/mainline/${NORMAL}"
echo -e ""

if [[ "$FORCE" != "1" ]]; then
	read -p "Do you still want to continue (y/N)? "
	if [[ "${REPLY}" != "y" ]]; then
		echo -e "Bailing out !"
		exit 1
	fi
fi

get_ubuntu_kernels
echo -e "Vanilla kernels headers ${BLUE}installed${NORMAL}, "
echo -e "now going to ${GREEN}rebuild${NORMAL} some binary dependencies..."
sleep 1
rebuild_header_binary_deps