1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0+
3#
4# Create an initrd directory if one does not already exist.
5#
6# Copyright (C) IBM Corporation, 2013
7#
8# Author: Connor Shu <Connor.Shu@ibm.com>
9
10D=tools/testing/selftests/rcutorture
11
12# Prerequisite checks
13if [ ! -d "$D" ]; then
14    echo >&2 "$D does not exist: Malformed kernel source tree?"
15    exit 1
16fi
17if [ -s "$D/initrd/init" ]; then
18    echo "$D/initrd/init already exists, no need to create it"
19    exit 0
20fi
21
22# Create a C-language initrd/init infinite-loop program and statically
23# link it.  This results in a very small initrd.
24echo "Creating a statically linked C-language initrd"
25cd $D
26mkdir -p initrd
27cd initrd
28cat > init.c << '___EOF___'
29#ifndef NOLIBC
30#include <unistd.h>
31#include <sys/time.h>
32#endif
33
34volatile unsigned long delaycount;
35
36int main(int argc, char *argv[])
37{
38	int i;
39	struct timeval tv;
40	struct timeval tvb;
41
42	printf("Torture-test rudimentary init program started, command line:\n");
43	for (i = 0; i < argc; i++)
44		printf(" %s", argv[i]);
45	printf("\n");
46	for (;;) {
47		sleep(1);
48		/* Need some userspace time. */
49		if (gettimeofday(&tvb, NULL))
50			continue;
51		do {
52			for (i = 0; i < 1000 * 100; i++)
53				delaycount = i * i;
54			if (gettimeofday(&tv, NULL))
55				break;
56			tv.tv_sec -= tvb.tv_sec;
57			if (tv.tv_sec > 1)
58				break;
59			tv.tv_usec += tv.tv_sec * 1000 * 1000;
60			tv.tv_usec -= tvb.tv_usec;
61		} while (tv.tv_usec < 1000);
62	}
63	return 0;
64}
65___EOF___
66
67# build using nolibc on supported archs (smaller executable) and fall
68# back to regular glibc on other ones.
69if echo -e "#if __x86_64__||__i386__||__i486__||__i586__||__i686__" \
70	   "||__ARM_EABI__||__aarch64__||(__mips__ && _ABIO32)" \
71	   "||__powerpc__||(__riscv && __riscv_xlen == 64)" \
72	   "||__s390x__||__loongarch__" \
73	   "\nyes\n#endif" \
74   | ${CROSS_COMPILE}gcc -E -nostdlib -xc - \
75   | grep -q '^yes'; then
76	# architecture supported by nolibc
77        ${CROSS_COMPILE}gcc -fno-asynchronous-unwind-tables -fno-ident \
78		-nostdlib -include ../../../../include/nolibc/nolibc.h \
79		-s -static -Os -o init init.c -lgcc
80	ret=$?
81else
82	${CROSS_COMPILE}gcc -s -static -Os -o init init.c
83	ret=$?
84fi
85
86if [ "$ret" -ne 0 ]
87then
88	echo "Failed to create a statically linked C-language initrd"
89	exit "$ret"
90fi
91
92rm init.c
93echo "Done creating a statically linked C-language initrd"
94
95exit 0
96