Running
$ make
$ qemu-system-x86_64 -kernel output/kernel-image -initrd output/initramfs.cpio.gz -append "root=/dev/ram0 rootfstype=ramfs init=/init console=ttyS0" -nographic -net nic,model=rtl8139 -net user
We recommend upgrading to the latest Google Chrome or Firefox.
| output/ |
| ################################################################################ | |
| # Base image | |
| # We use Alpine as it is small and its toolchain is already musl-based. | |
| FROM alpine:3.7 | |
| ################################################################################ | |
| # Pulling down sources | |
| # Get git for pulling down the kernel and busybox: | |
| RUN apk add --update git | |
| # Download and extract the Linux source: | |
| RUN git clone git://github.com/torvalds/linux.git --depth 1 --branch v4.15 -q | |
| # Download and extract BusyBox: | |
| RUN git clone git://git.busybox.net/busybox --depth 1 --branch 1_28_1 -q | |
| ################################################################################ | |
| # Building | |
| # Essential things for building Linux | |
| RUN apk add bc build-base linux-headers | |
| # Build BusyBox | |
| RUN cd /busybox \ | |
| && make defconfig > /dev/null \ | |
| && make clean > /dev/null \ | |
| && make LDFLAGS=-static install > /dev/null | |
| # Build Linux | |
| COPY Linuxfile /linux/config-overrides | |
| RUN cd /linux \ | |
| && make allnoconfig > /dev/null \ | |
| && cat config-overrides >> .config \ | |
| && make oldconfig > /dev/null \ | |
| && make -j 4 \ | |
| && mv arch/x86/boot/bzImage /bzImage | |
| ################################################################################ | |
| # File system | |
| # Essential things for building the initramfs | |
| RUN apk add cpio bash | |
| # Create our initial file system | |
| RUN mkdir /initramfs \ | |
| && cd /initramfs \ | |
| && bash -c 'mkdir -pv {bin,sbin,etc,proc,sys,usr/{bin,sbin,lib},lib,dev,mnt,root,tmp,var/log}' \ | |
| && cp -av /busybox/_install/* . | |
| COPY Initfile /initramfs/init | |
| RUN echo nameserver 8.8.8.8 > /initramfs/etc/resolv.conf \ | |
| && chmod 755 /initramfs/init && chmod +x /initramfs/init | |
| ################################################################################ | |
| # Final output | |
| # Make the initramfs | |
| RUN cd /initramfs \ | |
| && find . -print0 \ | |
| | cpio --null -ov --format=newc \ | |
| | gzip -9 > /initramfs.cpio.gz | |
| # Export the image and filesystem ready to boot into | |
| RUN mkdir /output \ | |
| && cp /bzImage /output/kernel-image \ | |
| && mv /initramfs.cpio.gz /output/ | |
| # Essentials for building the ISO file | |
| RUN apk add syslinux xorriso | |
| # Make the boot directory | |
| RUN mkdir -p /iso/boot; \ | |
| cp /bzImage /iso/boot/vmlinuz64; \ | |
| cp /output/initramfs.cpio.gz /iso/boot/initrd.img | |
| # Make the isolinux directory | |
| RUN mkdir -p /iso/isolinux; \ | |
| cp /usr/share/syslinux/*.* /iso/isolinux | |
| COPY isolinux.cfg /iso/isolinux/isolinux.cfg | |
| # Make the ISO | |
| RUN xorriso -as mkisofs -l -r -J -V "CUSTOM_LINUX" \ | |
| -b isolinux/isolinux.bin \ | |
| -isohybrid-mbr /usr/share/syslinux/isohdpfx.bin \ | |
| -no-emul-boot \ | |
| -boot-load-size 4 \ | |
| -boot-info-table \ | |
| -c isolinux/boot.cat \ | |
| -o /output/custom-linux.iso \ | |
| /iso/ |
| #!/bin/sh | |
| mount -t devtmpfs devtmpfs /dev | |
| mount -t proc none /proc | |
| mount -t sysfs none /sys | |
| mkdir -p /var/run/ | |
| mkdir -p /etc/network/if-down.d | |
| mkdir -p /etc/network/if-post-down.d | |
| mkdir -p /etc/network/if-post-up.d | |
| mkdir -p /etc/network/if-pre-down.d | |
| mkdir -p /etc/network/if-pre-up.d | |
| mkdir -p /etc/network/if-up.d | |
| /sbin/mdev -s | |
| /sbin/ifconfig lo 127.0.0.1 netmask 255.0.0.0 up | |
| /sbin/ifconfig eth0 up 10.0.2.15 netmask 255.255.255.0 up | |
| /sbin/route add default gw 10.0.2.2 | |
| echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n" | |
| echo '<LSPCI>' | |
| lspci -k | |
| echo '</LSPCI>' | |
| /usr/bin/setsid /bin/cttyhack /bin/sh | |
| exec /bin/sh |
| serial 0 9600 | |
| default linux | |
| label linux | |
| kernel /boot/vmlinuz64 com1=9600,8n1 | |
| initrd /boot/initrd.img | |
| append console=ttyS0 console=tty0 | |
| # see http://www.syslinux.org/wiki/index.php/SYSLINUX | |
| # If flag_val is 0, do not load a kernel image unless it has been explicitly named in a LABEL statement. The default is 1. | |
| implicit 0 | |
| # If flag_val is 0, display the boot: prompt only if the Shift or Alt key is pressed, or Caps Lock or Scroll lock is set (this is the default). If flag_val is 1, always display the boot: prompt. | |
| prompt 0 | |
| # Indicates how long to pause at the boot: prompt until booting automatically, in units of 1/10 s. The timeout is cancelled when any key is pressed, the assumption being the user will complete the command line. A timeout of zero will disable the timeout completely. The default is 0. | |
| timeout 0 |
| CONFIG_64BIT=y | |
| CONFIG_EMBEDDED=n | |
| CONFIG_PRINTK=y | |
| CONFIG_PCI_QUIRKS=y | |
| CONFIG_BLK_DEV=y | |
| CONFIG_BLK_DEV_INITRD=y | |
| CONFIG_INITRAMFS_SOURCE=/initramfs.cpio | |
| CONFIG_BLOCK=y | |
| CONFIG_SMP=y | |
| CONFIG_PCI=y | |
| CONFIG_MTTR=y | |
| CONFIG_BINFMT_ELF=y | |
| CONFIG_BINFMT_SCRIPT=y | |
| CONFIG_EXT2_FS=y | |
| CONFIG_INOTIFY_USER=y | |
| CONFIG_NET=y | |
| CONFIG_PACKET=y | |
| CONFIG_UNIX=y | |
| CONFIG_INET=y | |
| CONFIG_WIRELESS=n | |
| CONFIG_ATA=y | |
| CONFIG_NETDEVICES=y | |
| CONFIG_WLAN=n | |
| CONFIG_DEVKMEM=y | |
| CONFIG_TTY=y | |
| CONFIG_TTY_PRINTK=y | |
| CONFIG_SERIAL_8250=y | |
| CONFIG_SERIAL_8250_CONSOLE=y | |
| CONFIG_PROC_FS=y | |
| CONFIG_PROC_KCORE=y | |
| CONFIG_SYSFS=y | |
| CONFIG_X86_VERBOSE_BOOTUP=y | |
| CONFIG_EARLY_PRINTK=y | |
| CONFIG_DEVTMPFS=y | |
| CONFIG_DEVTMPFS_MOUNT=y | |
| CONFIG_POSIX_TIMERS=y | |
| ################################################################################ | |
| ## Networking | |
| # For QEMU | |
| CONFIG_NET_VENDOR_REALTEK=y | |
| CONFIG_8139TOO=y | |
| CONFIG_8139CP=y | |
| # For VirtualBox | |
| CONFIG_NET_VENDOR_INTEL=y | |
| CONFIG_E1000=y | |
| ################################################################################ | |
| ## Graphics | |
| CONFIG_EPOLL=y # Needed for Xorg. | |
| CONFIG_AGP=y | |
| CONFIG_DRM_KMS_HELPER=y | |
| # MacBook | |
| CONFIG_DRM=y | |
| CONFIG_DRM_FBDEV_EMULATION=y | |
| CONFIG_DRM_I915=y | |
| CONFIG_DRM_I915_KMS=y | |
| CONIFG_LOGO=y | |
| CONFIG_INTEL=y | |
| # QEMU & VirtualBox | |
| CONFIG_FB=y | |
| CONFIG_DRM_BOCHS=y | |
| CONFIG_DRM_CIRRUS_QEMU=y | |
| # VirtualBox | |
| CONFIG_STAGING=y | |
| CONFIG_X86=y | |
| CONFIG_DRM_VBOXVIDEO=y | |
| CONFIG_DRM_TTM=y # it's not this | |
| CONFIG_GENERIC_ALLOCATOR=y # it's not this | |
| ################################################################################ | |
| ## Input devices | |
| CONFIG_INPUT=y | |
| CONFIG_INPUT_EVDEV=y | |
| CONFIG_INPUT_MOUSEDEV=y |
| all: Dockerfile Initfile Linuxfile | |
| docker-machine scp Dockerfile custom-linux: > /dev/null \ | |
| && docker-machine scp Linuxfile custom-linux: > /dev/null \ | |
| && docker-machine scp Initfile custom-linux: > /dev/null \ | |
| && docker-machine scp isolinux.cfg custom-linux: > /dev/null \ | |
| && docker-machine ssh custom-linux docker image build . -t custom-linux \ | |
| && docker-machine ssh custom-linux docker run --name custom-linux-copy custom-linux \ | |
| && docker-machine ssh custom-linux docker cp custom-linux-copy:/output `pwd` \ | |
| && docker-machine ssh custom-linux docker rm custom-linux-copy |