commit 12a9341b40fc3c48503b46f42315f6ad90a273f4 Author: aimran96 Date: Wed Nov 15 14:04:11 2023 -0500 add working ARM build diff --git a/Image b/Image new file mode 100644 index 0000000..7356872 Binary files /dev/null and b/Image differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..413b1bf --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# minimal-linux + +A minimal linux distro cross compiled for ARM with busybox. This works fine but doing the exact same thing with x86_64 doesn't work in the main branch? Don't know whats happening but I presume the startup process is much more complicated for x86_64 + +## build from scratch + +`./manual-linux.sh` + +### test with QEMU + +`./start-qemu-terminal.sh` diff --git a/initramfs.cpio.gz b/initramfs.cpio.gz new file mode 100644 index 0000000..b4b3866 Binary files /dev/null and b/initramfs.cpio.gz differ diff --git a/manual-linux.sh b/manual-linux.sh new file mode 100755 index 0000000..503b855 --- /dev/null +++ b/manual-linux.sh @@ -0,0 +1,148 @@ +#!/bin/bash +# Script create the simplest linux distro ever + +set -e +set -u + +OUTDIR=/tmp/aeld +KERNEL_REPO=git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git +KERNEL_VERSION=v6.1.14 +BUSYBOX_VERSION=1_33_1 +# FINDER_APP_DIR=$(realpath $(dirname $0)) +ARCH=arm64 +CROSS_COMPILE=aarch64-none-linux-gnu- + +if [ $# -lt 1 ] +then + echo "Using default directory ${OUTDIR} for output" +else + OUTDIR=$1 + echo "Using passed directory ${OUTDIR} for output" +fi + +mkdir -p ${OUTDIR} + +cd "$OUTDIR" +if [ ! -d "${OUTDIR}/linux-stable" ]; then + #Clone only if the repository does not exist. + echo "CLONING GIT LINUX STABLE VERSION ${KERNEL_VERSION} IN ${OUTDIR}" + git clone ${KERNEL_REPO} --depth 1 --single-branch --branch ${KERNEL_VERSION} +fi +if [ ! -e ${OUTDIR}/linux-stable/arch/${ARCH}/boot/Image ]; then + cd linux-stable + echo "Checking out version ${KERNEL_VERSION}" + git checkout ${KERNEL_VERSION} + # https://unix.stackexchange.com/questions/657882/how-do-i-cross-compile-the-linux-kernel + #make ARCH="$ARCH" CROSS_COMPILE="$CROSS_COMPILE" menuconfig + #make ARCH="$ARCH" CROSS_COMPILE="$CROSS_COMPILE" config + # use default config + # make ARCH="$ARCH" CROSS_COMPILE="$CROSS_COMPILE" defconfig + # make ARCH="$ARCH" CROSS_COMPILE="$CROSS_COMPILE" + # (deepclean) the kernal Biuld tree - remove any existing configuration + make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} mrproper + # configure our virt device we simulate in qemu + echo "(configure our virt)" + make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} defconfig + # biuld a kernel image for booting with qemu + echo "biuld a kernel image for booting with qemu" + make -j4 ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} all + # build any kernel modules + echo "build any kernel modules" + make ARCH=arm64 CROSS_COMPILE=${CROSS_COMPILE} modules + # build the device tree + make ARCH=arm64 CROSS_COMPILE=${CROSS_COMPILE} dtbs +fi + +echo "Adding the Image in outdir" + +cp ${OUTDIR}/linux-stable/arch/${ARCH}/boot/Image ${OUTDIR} + +echo "Creating the staging directory for the root filesystem" +cd "$OUTDIR" +if [ -d "${OUTDIR}/rootfs" ] +then + echo "Deleting rootfs directory at ${OUTDIR}/rootfs and starting over" + sudo rm -rf ${OUTDIR}/rootfs +fi + +# TODO: Create necessary base directories +mkdir rootfs/ +mkdir rootfs/bin +mkdir rootfs/dev +mkdir rootfs/etc +mkdir rootfs/home +mkdir rootfs/lib +mkdir rootfs/lib/modules +mkdir rootfs/lib64 +mkdir rootfs/lib64/modules +mkdir rootfs/proc +mkdir rootfs/sys +mkdir rootfs/sbin +mkdir rootfs/tmp +mkdir rootfs/usr +mkdir rootfs/usr/lib +mkdir rootfs/usr/bin +mkdir rootfs/usr/sbin +mkdir rootfs/var +mkdir rootfs/var/log + +cd "$OUTDIR" +if [ ! -d "${OUTDIR}/busybox" ] +then +git clone git://busybox.net/busybox.git + cd busybox + git checkout ${BUSYBOX_VERSION} + # TODO: Configure busybox + # https://busybox.net/FAQ.html#configure + make ARCH="$ARCH" CROSS_COMPILE="$CROSS_COMPILE" defconfig +else + cd busybox +fi + +# TODO: Make and install busybox +make ARCH="$ARCH" CROSS_COMPILE="$CROSS_COMPILE" +make ARCH="$ARCH" CROSS_COMPILE="$CROSS_COMPILE" CONFIG_PREFIX="${OUTDIR}/rootfs" install +cd .. +pwd + +echo "Library dependencies" +${CROSS_COMPILE}readelf -a ${OUTDIR}/rootfs/bin/busybox | grep "program interpreter" +${CROSS_COMPILE}readelf -a ${OUTDIR}/rootfs/bin/busybox | grep "Shared library" + +# TODO: Add library dependencies to rootfs +CROSS_COMPILE_PATH=$(${CROSS_COMPILE}gcc --print-sysroot) +cp "${CROSS_COMPILE_PATH}"/lib/ld-linux-aarch64.so.1 "${OUTDIR}"/rootfs/lib +cp "${CROSS_COMPILE_PATH}"/lib64/libm.so.6 "${OUTDIR}"/rootfs/lib64 +cp "${CROSS_COMPILE_PATH}"/lib64/libresolv.so.2 "${OUTDIR}"/rootfs/lib64 +cp "${CROSS_COMPILE_PATH}"/lib64/libc.so.6 "${OUTDIR}"/rootfs/lib64 + +# TODO: Make device nodes +cd "$OUTDIR/rootfs" +sudo mknod -m 666 dev/null c 1 3 +sudo mknod -m 600 dev/console c 5 1 + +# TODO: Copy scripts and executables to a directory +# on the target rootfs + +# embedded apps and ohter installs can go here? + +# cd "$FINDER_APP_DIR" +# make clean +# make ARCH="$ARCH" CROSS_COMPILE="$CROSS_COMPILE" + +# cp writer ${OUTDIR}/rootfs/home +# cp finder.sh ${OUTDIR}/rootfs/home +# cp finder-test.sh ${OUTDIR}/rootfs/home +# cp writer.sh ${OUTDIR}/rootfs/home +# mkdir ${OUTDIR}/rootfs/home/conf +# cp -r conf/. ${OUTDIR}/rootfs/home/conf +# cp autorun-qemu.sh ${OUTDIR}/rootfs/home + +# TODO: Chown the root directory +cd "$OUTDIR/rootfs" +sudo chown -R root:root * + +# TODO: Create initramfs.cpio.gz +find . | cpio -H newc -ov --owner root:root > ${OUTDIR}/initramfs.cpio +cd "$OUTDIR" +gzip -f initramfs.cpio diff --git a/start-qemu-terminal.sh b/start-qemu-terminal.sh new file mode 100755 index 0000000..f1a133f --- /dev/null +++ b/start-qemu-terminal.sh @@ -0,0 +1,32 @@ +# !/bin/bash +# Script to open qemu terminal. +# Author: Siddhant Jajoo. + +set -e + +OUTDIR=$1 + +if [ -z "${OUTDIR}" ]; then + OUTDIR=/tmp/aeld + echo "No outdir specified, using ${OUTDIR}" +fi + +KERNEL_IMAGE=${OUTDIR}/Image +INITRD_IMAGE=${OUTDIR}/initramfs.cpio.gz + +if [ ! -e ${KERNEL_IMAGE} ]; then + echo "Missing kernel image at ${KERNEL_IMAGE}" + exit 1 +fi +if [ ! -e ${INITRD_IMAGE} ]; then + echo "Missing initrd image at ${INITRD_IMAGE}" + exit 1 +fi + + +echo "Booting the kernel" +# See trick at https://superuser.com/a/1412150 to route serial port output to file +qemu-system-aarch64 -m 256M -M virt -cpu cortex-a53 -nographic -smp 1 -kernel ${KERNEL_IMAGE} \ + -chardev stdio,id=char0,mux=on,logfile=${OUTDIR}/serial.log,signal=off \ + -serial chardev:char0 -mon chardev=char0\ + -append "rdinit=/bin/sh" -initrd ${INITRD_IMAGE}