The process of creating FlickOS
Posted on Wed 22 March 2023 in operating system
Hey everyone. First off, I want to say thank you to all who downloaded Flick. According to sourceforge log, we have 500+ downloads in the span of just two weeks. That means we saved and made 500+ computers usable again and that makes me very proud. Anyway, today's blog is about the processes and steps that I did to create Flick. This content will serve as my personal record but could also be used by anyone who wants to create their own. I will list down below the general steps and then explain it even further.
Steps:
- install necessary tools
- extract the squash file and unsquash it
- mount to chroot
- apply modifications and changes
- squash it again and create the ISO file
Install tools
To begin our journey in creating Flick, we have to first install tools and packages needed for the tasks ahead.
sudo apt-get install \
binutils \
debootstrap \
squashfs-tools \
xorriso \
grub-pc-bin \
grub-efi-amd64-bin \
mtools \
isomaster
Now that we have all the tools needed, let us proceed to extracting the neccessary files from our chosen ISO distribution.
Extract and unsquash
For this step, we will first extract filesystem.squashfs
from an existing ISO image, and in my case the LXLE ISO image. Second, we are going to unsquash
the filesystem.squashfs, this action will create a folder named squashfs-root
that contains all the files of the operating system.
- Using
isomaster
extract thefilesystem.squashfs
- Unsquash the file
sudo unsquashfs filesystem.squashfs
- Confirm that the previous command created the folder
squashfs-root
Mount everything
And now the fun begins. For us to be productive in this step, we have to understand first what is chroot
. Chroot in Linux is like a virtual machine but not quite. It's a kernel-level virtualization so its very light in resource usage. By chrooting
you create an isolated environment within your Linux system, where you can install and run applications with their own file system hierarchy. This can be useful for testing and debugging applications, isolating processes from the rest of the system, and for security purposes. So, that's what we are going to do with our freshly unsquashed squashfs-root
folder. To chroot inside we execute:
sudo mount --bind /dev squashfs-root/dev
sudo mount --bind /run squashfs-root/run
sudo chroot squashfs-root
And other mounts needed when we are making modifications inside the root system:
mount none -t proc /proc
mount none -t sysfs /sys
mount none -t devpts /dev/pts
export HOME=/root
export LC_ALL=C
If we encounter no errors, our terminal prompt will change to this: root@host-os:/#
. Always remember that whatever command that we execute inside this prompt, we are doing it inside the squashfs-root directory operating system, not the host operating system. If we need to execute commands for our host operating system, we have to open another terminal that belongs to the host OS.
Go loco
Okay, this is where the most fun of them all. This the time where we customize the operating system that we want. Some of the things that we can do are: remove applications that we don't like and install the ones that we like, set per applications configuration, create the user template under /etc/skel
, configure the ubiquity installer, create your own tools and utilities, and many more. Below is the list of folders I found important for modifications.
- /usr/share /applications /icons /backgrounds
- /usr/bin
- /etc/init.d /grub.d /skel
- /usr/local/bin
- /home/username/.local/bin /applications
- /home/username/.config
Squash and create
Congratulations if you're reading this last step. This step is where the excitement happens. Here we will have mixed emotions like excitement and anxiousness at the same time. We are excited to see the fruit of our labor but worried that we might missed something. The code to create our final product is:
#!/bin/bash
cd $HOME/lxle
echo "Clean up..."
sudo rm -r image *.iso
echo "Create directories.."
mkdir -p image/{casper,isolinux,install}
echo "Copy vmlinuz and initrd..."
sudo cp squashfs-root/boot/vmlinuz-5.4.0-113-generic image/casper/vmlinuz
sudo cp squashfs-root/boot/initrd.img-5.4.0-113-generic image/casper/initrd
echo "Copy memtest86+..."
sudo cp squashfs-root/boot/memtest86+.bin image/install/memtest86+
touch image/ubuntu
echo "Create grub menu..."
cat <<EOF > image/isolinux/grub.cfg
search --set=root --file /ubuntu
insmod all_video
set default="0"
set timeout=30
menuentry "Try Flick OS without installing" {
linux /casper/vmlinuz boot=casper nopersistent toram fsck.mode=skip quiet splash ---
initrd /casper/initrd
}
menuentry "Install Flick OS" {
linux /casper/vmlinuz boot=casper only-ubiquity fsck.mode=skip quiet splash ---
initrd /casper/initrd
}
menuentry "Check disc for defects" {
linux /casper/vmlinuz boot=casper integrity-check quiet splash ---
initrd /casper/initrd
}
menuentry "Test memory Memtest86+ (BIOS)" {
linux16 /install/memtest86+
}
menuentry "Test memory Memtest86 (UEFI, long load time)" {
insmod part_gpt
insmod search_fs_uuid
insmod chain
loopback loop /install/memtest86
chainloader (loop,gpt1)/efi/boot/BOOTX64.efi
}
EOF
echo "Generate manifest..."
sudo chroot squashfs-root dpkg-query -W --showformat='${Package} ${Version}\n' | sudo tee image/casper/filesystem.manifest
sudo cp -v image/casper/filesystem.manifest image/casper/filesystem.manifest-desktop
sudo sed -i '/ubiquity/d' image/casper/filesystem.manifest-desktop
sudo sed -i '/casper/d' image/casper/filesystem.manifest-desktop
sudo sed -i '/discover/d' image/casper/filesystem.manifest-desktop
sudo sed -i '/laptop-detect/d' image/casper/filesystem.manifest-desktop
sudo sed -i '/os-prober/d' image/casper/filesystem.manifest-desktop
echo "Create squashfs..."
sudo mksquashfs squashfs-root image/casper/filesystem.squashfs
echo "Write filesystem.size..."
printf $(sudo du -sx --block-size=1 squashfs-root | cut -f1) > image/casper/filesystem.size
echo "Create README.diskdefines..."
cat <<EOF > image/README.diskdefines
#define DISKNAME Flick
#define TYPE binary
#define TYPEbinary 1
#define ARCH amd64
#define ARCHamd64 1
#define DISKNUM 1
#define DISKNUM1 1
#define TOTALNUM 0
#define TOTALNUM0 1
EOF
cd $HOME/lxle/image
echo "Create a grub UEFI image..."
grub-mkstandalone \
--format=x86_64-efi \
--output=isolinux/bootx64.efi \
--locales="" \
--fonts="" \
"boot/grub/grub.cfg=isolinux/grub.cfg"
echo "Create a FAT16 UEFI boot disk image containing the EFI bootloader..."
(
cd isolinux && \
dd if=/dev/zero of=efiboot.img bs=1M count=10 && \
sudo mkfs.vfat efiboot.img && \
LC_CTYPE=C mmd -i efiboot.img efi efi/boot && \
LC_CTYPE=C mcopy -i efiboot.img ./bootx64.efi ::efi/boot/
)
echo "Create a grub BIOS image..."
grub-mkstandalone \
--format=i386-pc \
--output=isolinux/core.img \
--install-modules="linux16 linux normal iso9660 biosdisk memdisk search tar ls" \
--modules="linux16 linux normal iso9660 biosdisk search" \
--locales="" \
--fonts="" \
"boot/grub/grub.cfg=isolinux/grub.cfg"
echo "Combine a bootable Grub cdboot.img..."
cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > isolinux/bios.img
echo "Generate md5sum.txt..."
sudo /bin/bash -c "(find . -type f -print0 | xargs -0 md5sum | grep -v -e 'md5sum.txt' -e 'bios.img' -e 'efiboot.img' > md5sum.txt)"
echo "Create ISO image..."
sudo xorriso \
-as mkisofs \
-iso-level 3 \
-full-iso9660-filenames \
-volid "FlickOS" \
-output "../flickos.iso" \
-eltorito-boot boot/grub/bios.img \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
--eltorito-catalog boot/grub/boot.cat \
--grub2-boot-info \
--grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \
-eltorito-alt-boot \
-e EFI/efiboot.img \
-no-emul-boot \
-append_partition 2 0xef isolinux/efiboot.img \
-m "isolinux/efiboot.img" \
-m "isolinux/bios.img" \
-graft-points \
"/EFI/efiboot.img=isolinux/efiboot.img" \
"/boot/grub/bios.img=isolinux/bios.img" \
"."
I know it's quite long, but you can save this as a bash file, make necessary adjustment and execute the file.
Conclusion
Linux is a file based operating system, this means everything is written somewhere like configurations and logs. We just need to be creative and learn how to ask the right questions. Everything is in google, I never asked a person about anything during the development of Flick so don't worry much where to get help.
Best advise that I could give is that document everything
. Every actions, commands and changes that you do should be recorded or noted. This way you can replicate the changes in the future or you could undo something that you do not like. On the plus side, when everything is documented, you could create a bash
program to automate everything, and run the automation the next time you want to generate a fresh OS.
Making a Linux operating system is fun and exciting. We have all the tools, documentations and forums that we can go to if needed. All that we need is unleash our creativity, programming skills if you want to create your own utilities and most importantly a lot of patience. The overall process is quite time consuming and it will definitely test your patience. Now that you have the idea, why not make your own Linux. Goodluck!
References