diff --git a/README.md b/README.md index cb62c83..ca762fe 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ # minimal-linux -A minimal linux distro with busybox. Don't know if this works properly \ No newline at end of file +A minimal linux distro with busybox. Kernel loads up in Qemu but doesn't "init" into shell properly yet. + +## build from scratch + +Just do: `./build.sh` + +### test with QEMU + +`./start-vm.sh` diff --git a/build.iso b/build.iso deleted file mode 100644 index 6e50515..0000000 Binary files a/build.iso and /dev/null differ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..e09b188 --- /dev/null +++ b/build.sh @@ -0,0 +1,119 @@ +set -e +set -u + +OUTDIR=/minimal-linux +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 + +#ARCH=arm64 +#CROSS_COMPILE=aarch64-none-linux-gnu- +ARCH=x86_64 +CROSS_COMPILE= + +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" +fi + +echo "Adding the Image in outdir" + +cp ${OUTDIR}/linux-stable/arch/x86/boot/bzImage ${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 +SYSROOT=$(${CROSS_COMPILE}gcc -print-sysroot) +echo "SYSROOT is : $SYSROOT" +cp -a ${SYSROOT}/lib64/ld-linux-x86-64.so.2 ${OUTDIR}/rootfs/lib +echo "cp 1 result $#" +cp -r ${SYSROOT}/lib64/ ${OUTDIR}/rootfs/lib64 +echo "cp 2 result $#" + +# 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 +ls -l dev + +# 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 \ No newline at end of file diff --git a/vmlinux b/bzImage old mode 100755 new mode 100644 similarity index 99% rename from vmlinux rename to bzImage index 44bd90b..14dcbdf Binary files a/vmlinux and b/bzImage differ diff --git a/initramfs.cpio b/initramfs.cpio new file mode 100644 index 0000000..732e4ca Binary files /dev/null and b/initramfs.cpio differ diff --git a/initramfs.cpio.gz b/initramfs.cpio.gz index a66fadc..190aa9f 100644 Binary files a/initramfs.cpio.gz and b/initramfs.cpio.gz differ diff --git a/start-vm.sh b/start-vm.sh new file mode 100755 index 0000000..61b3899 --- /dev/null +++ b/start-vm.sh @@ -0,0 +1,37 @@ +# !/bin/bash +# Script to test build using qemu x86 emulator. + +set -e + +OUTDIR=$1 + +if [ -z "${OUTDIR}" ]; then + OUTDIR=/minimal-linux + echo "No outdir specified, using ${OUTDIR}" +fi + +KERNEL_IMAGE=${OUTDIR}/linux-stable/arch/x86/boot/bzImage +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-x86_64 \ + -m 256M \ + -M pc \ + -cpu qemu64 \ + -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=/home/autorun-qemu.sh console=ttyAMA0" -initrd ${INITRD_IMAGE}