1#!/bin/bash -e
2
3KERNELS=$(ls | grep kernel- || true)
4
5update_kernel()
6{
7	# Fallback to current kernel
8	RK_KERNEL_VERSION=${RK_KERNEL_VERSION:-$(kernel_version)}
9
10	# Fallback to 5.10 kernel
11	RK_KERNEL_VERSION=${RK_KERNEL_VERSION:-5.10}
12
13	# Update .config
14	KERNEL_CONFIG="RK_KERNEL_VERSION=\"$RK_KERNEL_VERSION\""
15	if ! grep -q "^$KERNEL_CONFIG$" "$RK_CONFIG"; then
16		sed -i "s/^RK_KERNEL_VERSION=.*/$KERNEL_CONFIG/" "$RK_CONFIG"
17		"$SCRIPTS_DIR/mk-config.sh" olddefconfig &>/dev/null
18	fi
19
20	[ "$(kernel_version)" != "$RK_KERNEL_VERSION" ] || return 0
21
22	# Update kernel
23	KERNEL_DIR=kernel-$RK_KERNEL_VERSION
24	echo "switching to $KERNEL_DIR"
25	if [ ! -d "$KERNEL_DIR" ]; then
26		echo "$KERNEL_DIR not exist!"
27		exit 1
28	fi
29
30	rm -rf kernel
31	ln -rsf $KERNEL_DIR kernel
32}
33
34do_build()
35{
36	if [ "$DRY_RUN" ]; then
37		echo -e "\e[35mCommands of building $1:\e[0m"
38	else
39		echo "=========================================="
40		echo "          Start building $1"
41		echo "=========================================="
42	fi
43
44	check_config RK_KERNEL_DTS_NAME RK_KERNEL_CFG RK_BOOT_IMG || return 0
45
46	run_command $KMAKE $RK_KERNEL_CFG $RK_KERNEL_CFG_FRAGMENTS
47
48	if [ -z "$DRY_RUN" ]; then
49		"$SCRIPTS_DIR/check-kernel.sh"
50	fi
51
52	case "$1" in
53		kernel-config)
54			KERNEL_CONFIG_DIR="kernel/arch/$RK_KERNEL_ARCH/configs"
55			run_command $KMAKE menuconfig
56			run_command $KMAKE savedefconfig
57			run_command mv kernel/defconfig \
58				"$KERNEL_CONFIG_DIR/$RK_KERNEL_CFG"
59			;;
60		kernel*)
61			run_command $KMAKE "$RK_KERNEL_DTS_NAME.img"
62		       	run_command $KMAKE modules
63			rm -fr $SDK_DIR/buildroot/output/$RK_BUILDROOT_CFG/target/lib/modules/5.10.160
64			run_command $KMAKE modules_install INSTALL_MOD_PATH=$SDK_DIR/buildroot/output/$RK_BUILDROOT_CFG/target/usr
65
66			# The FIT image for initrd would be packed in rootfs stage
67			if [ -n "$RK_BOOT_FIT_ITS" ]; then
68				if [ -z "$RK_ROOTFS_INITRD" ]; then
69					run_command \
70						"$SCRIPTS_DIR/mk-fitimage.sh" \
71						"kernel/$RK_BOOT_IMG" \
72						"$RK_BOOT_FIT_ITS" \
73						"$RK_KERNEL_IMG"
74				fi
75			fi
76			;;
77		modules)
78			run_command $KMAKE modules
79			if [ "$RK_ROOTFS_SYSTEM" == "ubuntu" ]; then
80				if [ -f "$SDK_DIR/ubuntu/jammy-rootfs.img" ]; then
81					mkdir -p $SDK_DIR/ubuntu/rootfs_mnt
82					sudo mount $SDK_DIR/ubuntu/jammy-rootfs.img $SDK_DIR/ubuntu/rootfs_mnt
83					sudo -E $KMAKE modules_install INSTALL_MOD_PATH=$SDK_DIR/ubuntu/rootfs_mnt
84					sudo umount $SDK_DIR/ubuntu/rootfs_mnt
85					rm -r $SDK_DIR/ubuntu/rootfs_mnt
86				fi
87			else
88				rm -fr $SDK_DIR/buildroot/output/$RK_BUILDROOT_CFG/target/lib/modules/5.10.160
89				run_command $KMAKE modules_install INSTALL_MOD_PATH=$SDK_DIR/buildroot/output/$RK_BUILDROOT_CFG/target/usr
90			fi
91			;;
92	esac
93}
94
95# Hooks
96
97usage_hook()
98{
99	for k in $KERNELS; do
100		echo -e "$k[:cmds]               \tbuild kernel ${k#kernel-}"
101	done
102
103	echo -e "kernel[:cmds]                    \tbuild kernel"
104	echo -e "modules[:cmds]                   \tbuild kernel modules"
105	echo -e "linux-headers[:cmds]             \tbuild linux-headers"
106	echo -e "kernel-config[:cmds]             \tmodify kernel defconfig"
107}
108
109clean_hook()
110{
111	[ ! -d kernel ] || make -C kernel distclean
112}
113
114INIT_CMDS="default $KERNELS"
115init_hook()
116{
117	load_config RK_KERNEL_CFG
118	check_config RK_KERNEL_CFG &>/dev/null || return 0
119
120	# Priority: cmdline > custom env > .config > current kernel/ symlink
121	if echo $1 | grep -q "^kernel-"; then
122		export RK_KERNEL_VERSION=${1#kernel-}
123		echo "Using kernel version($RK_KERNEL_VERSION) from cmdline"
124	elif [ "$RK_KERNEL_VERSION" ]; then
125		export RK_KERNEL_VERSION=${RK_KERNEL_VERSION//\"/}
126		echo "Using kernel version($RK_KERNEL_VERSION) from environment"
127	else
128		load_config RK_KERNEL_VERSION
129	fi
130
131	update_kernel
132}
133
134PRE_BUILD_CMDS="kernel-config kernel-make kmake"
135pre_build_hook()
136{
137	check_config RK_KERNEL_CFG || return 0
138
139	echo "Toolchain for kernel:"
140	echo "${RK_KERNEL_TOOLCHAIN:-gcc}"
141	echo
142
143	case "$1" in
144		kernel-make | kmake)
145			shift
146			[ "$1" != cmds ] || shift
147
148			if [ ! -r kernel/.config ]; then
149				run_command $KMAKE $RK_KERNEL_CFG \
150					$RK_KERNEL_CFG_FRAGMENTS
151			fi
152			run_command $KMAKE $@
153			;;
154		kernel-config)
155			do_build $@
156			;;
157	esac
158
159	if [ -z "$DRY_RUN" ]; then
160		finish_build $@
161	fi
162}
163
164pre_build_hook_dry()
165{
166	DRY_RUN=1 pre_build_hook $@
167}
168
169BUILD_CMDS="$KERNELS kernel modules"
170build_hook()
171{
172	check_config RK_KERNEL_DTS_NAME RK_KERNEL_CFG RK_BOOT_IMG || return 0
173
174	echo "Toolchain for kernel:"
175	echo "${RK_KERNEL_TOOLCHAIN:-gcc}"
176	echo
177
178	if echo $1 | grep -q "^kernel-"; then
179		if [ "$RK_KERNEL_VERSION" != "${1#kernel-}" ]; then
180			echo -ne "\e[35m"
181			echo "Kernel version overrided: " \
182				"$RK_KERNEL_VERSION -> ${1#kernel-}"
183			echo -ne "\e[0m"
184		fi
185	fi
186
187	do_build $@
188
189	if [ "$DRY_RUN" ]; then
190		return 0
191	fi
192
193	if echo $1 | grep -q "^kernel"; then
194		ln -rsf "kernel/$RK_BOOT_IMG" "$RK_FIRMWARE_DIR/boot.img"
195		"$SCRIPTS_DIR/check-power-domain.sh"
196	fi
197
198	finish_build build_$1
199}
200
201build_hook_dry()
202{
203	DRY_RUN=1 build_hook $@
204}
205
206POST_BUILD_CMDS="linux-headers"
207post_build_hook()
208{
209	check_config RK_KERNEL_DTS_NAME RK_KERNEL_CFG RK_BOOT_IMG || return 0
210
211	[ "$1" = "linux-headers" ] || return 0
212	shift
213
214	[ "$1" != cmds ] || shift
215	OUTPUT_FILE="${2:-"$RK_OUTDIR"}/linux-headers.tar"
216	mkdir -p "$(dirname "OUTPUT_DIR")"
217
218	HEADER_FILES_SCRIPT=$(mktemp)
219
220	if [ "$DRY_RUN" ]; then
221		echo -e "\e[35mCommands of building linux-headers:\e[0m"
222	else
223		echo "Saving linux-headers to $OUTPUT_FILE"
224	fi
225
226	run_command $KMAKE $RK_KERNEL_CFG $RK_KERNEL_CFG_FRAGMENTS
227	run_command $KMAKE modules_prepare
228
229	cat << EOF > "$HEADER_FILES_SCRIPT"
230{
231	# Based on kernel/scripts/package/builddeb
232	find . arch/$RK_KERNEL_ARCH -maxdepth 1 -name Makefile\*
233	find include -type f -o -type l
234	find arch/$RK_KERNEL_ARCH -name module.lds -o -name Kbuild.platforms -o -name Platform
235	find \$(find arch/$RK_KERNEL_ARCH -name include -o -name scripts -type d) -type f
236	find arch/$RK_KERNEL_ARCH/include Module.symvers -type f
237	echo .config
238} | tar --no-recursion --ignore-failed-read -T - \
239	-cf "$OUTPUT_FILE"
240EOF
241
242	run_command cd "$SDK_DIR/kernel"
243
244	cat "$HEADER_FILES_SCRIPT"
245
246	if [ -z "$DRY_RUN" ]; then
247		. "$HEADER_FILES_SCRIPT"
248	fi
249
250	case "$RK_KERNEL_KBUILD_ARCH" in
251		host) run_command tar -uf "$OUTPUT_FILE" scripts tools ;;
252		*)
253			run_command cd "$RK_KBUILD_DIR/$RK_KERNEL_KBUILD_ARCH"
254			run_command cd "linux-kbuild-$RK_KERNEL_VERSION_REAL"
255			run_command tar -uf "$OUTPUT_FILE" .
256			;;
257	esac
258
259	run_command cd "$SDK_DIR"
260
261	rm -f "$HEADER_FILES_SCRIPT"
262}
263
264post_build_hook_dry()
265{
266	DRY_RUN=1 post_build_hook $@
267}
268
269source "${BUILD_HELPER:-$(dirname "$(realpath "$0")")/../build-hooks/build-helper}"
270
271case "${1:-kernel}" in
272	kernel-config | kernel-make | kmake) pre_build_hook $@ ;;
273	kernel* | modules)
274		init_hook $@
275		build_hook ${@:-kernel}
276		;;
277	linux-headers) post_build_hook $@ ;;
278	*) usage ;;
279esac
280