162306a36Sopenharmony_ci#!/bin/bash
262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0+
362306a36Sopenharmony_ci#
462306a36Sopenharmony_ci# Create an initrd directory if one does not already exist.
562306a36Sopenharmony_ci#
662306a36Sopenharmony_ci# Copyright (C) IBM Corporation, 2013
762306a36Sopenharmony_ci#
862306a36Sopenharmony_ci# Author: Connor Shu <Connor.Shu@ibm.com>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciD=tools/testing/selftests/rcutorture
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci# Prerequisite checks
1362306a36Sopenharmony_ciif [ ! -d "$D" ]; then
1462306a36Sopenharmony_ci    echo >&2 "$D does not exist: Malformed kernel source tree?"
1562306a36Sopenharmony_ci    exit 1
1662306a36Sopenharmony_cifi
1762306a36Sopenharmony_ciif [ -s "$D/initrd/init" ]; then
1862306a36Sopenharmony_ci    echo "$D/initrd/init already exists, no need to create it"
1962306a36Sopenharmony_ci    exit 0
2062306a36Sopenharmony_cifi
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci# Create a C-language initrd/init infinite-loop program and statically
2362306a36Sopenharmony_ci# link it.  This results in a very small initrd.
2462306a36Sopenharmony_ciecho "Creating a statically linked C-language initrd"
2562306a36Sopenharmony_cicd $D
2662306a36Sopenharmony_cimkdir -p initrd
2762306a36Sopenharmony_cicd initrd
2862306a36Sopenharmony_cicat > init.c << '___EOF___'
2962306a36Sopenharmony_ci#ifndef NOLIBC
3062306a36Sopenharmony_ci#include <unistd.h>
3162306a36Sopenharmony_ci#include <sys/time.h>
3262306a36Sopenharmony_ci#endif
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_civolatile unsigned long delaycount;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciint main(int argc, char *argv[])
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	int i;
3962306a36Sopenharmony_ci	struct timeval tv;
4062306a36Sopenharmony_ci	struct timeval tvb;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	printf("Torture-test rudimentary init program started, command line:\n");
4362306a36Sopenharmony_ci	for (i = 0; i < argc; i++)
4462306a36Sopenharmony_ci		printf(" %s", argv[i]);
4562306a36Sopenharmony_ci	printf("\n");
4662306a36Sopenharmony_ci	for (;;) {
4762306a36Sopenharmony_ci		sleep(1);
4862306a36Sopenharmony_ci		/* Need some userspace time. */
4962306a36Sopenharmony_ci		if (gettimeofday(&tvb, NULL))
5062306a36Sopenharmony_ci			continue;
5162306a36Sopenharmony_ci		do {
5262306a36Sopenharmony_ci			for (i = 0; i < 1000 * 100; i++)
5362306a36Sopenharmony_ci				delaycount = i * i;
5462306a36Sopenharmony_ci			if (gettimeofday(&tv, NULL))
5562306a36Sopenharmony_ci				break;
5662306a36Sopenharmony_ci			tv.tv_sec -= tvb.tv_sec;
5762306a36Sopenharmony_ci			if (tv.tv_sec > 1)
5862306a36Sopenharmony_ci				break;
5962306a36Sopenharmony_ci			tv.tv_usec += tv.tv_sec * 1000 * 1000;
6062306a36Sopenharmony_ci			tv.tv_usec -= tvb.tv_usec;
6162306a36Sopenharmony_ci		} while (tv.tv_usec < 1000);
6262306a36Sopenharmony_ci	}
6362306a36Sopenharmony_ci	return 0;
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci___EOF___
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci# build using nolibc on supported archs (smaller executable) and fall
6862306a36Sopenharmony_ci# back to regular glibc on other ones.
6962306a36Sopenharmony_ciif echo -e "#if __x86_64__||__i386__||__i486__||__i586__||__i686__" \
7062306a36Sopenharmony_ci	   "||__ARM_EABI__||__aarch64__||__s390x__||__loongarch__\nyes\n#endif" \
7162306a36Sopenharmony_ci   | ${CROSS_COMPILE}gcc -E -nostdlib -xc - \
7262306a36Sopenharmony_ci   | grep -q '^yes'; then
7362306a36Sopenharmony_ci	# architecture supported by nolibc
7462306a36Sopenharmony_ci        ${CROSS_COMPILE}gcc -fno-asynchronous-unwind-tables -fno-ident \
7562306a36Sopenharmony_ci		-nostdlib -include ../../../../include/nolibc/nolibc.h \
7662306a36Sopenharmony_ci		-s -static -Os -o init init.c -lgcc
7762306a36Sopenharmony_ci	ret=$?
7862306a36Sopenharmony_cielse
7962306a36Sopenharmony_ci	${CROSS_COMPILE}gcc -s -static -Os -o init init.c
8062306a36Sopenharmony_ci	ret=$?
8162306a36Sopenharmony_cifi
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciif [ "$ret" -ne 0 ]
8462306a36Sopenharmony_cithen
8562306a36Sopenharmony_ci	echo "Failed to create a statically linked C-language initrd"
8662306a36Sopenharmony_ci	exit "$ret"
8762306a36Sopenharmony_cifi
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cirm init.c
9062306a36Sopenharmony_ciecho "Done creating a statically linked C-language initrd"
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ciexit 0
93