Linux Distribution for LOADLIN
This is a similar project to the Linux Distribution for 386SX but this with some different goals. Most importantly to boot it with LOADLIN directly from DOS and keeping the root filesystem in RAM using Cramfs. In addition, I wanted to have functioning SLIP support.
I ended up using these specific software versions:
* linux-2.4.37.11
* gcc-3.4.6
* busybox-1.19.4
* uClibc-0.9.33.2
* binutils-2.32
Get the necessary scripts, configuration and patches here to make it yourself. Or just get the completed kernel and root filesystem here.
For easy reference, here is the script to compile everything:
#!/bin/bash set -e TARGET="i386-linux-uclibc" PREFIX="${HOME}/opt/gcc-${TARGET}/" SYSROOT="${PREFIX}/${TARGET}/sysroot" GCC_SRC="gcc-3.4.6.tar.bz2" BINUTILS_SRC="binutils-2.32.tar.xz" UCLIBC_SRC="uClibc-0.9.33.2.tar.xz" LINUX_SRC="linux-2.4.37.11.tar.xz" BUSYBOX_SRC="busybox-1.19.4.tar.bz2" export PATH="${PREFIX}bin:$PATH" # Prepare Prefix and System Root if [ -d "$SYSROOT" ]; then echo "Old system root directory detected, please remove it." exit 1 else mkdir -p "$SYSROOT/usr" fi # Prepare Build Directories: if [ -d build ]; then echo "Old build directory detected, please remove it." exit 1 else mkdir -p build/binutils mkdir -p build/gcc-stage1 mkdir -p build/gcc-stage2 mkdir -p build/uclibc mkdir -p build/linux mkdir -p build/busybox fi # Unpack Sources: if [ -d source ]; then cd source tar -xvjf "$GCC_SRC" tar -xvJf "$BINUTILS_SRC" tar -xvJf "$UCLIBC_SRC" -C ../build/uclibc tar -xvJf "$LINUX_SRC" -C ../build/linux tar -xvjf "$BUSYBOX_SRC" -C ../build/busybox cd - else echo "No source directory, please download sources." exit 1 fi # Patch gcc-3.4.6: cd "source/gcc-3.4.6/gcc/config/i386/" if ! fgrep --silent "inhibit_libc" linux.h; then patch -p 0 < ../../../../../gcc-3.4.6-linux.h.patch fi cd - # Patch linux-2.4.37.11: cd "build/linux/linux-2.4.37.11/include/linux/" if ! fgrep --silent "<linux/types.h>" filter.h; then patch -p 0 < ../../../../../linux-2.4.37.11-filter.h.patch fi cd - # Install Linux 2.4 Headers: cd build/linux/linux-* make ARCH=i386 mrproper make ARCH=i386 include/linux/version.h make ARCH=i386 symlinks mkdir -p "$SYSROOT/usr/include/asm" cp -v -R -H include/asm "$SYSROOT/usr/include" cp -v -R include/asm-generic "$SYSROOT/usr/include" cp -v -R include/linux "$SYSROOT/usr/include" touch "${SYSROOT}/usr/include/linux/autoconf.h" cd - # Build binutils: cd build/binutils ../../source/binutils-*/configure --target="$TARGET" --prefix="$PREFIX" --with-sysroot="$SYSROOT" --disable-werror --enable-languages=c,c++ --enable-shared --without-newlib --disable-libgomp --enable-fast-install=N/A make all-{binutils,gas,ld} make install-{binutils,ld,gas} cd - # Build Stage 1 GCC3: cd build/gcc-stage1 ../../source/gcc-3*/configure --target="$TARGET" --prefix="$PREFIX" --with-sysroot="$SYSROOT" --with-cpu=i386 --disable-fast-install --disable-werror --disable-multilib --enable-languages=c --without-headers --disable-shared --disable-libssp --disable-libmudflap --with-newlib --disable-c99 --disable-libgomp --disable-threads make all-gcc make install-gcc cd - # Install uClibc Headers: cd build/uclibc/uClibc-* cp -v ../../../config-uclibc .config sed -i -e "s%KERNEL_HEADERS=.*%KERNEL_HEADERS=\"$SYSROOT/usr/include/\"%" .config make ARCH=i386 PREFIX="$SYSROOT" install_headers cd - # Build uClibc: cd build/uclibc/uClibc-* make ARCH=i386 PREFIX="$SYSROOT" make ARCH=i386 PREFIX="$SYSROOT" install cd - # Build Stage 2 GCC3: cd build/gcc-stage2 ../../source/gcc-3*/configure --target="$TARGET" --prefix="$PREFIX" --with-sysroot="$SYSROOT" --with-cpu=i386 --enable-fast-install=N/A --disable-werror --enable-languages=c,c++ --disable-shared --without-newlib --disable-libgomp --disable-threads make all-gcc make install-gcc cd - # Build Linux 2.4: cd build/linux/linux-* cp -v ../../../config-linux .config make ARCH=i386 CROSS_COMPILE=i386-linux-uclibc- oldconfig make ARCH=i386 CROSS_COMPILE=i386-linux-uclibc- dep make ARCH=i386 CROSS_COMPILE=i386-linux-uclibc- bzImage cd - # Build Busybox: cd build/busybox/busybox-* cp -v ../../../config-busybox .config make CROSS_COMPILE=i386-linux-uclibc- cd -
And here is the script to make the root filesystem:
#!/bin/bash set -e ROOTFS="`pwd`/rootfs/" TARGET="i386-linux-uclibc" PREFIX="${HOME}/opt/gcc-${TARGET}/" SYSROOT="${PREFIX}/${TARGET}/sysroot" export PATH="${PREFIX}bin:$PATH" if [ -d "$ROOTFS" ]; then echo "Old root FS directory detected, please remove it." exit 1 fi mkdir -p "$ROOTFS" # Install Busybox: cd build/busybox/busybox-* make CROSS_COMPILE=i386-linux-uclibc- CONFIG_PREFIX="$ROOTFS" install cd - # Create some essential directories cd "$ROOTFS" mkdir etc mkdir etc/init.d mkdir lib mkdir proc mkdir sys mkdir tmp mkdir root mkdir dev mkdir dev/pts cd - # Initial rc.S: cat > rcS <<EOF #!/bin/sh mount -t proc /proc /proc mount -t devpts /dev/pts /dev/pts mount -t tmpfs /tmp /tmp loadkmap < /etc/no-latin1.bmap hostname busybox EOF mv -v rcS "$ROOTFS/etc/init.d/" # Initial inittab: cat > inittab <<EOF ::sysinit:/etc/init.d/rcS ::respawn:-/bin/sh ::ctrlaltdel:/sbin/reboot ::shutdown:/bin/umount -a -r ::restart:/sbin/init EOF mv -v inittab "$ROOTFS/etc/" # Copy this system's keymap: loadkeys -b /usr/share/kbd/keymaps/i386/qwerty/no-latin1.map.gz > "$ROOTFS/etc/no-latin1.bmap" # Make everything root user: sudo chown -R root:root "$ROOTFS" # Create some critical devices: sudo mknod "$ROOTFS/dev/tty" c 5 0 sudo mknod "$ROOTFS/dev/console" c 5 1 sudo mknod -m 0666 "$ROOTFS/dev/null" c 1 3 # Create some useful devices: sudo mknod "$ROOTFS/dev/rtc" c 10 135 sudo mknod "$ROOTFS/dev/tty0" c 4 0 sudo mknod "$ROOTFS/dev/tty1" c 4 1 sudo mknod "$ROOTFS/dev/tty2" c 4 2 sudo mknod "$ROOTFS/dev/tty3" c 4 3 sudo mknod "$ROOTFS/dev/ttyS0" c 4 64 sudo mknod "$ROOTFS/dev/ttyS1" c 4 65 sudo mknod "$ROOTFS/dev/fd0" b 2 0 sudo mknod "$ROOTFS/dev/fd1" b 2 1 sudo mknod "$ROOTFS/dev/root" b 4 0 sudo mknod "$ROOTFS/dev/lp0" c 6 0 # SetUID on busybox binary: sudo chmod +s "$ROOTFS/bin/busybox" # Make rcS executable: sudo chmod +x "$ROOTFS/etc/init.d/rcS" # Make Compressed ROM archive: mkfs.cramfs rootfs rootfs.cramfs
Instead of using LOADLIN, it is actually easy to start this with QEMU as well, like so:
qemu-system-i386 -kernel bzImage -initrd rootfs.cramfs