Post

Toolchain Kernel ARM64

Introduction

Pour construire le kernel, vous aurez juste besoin de ce fichier :

  • build.sh
  • toolchain.sh

Fichiers requis

build.sh

[Fichier]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#/bin/bash
# 2022-10-15

clear

OUTFOLDER=/opt/build/toolchain/raspberrypi/arm64/kernel

KERNEL_MAIN=$1
KERNEL_PATCH=$2
KERNEL_RT=$3

# overrides
KERNEL_MAIN=6.0
KERNEL_PATCH=/opt/scripts/toolchain/arm64/patchs/kernel_config_patch_6.0.0.patch
KERNEL_RT=

bash toolchain.sh $OUTFOLDER $KERNEL_MAIN $KERNEL_PATCH $KERNEL_RT

exit 0

toolchain.sh

[Fichier]

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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
#!/bin/bash
# 2022-10-15

KERNEL_DEFAULT=6.0

OUTFOLDER=$1
KERNEL_MAIN=$2
KERNEL_PATCH=$3
KERNEL_RT=$4
PATCH_FILE=
KERNEL=
FINAL_FOLDER=$OUTFOLDER
BASE_FOLDER=$FINAL_FOLDER

SKIP_PACMAN=1
SKIP_TOOLCHAIN_CREATION=1
SKIP_ADD_FOLDER=0
SKIP_GRAB_KERNEL=0
SKIP_KERNEL_RT=1
SKIP_BUILD_KERNEL=0
SKIP_BUILD_FINAL=0

#
# https://www.raspberrypi.com/documentation/computers/linux_kernel.html#cross-compiling-the-kernel
# https://wiki.archlinux.org/title/Cross-compiling_tools_package_guidelines
# https://ilyas-hamadouche.medium.com/creating-a-cross-platform-toolchain-for-raspberry-pi-4-5c626d908b9d
#

function header() {
	clear
	echo ">>> Toolchain Archlinux / RPi 4 ARM64 / Kernel"
	echo "--------------------------------------------------"
	echo ">> DATE     : $CURRENT"
	echo ">> OUTFOLDER: $OUTFOLDER"
	echo ">> BRANCH   : $BRANCH"
	echo ">> PATCH    : $PATCH_FILE"
	echo ">> RT PATCH : $KERNEL_RT"
	echo ">> VERSION  : $VERSION"
	echo ">> KERNEL   : $KERNEL"
	echo "--------------------------------------------------"
	echo ""
}

function wait() {
	read -p "> [Press enter to continue] "
}

header
echo "> Prepare things"
# if kernel branch is not given, use default
if [ -z "$KERNEL_MAIN" ]; then
	KERNEL_MAIN=$KERNEL_DEFAULT
fi
# if patch is given but file doesn't exist, remove it
if [ ! -z "$KERNEL_PATCH" ]; then
	if [ ! -f "$KERNEL_PATCH" ]; then
		KERNEL_PATCH=
	else
		PATCH_FILE=$(basename $KERNEL_PATCH)
	fi
fi

# kernel branch/version
MAIN=$KERNEL_MAIN
BRANCH=rpi-$MAIN.y

# use current date as base kernel folder
CURRENT=$(date '+%Y-%m-%d')

# folders
OUTFOLDER=$BASE_FOLDER/$CURRENT

header
echo "> Create working folders"
if [ ! -d "~/src" ]; then
	mkdir -p ~/src
fi
if [ ! -d "$OUTFOLDER" ]; then
	mkdir -p $OUTFOLDER
fi
cd $OUTFOLDER
if [ ! -d "ctng" ]; then
	mkdir ctng
fi
cd $OUTFOLDER

if [ ! -z "$PATCH_FILE" ]; then
	cp $KERNEL_PATCH $OUTFOLDER/$PATCH_FILE
fi

if [ "$SKIP_PACMAN" == "0" ]; then
	header
	echo "> Install crosstool-ng"
	wait
	sudo pacman -S --needed crosstool-ng
fi

if [ "$SKIP_TOOLCHAIN_CREATION" == "0" ]; then
	header
	echo "> Create toolchain for RPi 4"
	echo ">> Set 'Render the toolchain read-only' to false (uncheck)"
	wait
	ulimit -n 4096 now
	#
	#  Make 1 changes:
	#  1. Allow extending the toolchain after it is created (by default, it is created as read-only):
	#      Paths and misc options -> Render the toolchain read-only ->false
	#
	cd ctng
	ct-ng -j$(nproc) aarch64-rpi4-linux-gnu
	ct-ng -j$(nproc) menuconfig

	header
	# (path: ${HOME}/x-tools/aarch64-rpi4-linux-gnu)
	echo "> Build the toolchain"
	ct-ng -j$(nproc) build
fi

header
echo "> Add toolchain path"
cd $OUTFOLDER
PATH=$PATH:~/x-tools/aarch64-rpi4-linux-gnu/bin

if [ "$SKIP_ADD_FOLDER" == "0" ]; then
	header
	echo "> Add folders"
	wait
	sudo rm -rf build
	mkdir -p build/mnt/fat32/overlays
	mkdir -p build/mnt/ext4/opt/build/kernel/$CURRENT/$BRANCH
fi

if [ ! -z "$PATCH_FILE" ]; then
	cp $OUTFOLDER/$PATCH_FILE build/mnt/$PATCH_FILE
fi

if [ "$SKIP_GRAB_KERNEL" == "0" ]; then
	header
	echo "> Get kernel sources"
	rm -rf linux
	rm -rf $BRANCH
	git clone --branch $BRANCH --depth=1 https://github.com/raspberrypi/linux
	mv linux $BRANCH
fi
cd $BRANCH

header
echo "> Get exact kernel version"
FILE=Makefile
KVERSION=VERSION
KPATCHLEVEL=PATCHLEVEL
KSUBLEVEL=SUBLEVEL
KEXTRAVERSION=EXTRAVERSION
	GET_VAR=$KVERSION && KVERSION=$(grep --color=never -Po "^${GET_VAR}\ =\ \K.*" "${FILE}" || true)
	GET_VAR=$KPATCHLEVEL && KPATCHLEVEL=$(grep --color=never -Po "^${GET_VAR}\ =\ \K.*" "${FILE}" || true)
	GET_VAR=$KSUBLEVEL && KSUBLEVEL=$(grep --color=never -Po "^${GET_VAR}\ =\ \K.*" "${FILE}" || true)
	GET_VAR=$KEXTRAVERSION && KEXTRAVERSION=$(grep --color=never -Po "^${GET_VAR}\ =\ \K.*" "${FILE}" || true)
VERSION=$KVERSION.$KPATCHLEVEL.$KSUBLEVEL

if [ "$SKIP_BUILD_KERNEL" == "0" ]; then
	header

	if [ "$SKIP_KERNEL_RT" == "0" ]; then
		echo "> Apply RT patchs"
		wget https://mirrors.edge.kernel.org/pub/linux/kernel/projects/rt/$MAIN/patch-$MAIN-$KERNEL_RT.patch.gz
		if [ ! -f patch-$MAIN-$KERNEL_RT.patch.gz ]; then
			echo ">> No Kernel RT patch found... Not appying !"
			wait
		else
			gzip -cd patch-$MAIN-$KERNEL_RT.patch.gz | patch -p1 --verbose
		fi
	fi

	header
	echo "> Generate default config"
	KERNEL=kernel8
	env PATH=$PATH make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-rpi4-linux-gnu- bcm2711_defconfig

    header
	echo "> Disable Debug Infos"
	env PATH=$PATH scripts/config --disable DEBUG_INFO

	header
	echo "> Backup config"
	cp -f .config .config.original

	if [ ! -z "$PATCH_FILE" ]; then
		header
		echo "> Apply config patch"
		cp $OUTFOLDER/$PATCH_FILE $PATCH_FILE
		patch < $OUTFOLDER/$PATCH_FILE
	fi

	# setup kernel config and generate diff patch from original
	# or patch default config with defined patch
	header
	echo "> Generate config"
	echo ">> If you specified patch, you may save/exit only"
    echo ">> Feel free to adjust settings too..."
	wait
	env PATH=$PATH make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-rpi4-linux-gnu- menuconfig
	if [ ! -f ".config" ]; then
		header
		echo "> !!! No .config (menuconfig) found!"
		echo "> !!! Abort!"
		exit 1
	fi

    header
    echo "> Create config patch from original for current version"
    diff -u .config.original .config > $OUTFOLDER/kernel_config_patch_$VERSION.patch

	header
	echo "> Disable Debug Info"
	wait
	env PATH=$PATH scripts/config --disable DEBUG_INFO

	header
	echo "> Compile kernel"
	wait
	env PATH=$PATH make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-rpi4-linux-gnu- Image modules dtbs

	header
	echo "> Install modules"
	env PATH=$PATH make -j$(nproc) ARCH=arm64 CROSS_COMPILE=aarch64-rpi4-linux-gnu- INSTALL_MOD_PATH=../build/mnt/ext4 modules_install
else
	KERNEL=kernel8
fi
KERNEL=$KERNEL-$VERSION-v8+

header
echo "> Copy files"
wait
sudo cp arch/arm64/boot/Image ../build/mnt/fat32/$KERNEL.img
sudo cp arch/arm64/boot/dts/broadcom/*.dtb ../build/mnt/fat32/
sudo cp arch/arm64/boot/dts/overlays/*.dtb* ../build/mnt/fat32/overlays/
sudo cp arch/arm64/boot/dts/overlays/README ../build/mnt/fat32/overlays/

header
echo "> Adjust permissions"
wait
cd $OUTFOLDER
sudo chmod -R 0755 build/mnt/fat32/

header
echo "> Copy kernel source"
cd $OUTFOLDER
sudo mkdir -p build/mnt/ext4/opt/build/kernel/$CURRENT/$BRANCH
sudo cp -r $BRANCH build/mnt/ext4/opt/build/kernel/$CURRENT/

header
echo "> Remove symlinks..."
wait
cd $OUTFOLDER
cd build/mnt/ext4/lib/modules/$VERSION-v8+/
sudo rm build
sudo rm source


header
echo "> Create post-install script..."
cd $OUTFOLDER
sudo chown -R 1000:1000 build
cd build/mnt/
rm -f install.sh
touch install.sh
tee -a install.sh <<EOF
#!/bin/bash
clear

echo ">>> Installation of kernel [$KERNEL]"

echo "> Setup permissions (fat32)"
chmod -R 0755 fat32/

echo "> Setup owner (root)"
chown -R root:root fat32/
chown -R root:root ext4/

echo "> Copy files (fat32, ext4)"
cp -rf fat32/.      /boot/
cp -rf ext4/lib/.   /lib/
cp -rf ext4/opt/.   /opt/

echo "> Symlink kernel source to modules ($VERSION-v8+)"
rm -f /lib/modules/$VERSION-v8+/build
rm -f /lib/modules/$VERSION-v8+/source
ln -s /opt/build/kernel/$CURRENT/$BRANCH /lib/modules/$VERSION-v8+/build
ln -s /opt/build/kernel/$CURRENT/$BRANCH /lib/modules/$VERSION-v8+/source

echo "> Add kernel line (as disabled) to config.txt"
echo '#kernel=$KERNEL.img' >> /boot/config.txt

echo "> Done!"
EOF
chmod +x install.sh

header
echo "> Adjust rights"
wait
cd $OUTFOLDER
sudo chown -R root:root build

if [ "$SKIP_BUILD_FINAL" == "0" ]; then
	header
	echo "> Build archive"
	cd $OUTFOLDER/build/mnt/
	sudo tar -cf $OUTFOLDER/rpi_kernel_arm64_$VERSION.tar .
    sudo chown 1000:1000 $OUTFOLDER/rpi_kernel_arm64_$VERSION.tar

	header
	echo "> Compress archive"
	cd $OUTFOLDER
	sudo pigz --force --best rpi_kernel_arm64_$VERSION.tar
	sudo chown 1000:1000 rpi_kernel_arm64_$VERSION.tar.gz
fi

header
echo "> Create install script"
rm -f install.sh
touch install.sh
tee -a install.sh <<EOF
#!/bin/bash
clear

echo ">>> Extraction of kernel [$KERNEL]"

echo "> Unzip archive"
pigz -d rpi_kernel_arm64_$VERSION.tar.gz
chown root:root rpi_kernel_arm64_$VERSION.tar

echo "> Untar archive"
tar -xf rpi_kernel_arm64_$VERSION.tar

echo "> Set install script as root/executable"
chown root:root install.sh
chmod +x install.sh

echo "> Proceed to install kernel with: [bash install.sh]"
echo "> Done!"
EOF
chmod +x install.sh

header
echo "> Done!"

exit 0

Procédure

Pour lancer la construction du kernel, il suffit de copier le script dans le répertoire /opt/script/toolchain puis de le lancer :

1
sudo chmod +x build.sh && sudo chmod +x toolchain.sh && sudo bash build.sh

NB: Dans cette version, cela compilera le dernier kernel en version 6.0 disponible.Pour compiler une autre version, il convient d’éditer le script pour remplacer la valeur MAIN par une autre version… Par exemple 7.0.

Et après ?

Il suffit de copier les fichiers suivant sur votre Pi :

  • install.sh
  • rpi_kernel_arm64_6.0.0.tar.gz

Vous lancez une première fois install.sh qui va décompresser et préparer dans le répertoire courant les fichiers pour l’installation.

Ensuite, vous relancez install.sh qui là va installer (copier) tous les fichiers nécessaires au kernel au bon endroit.

Pour activer le kernel il vous faut éditer manuellement le fichier /boot/config.txt et ne conserver en non commenté que la ligne kernel= correspondant à la version que vous venez de préparer.

Ensuite… et bien reboot !

Conclusion

Au bout d’un petit moment, dépendant de la puissance de votre machine, vous aurez une archive contenant tout le kernel ARM64 pour un Raspbery Pi 4.

Cet article est sous licence CC BY 4.0 par l'auteur.

© 2022- Olivier. Certains droits réservés.

Propulsé par τζ avec le thème Χ