If you plan to use this guide to compile your own OS you must mention this guide You will need over 20-40 GiB if you want to complete this entire guide
Create your own Distro From Scratch with DFS a Free-to-use guide on how to get started building your Linux Distro
TABLE OF CONTENTS
- DFS Project
- Chapter 1.0 : Installing Required Dependencies
- Chapter 1.1 : Configuring The Kernel
- Chapter 1.2 : The User Space
- Chapter 1.3 : The Bootloader
- Chapter 2.0 : Creating the ISO
- Chapter 2.1 Further Beyond DFS: GUI
- Chapter 2.2 Further Beyond DFS: User-space
- Chapter 2.3 Further Beyond DFS : The Desktop Enviorment
- Chapter 2.4 Further Beyond DFS : Bootloader & ISO
- Chapter 3 Further Beyond DFS: How to port xorg
- Chapter 3.1 Further Beyond DFS : Porting A Browser
- Chapter 3.2 Further Beyond DFS : Mobile Devices (Compiling the Kernel)
- Chapter 3.3 Further Beyond DFS : Mobile Devices (Compiling The User-space)
- Chapter 3.3 Further Beyond DFS : Mobile Devices (The Bootloader)
- Chapter 3.4 Further Beyond DFS : Mobile Devices (Creating The ISO)
- Chapter 5 Further Beyond DFS : Installation Script
- Chapter 5.1 Further Beyond DFS : Installation Script (The Rootfilesystem)
- Chapter 5.2 Further Beyond DFS : Installation Script (Script Development)
- Chapter 6 Further Beyond DFS : Package Managers (Networking and Compiling in the Kernel)
- Chapter 6.1 Further Beyond DFS : Package Managers (User-space)
- Chapter 6.2 Further Beyond DFS: Package Managers (The bootloader)
- Chapter 6.3 Further Beyond DFS : Package Manager (Development)
- Chapter 7 Further Beyond DFS : Wine
- Chapter 7.1 Further Beyond DFS : Using a custom bootloader
- Chapter 8 Further Beyond DFS : Text Editors (NANO)
- we will require a few dependencies to configure , build and use the kernel here are a few packages we may need
apt-get install bzip2 git vim make gcc libncurses-dev flex bison bc cpio libelf-dev libssl-dev syslinux dosfstools
if you get an error such as
xaruc@dfs-guide:~$ apt-get install bzip2 git vim make gcc libncurses-dev flex bison bc cpio libelf-dev libssl-dev syslinux dosfstools
E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?
xaruc@dfs-guide:~$
you may need to run it with sudo
- we first have to configure and compile the kernel this is (chapter 1.0-1.3) the simplest part of the entire book
- first you need to fetch the latest kernel at the time writing it is
6.10.7
- you need to clone the repository using
git
and enter the directory usingcd
here is how
git clone --depth 1 https://github.com/torvalds/linux.git
cd linux
- now you need to configure the kernel the simplest way is to run
make menuconfig
- the best things I recommend are adding Drivers to your distro and make sure they are selected as
*
notM
M
means module, After you have finished run themake
command to build the kernel
make -j $(nproc)
- after the kernel finsihed building you will see a message looking similar to this
Kernel: arch/x86/boot/bzImage is ready (#1)
- this means the kernel has compiled,
bzImage
is the compiled kernel binary we will use it later to boot to the system lets create a directory lets call it for exampledfs-distro
and we will copy thebzImage
/Kernel to the directory
mkdir ~/dfs-distro
cp -r arch/x86/boot/bzImage ~/dfs-distro
- we will use busybox as the user space, linux will be the kernel but we need some kind of user-space, we will use git for this operation
git clone --depth 1 https://git.busybox.net/busybox
cd busybox
- we are going to the same thing we did with the kernel by configuring
busybox
make menuconfig
- first we are going to change a few settings in busybox you need to go to to
Settings
then you need to selectBuild static binary (no shared libs) (NEW)
after that run hitESC
x2 times and hitYES
to save the config - now compile the kernel
make -j $(nproc)
- after busybox finsihed compiling we will create a new directory in the
~/dfs-distro
directory and we will call itinitramfs
mkdir ~/dfs-distro/initramfs
- now we need to install it to the
initramfs
directory
make CONFIG_PREFIX=/home/$USER/dfs-distro/initramfs install
initramfs
is the initial file system the kernel loads after booting we will putbusybox
over there- now enter that directory
cd ~/dfs-distro/initramfs
ls
- you will find 1 file and 3 directories
bin linuxrc sbin usr
- we will create another file called
init
which will load the shell proccess in the kernel, it will use the shell to use the shell its a little bit funny but thats what its going to do
touch init
echo "#!/bin/sh
/bin/sh" >> init
- also we can remove
linuxrc
no need for that file
rm linuxrc
- also add exec perms for
init
chmod +x init
- we will use the find command to pack this into a
cpio
archive, we will pass find ascpio
and pass it as a file calledinit.cpio
which will be used in the above directory
find . | cpio -o -H newc ../init.cpio
- if you go one directory back you will find the
init.cpio
file, we will use the syslinux bootloader
- we will use a utility called
dd
which will allow us to create the bootloader
dd if=/dev/zero of=boot.img bs=1M count=50
ls
- you will find the bootloader has been created as the file called
boot
, now set theboot
file to be afat
format
mkfs.vfat boot.img
- after running it will create a
fat
fs on theboot
file now we need to enablesyslinux
on theboot
file
syslinux boot.img
- we still need to copy the
init.cpio
andbzImage
to thesyslinux
bootloader, we will create a new directory we will call it asBOOTLOADER
so we will copy those files to theBOOTLOADER
directory
mkdir BOOTLOADER
mount boot.img BOOTLOADER
cp bzImage init.cpio BOOTLOADER
- now you can unmount it
umount BOOTLOADER
you could finish here but if you want to create an ISO continue
- Install the Necessary Packages we will need
xorriso
to create a new ISO format for our Image
sudo apt-get install xorriso genisoimage
- create a new directory for example
~/dfs-iso
and create these directories
mkdir -p ~/dfs-iso/iso/{boot,rootfs}
- now copy Kernel and Initramfs and Syslinux:
cp ~/dfs-distro/BOOTLOADER/bzImage ~/dfs-iso/boot/
cp ~/dfs-distro/BOOTLOADER/init.cpio ~/dfs-iso/boot/
cp ~/dfs-distro/boot.img ~/dfs-iso/boot/
- Mount the FAT Image and copy Kernel and Initramfs to the Image:
mkdir ~/mnt/boot
sudo mount -o loop boot.img ~/mnt/boot
cp ~/dfs-iso/boot/bzImage ~/mnt/boot/
cp ~/dfs-iso/boot/initramfs.cpio ~/mnt/boot/
- Create Syslinux Configuration
touch ~/mnt/boot/boot/syslinux.cfg
echo 'DEFAULT linux
LABEL linux
KERNEL bzImage
INITRD initramfs.cpio
APPEND root=/dev/ram0' | sudo tee ~/mnt/boot/syslinux.cfg
- Unmount
sudo umount ~/mnt/boot
- Create the ISO Image Using
xorriso
:
xorriso -as mkisofs \
-r -V "DFS_Linux" \
-b boot.syslinux \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-o ~/dfs-iso/dfs-linux.iso \
~/dfs-iso
- We will discard the previous code since it will be useless, we need to install a few dependencies
apt install wget
apt install bzip2 libncurses-dev flex bison bc libelf-dev libssl-dev xz-utils autoconf gcc make libtool git vim libpng-dev libfreetype-dev g++ extlinux
- now download the kernel
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.10.tar.xz
tar xf linux-6.10.tar.xz
- now go to the kernel's folder and configure it
cd linux-6.10
make menuconfig
- Now we need to enable a few things find all of them
Device Drivers > Graphic Support > Cirrus drivers
Device Drivers > Graphic Support > Frame buffer devices > support for frame buffer devices
Device Drivers > Graphic Support > Bootup logo
- then hit
/
and typemousedev
enable it, now we need to compile it so hitESC
x2 times hitYES
then type
make -j $(nproc)
- now lets make a new directory we will call it
dfs-gui
mkdir ~/dfs-gui
- we will copy the kernel to the Directory
cp arch/x86/boot/bzImage ~/dfs-gui
This is the simplest part of Further Beyond DFS
- we will now use a user-space called Busybox again
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar xf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
- Now configure busybox
make menuconfig
- Now select
Settings > build static library (No shared libs) (NEW)
then hitESC
x2 times and select exit then compile it using
make -j$(nproc)
- Create a Config Prefix on where to install
busybox
make CONFIG_PREFIX=/home/$USER/dfs-gui install
we will use a Window Manager called Nano-X
git clone https://github.com/ghaerr/microwindows.git
cd microwindows
- Navigate to the
src/
folder and build The Microwindows/Nano-X Enviorment with the Linux Hardware buffer config
cd src/
cp Configs/config.linux-fb config
- Modify the Makefile to avoid issues
nano config # Change NX11 from N to Y
nano nx11/Makefile # Comment X11_INCULDE=$(X11HDRLOCATION) and Uncomment X11_INCLUDE=./x11-local
- Then run
make
make install
- Port an app : This is required so here is a demo
/*
hellox -- Hello world with Xlib.
$(CC) -o hellox hellox.c -lX11 -L/usr/X11/lib
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main(argc,argv)
int argc;
char **argv;
{
char hello[] = "Hello World!";
char hi[] = "hi!";
Display *mydisplay;
Window mywindow;
GC mygc;
XEvent myevent;
KeySym mykey;
XSizeHints myhint;
int myscreen;
unsigned long myforeground, mybackground;
int i;
char text[10];
int done;
/* setup display/screen */
mydisplay = XOpenDisplay("");
myscreen = DefaultScreen(mydisplay);
/* drawing contexts for an window */
myforeground = BlackPixel(mydisplay, myscreen);
mybackground = WhitePixel(mydisplay, myscreen);
myhint.x = 200;
myhint.y = 300;
myhint.width = 350;
myhint.height = 250;
myhint.flags = PPosition|PSize;
/* create window */
mywindow = XCreateSimpleWindow(mydisplay, DefaultRootWindow(mydisplay),
myhint.x, myhint.y,
myhint.width, myhint.height,
5, myforeground, mybackground);
/* window manager properties (yes, use of StdProp is obsolete) */
XSetStandardProperties(mydisplay, mywindow, hello, hello,
None, argv, argc, &myhint);
/* graphics context */
mygc = XCreateGC(mydisplay, mywindow, 0, 0);
XSetBackground(mydisplay, mygc, mybackground);
XSetForeground(mydisplay, mygc, myforeground);
/* allow receiving mouse events */
XSelectInput(mydisplay,mywindow,
ButtonPressMask|KeyPressMask|ExposureMask);
/* show up window */
XMapRaised(mydisplay, mywindow);
/* event loop */
done = 0;
while(done==0){
/* fetch event */
XNextEvent(mydisplay, &myevent);
switch(myevent.type){
case Expose:
/* Window was showed. */
if(myevent.xexpose.count==0)
XDrawImageString(myevent.xexpose.display,
myevent.xexpose.window,
mygc,
50, 50,
hello, strlen(hello));
break;
case MappingNotify:
/* Modifier key was up/down. */
XRefreshKeyboardMapping(&myevent);
break;
case ButtonPress:
/* Mouse button was pressed. */
XDrawImageString(myevent.xbutton.display,
myevent.xbutton.window,
mygc,
myevent.xbutton.x, myevent.xbutton.y,
hi, strlen(hi));
break;
case KeyPress:
/* Key input. */
i = XLookupString(&myevent, text, 10, &mykey, 0);
if(i==1 && text[0]=='q') done = 1;
break;
}
}
/* finalization */
XFreeGC(mydisplay,mygc);
XDestroyWindow(mydisplay, mywindow);
XCloseDisplay(mydisplay);
exit(0);
}
- Then run
gcc gui.c -lNX11 -lnano-x && gcc gui.c -lNX11 -lnano-x -I /microwindows/src/nx11/X11-local/
to compile now move it to the~/dfs-gui
dir by running
mv a.out ~/dfs-gui/x11app
- Now enter
bin
directory
cd microwindows/src/bin
# or cd bin/
- Run the LDD program to see the comipled libraries and create new directorys
ldd nano-X
mkdir -p /distro/lib/x86_64-linux-gnu/
mkdir /distro/lib64
- copy the neccassry files
cp /lib/x86_64-linux-gnu/libpng16.so.16 ~/dfs-gui/lib/x86_64-linux-gnu/libpng16.so.16
cp /lib/x86_64-linux-gnu/libz.so.1 ~/dfs-gui/lib/x86_64-linux-gnu/libz.so.1
cp /lib/x86_64-linux-gnu/libc.so.6 ~/dfs-gui/lib/x86_64-linux-gnu/libc.so.6
cp /lib/x86_64-linux-gnu/libm.so.6 ~/dfs-gui/lib/x86_64-linux-gnu/libm.so.6
cp /lib/x86_64-linux-gnu/libbrotlidec.so.1 ~/dfs-gui/lib/x86_64-linux-gnu/libbrotlidec.so.1
cp /lib64/ld-linux-x86-64.so.2 ~/dfs-gui/lib64/ld-linux-x86-64.so.2
- Now run those copy commands , copy the biniaries by copying the whole folder
cd ..
cp -r bin ~/dfs-gui/nanox
cd ..
cp runapp ~/dfs-gui/nanox
- Create the ISO Directory
mkdir -p ~/dfs-iso/{boot,grub}
- Copy linux kernel and other files:
cp ~/dfs-gui/bzImage ~/dfs-iso/boot/
cp -r ~/dfs-gui/{bin,lib,lib64,nanox,x11app,linuxrc,usr} ~/dfs-iso/
- Install GRUB
grub-mkrescue -o ~/dfs-iso/boot/grub/grub.cfg ~/dfs-iso
- Add the following to the
grub.cfg
set default=0
set timeout=5
menuentry "DFS Distro with GUI" {
linux /boot/bzImage root=/dev/sda rw
}
- Create the ISO Image
xorriso -as mkisofs -o ~/dfs-iso/dfs-gui.iso -b boot/grub/grub.cfg -no-emul-boot -boot-load-size 4 -boot-info-table -R -J -l ~/dfs-iso
- Test the ISO
qemu-system-x86_64 -cdrom ~/dfs-iso/dfs-gui.iso
If you get any issues create a new issue
This is hard and we do not recommend this to beginners please make sure you have a good understanding of Unix , Linux and The Previous Chapters so you can get a better understanding of how you can do this
-
Make sure you have the source code of the GUI ISO so you can continue
-
First
wget
the source code and extract the src
wget https://www.x.org/releases/individual/xserver/xorg-server-21.1.2.tar.xz
tar -xzf https://www.x.org/releases/individual/xserver/xorg-server-21.1.2.tar.xz
- now install dependencies
sudo apt-get install build-essential libx11-dev libxext-dev libxau-dev libxdmcp-dev xorg-dev libdrm-intel1
- Configure and Build Xorg
./configure --prefix=/home/$USER/dfs-gui/usr --sysconfdir=home/$USER/dfs-gui/etc --localstatedir=/var
- Compile: Build the Xorg server:
make
make CONFIG_PREFIX=/home/$USER/dfs-gui/ install
- Download Intel Driver
wget https://www.x.org/releases/individual/driver/xf86-video-intel-2.4.1.tar.bz2
tar -xjf xf86-video-intel-2.4.1.tar.bz2
cd xf86-video-intel-2.4.1
- Configure and Build Intel Driver
./configure --prefix=/home/$USER/dfs-gui/usr --sysconfdir=home/$USER/dfs-gui/etc
make
sudo make install
- Configure Xorg for Intel Devices
sudo mkdir -p /home/$USER/dfs-gui/etc/X11/xorg.conf.d/
sudo nano /home$USER/dfs-gui/etc/X11/xorg.conf.d/20-intel.conf
we will port links2
since it is a terminal-based
wget https://raw.githubusercontent.com/spartrekus/links2/master/links-1.03.tar.gz
tar xzf links-1.03
cd links-1.03
- Now lets configure the build
./configure
- Now we have a
Makefile
so we can compile it
make
sudo make install
- now you have the compiled binary run this command to find it
find . -name 'links*' -type f
- now make a new directory inside of the distro src/ and move the
link
browser binary to that directory
mkdir -p ~/dfs-gui/usr/bin/links/
mv links ~/dfs-gui/usr/bin/links/links
- Give it executable permissions
cd ~/dfs-gui/usr/bin/links/
chmod +x link
- Now compile it then you will have a browser then you will be able to use the browser, once you have booted to your distro type
cd /usr/bin/links/
./links www.url-to-site.com
we will not use any tools such as buildroot
or yocto
because I would consider that to be cheating
- Discard previous code we will need to rebuild the kernel
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.10.7.tar.xz
tar -xf linux-6.10.7.tar.xz
cd linux-6.10.7
- Edit the config (to do what ever you want)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs
- Compile the Kernel and install dependencies
sudo apt-get install gcc-arm-linux-gnueabihf
make ARCH=arm defconfig
- Build the kernel using the cross-compiler
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage
- Compile Device Tree (if needed):
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs
- move the compiled kernel to the directory
mkdir ~/dfs-arm
mv zImage ~/dfs-arm
- now we will use busybox for the user enviorment
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar xjf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
- Configure busybox to build statically (select
Build static binary (no shared libs) (NEW
)
make menuconfig
- After that hit
ESC
Key 2 times hit yes and then compile it using
make -j$(nproc)
- Make a new directory called
initramfs
in the OS src/ where busybox will be installed
mkdir ~/dfs-gui/initramfs
make CONFIG_PREFIX=/home/$USER/dfs-arm/initramfs install
- now enter that directory and we will create another file called init which will load the shell proccess in the kernel
cd ~/dfs-arm/initramfs
touch init
echo "#!/bin/sh
/bin/sh" >> init
- add executionable permissions to the
init
file
chmod +x init
- Implement the links browser to the usr directory
cd ~/
wget https://raw.githubusercontent.com/spartrekus/links2/master/links-1.03.tar.gz
tar xzf links-1.03
cd links-1.03
./configure
make
sudo make install
find . -name 'links*' -type f
mkdir -p ~/dfs-arm/usr/bin/links/
mv links ~/dfs-arm/usr/bin/links/links
cd ~/dfs-arm/usr/bin/links/
chmod +x link
- Create the
cpio
archive
find . | cpio -o -H newc ../init.cpio
- Use a utility called
dd
to create the bootloader
cd ..
dd if=/dev/zero of=boot.img bs=1M count=50
ls
- Create a FAT Filesystem to the
boot
image
mkfs.vfat boot.img
- Create a new directory called
BOOT-DFS
for us to copy the Compiled (OS) files to the image
mkdir BOOT-DFS
mount boot.img BOOT-DFS
cp zImage init.cpio BOOT-DFS
- Unmount
umount BOOT-DFS
- Install the Necessary packages
sudo apt-get install xorriso genisoimage
- Create the ISO directory
mkdir -p ~/dfs-iso/iso/{boot,rootfs}
- now copy the Kernel and Initramfs and Syslinux:
cp ~/dfs-arm/BOOT-DFS/zImage ~/dfs-iso/boot/
cp ~/dfs-arm/BOOT-DFS/init.cpio ~/dfs-iso/boot/
cp ~/dfs-arm/boot.img ~/dfs-iso/boot/
- Create the ISO Image Using
xorriso
:
xorriso -as mkisofs \
-r -V "DFS_Linux" \
-b boot.syslinux \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
-o ~/dfs-iso/dfs-linux.iso \
~/dfs-iso
You have Created an ARM-based kernel it was'nt that hard right?
For Users to install your OS you will need an Installation script for users to install your OS but first we need to go over some rules
- We cant use any language other than shell
- we can't use bash or zsh we can only use the shell that the kernel and busybox comes preinstalled with
- We have to port more programs
- Obtain FDISK's source code
wget https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.39/util-linux-2.39.tar.xz
- Extract the source code
tar -xvf util-linux-2.39.tar.xz
cd util-linux-2.39
- Configure , Build and compile
fdisk
./configure --without-ncurses --disable-all-programs --enable-fdisk
make fdisk
- Copy
fdisk
to the distro
cp disk-utils/fdisk ~/dfs-distro/usr/sbin/fdisk
- Add Necessary Libraries, Use ldd to check the libraries fdisk depends on:
ldd disk-utils/fdisk
- Copy these libraries to your root filesystem, ensuring they are placed in the correct directories (
/lib
or/lib64
). If the binary is too large, you can strip it to remove unnecessary symbols:
strip ~/dfs-distro/usr/sbin/mkfs.ext4
- Copy any necessary libraries to your distro’s lib or lib64 directories.
- If size is a concern, you can strip unnecessary symbols from the binary
strip ~/distro/usr/sbin/fdisk
- Now we need to port
mkfs
. Obtain the Source Code
wget https://downloads.sourceforge.net/project/e2fsprogs/e2fsprogs/1.46.5/e2fsprogs-1.46.5.tar.gz
tar -xzf e2fsprogs-1.46.5.tar.gz
cd e2fsprogs-1.46.5
- Configure , Build and Compile
ep2fsprogs
./configure --disable-shared --enable-static
make mkfs.ext4
- After building, you’ll need to copy the binary and its dependencies to your root filesystem.
cp mke2fs/mkfs.ext4 ~/dfs-distro/usr/sbin/
- Include Necessary Libraries
ldd ~/dfs-distro/usr/sbin/mkfs.ext4
- Now port
tar
so obtain it's source code
wget https://ftp.gnu.org/gnu/tar/tar-1.34.tar.gz
tar -xzf tar-1.34.tar.gz
cd tar-1.34
- Now configure,build and Compile
./configure --disable-shared --enable-static
make
- Copy the binary to the Root filesystem
cp src/tar ~/dfs-distro/usr/sbin/
- Include Necessary Libraries, Copy these libraries to the appropriate directories (
/lib
,/lib64
, etc.) in your root filesystem.
ldd ~/dfs-distro/usr/sbin/tar
- If the binary is too large, you can strip it to reduce its size:
strip ~/dfs-distro/usr/sbin/tar
- Port GRUB Obtain the source
wget https://ftp.gnu.org/gnu/grub/grub-2.06.tar.gz
tar -xzf grub-2.06.tar.gz
cd grub-2.06
- Configure and Compile GRUB
./configure --prefix=/home/$USER/dfs-distro/usr --with-platform=pc --target=x86_64 # For BIOS
make
make install
- Use LDD to implement missing libraries,Copy any required libraries to
/lib
or/lib64
in your root filesystem.
ldd ~/dfs-distro/usr/bin/grub-install
ldd ~/dfs-distro/usr/sbin/grub-mkconfig
- Now we need the root filesystem
tar.gz
so we will need to run this
cd ~/
tar -czvf rootfs.tar.gz dfs-distro
- Move the
.tar.gz
to thedfs-distro
directory and create standard unix partitions
cp -r rootfs.tar.gz dfs-distro
cd dfs-distro
mkdir var etc root tmp dev proc
- Port Chroot Obtain its source code
wget https://ftp.gnu.org/gnu/coreutils/coreutils-9.2.tar.xz
tar -xf coreutils-9.2.tar.xz
cd coreutils-9.2
- Configure the Build
./configure --prefix=/home/$USER/dfs-distro/usr
- Compile and install chroot onto the
rootfs
make
make install
- Ensure the chroot binary contains all of its dependencies
ldd ~/dfs-distro/usr/bin/chroot
We will start to work on the Script also please do not run these commands add these commands to the script I will call mine install.sh
- First set the shell enviorment, this will tell the OS we are using this type of shell, we have not implemented bash or zsh so we will use the default shell
#!/bin/sh
- Set some variables
DISK="/dev/sda"
BOOT_PARTITION="${DISK}1"
ROOT_PARTITION="${DISK}2"
MOUNT_POINT="/mnt"
ROOTFS_TARBALL="/path/to/rootfs.tar.gz"
KERNEL_IMAGE="/boot/bzImage" # If you are creating an ARM DFS distro please replace bzImage with zImage
INITRD_IMAGE="/boot/inut.cpio" # Adjust this if you have an initrd image
- Partition Disks
echo "Partitioning the disk..."
fdisk $DISK <<EOF
o # Create a new DOS partition table
n # Add a new partition
p # Primary partition
1 # Partition number
# Default - start at beginning of disk
+500M # Boot partition size
n # Add a new partition
p # Primary partition
2 # Partition number
# Default - start immediately after the previous partition
# Default - extend to the end of the disk
a # Make a partition bootable
1 # Mark the boot partition
w # Write the changes to disk
EOF
- Format the Partitions
echo "Formatting the partitions..."
/usr/sbin/mkfs.ext4 $BOOT_PARTITION
/usr/sbin/mkfs.ext4 $ROOT_PARTITION
- Mount the Partitions
echo "Mounting the partitions..."
mkdir -p $MOUNT_POINT
mount $ROOT_PARTITION $MOUNT_POINT
mkdir -p $MOUNT_POINT/boot
mount $BOOT_PARTITION $MOUNT_POINT/boot
- Extract the Root filesystem
echo "Extracting the root filesystem..."
/usr/sbin/tar -xzf $ROOTFS_TARBALL -C $MOUNT_POINT
- Install GRUB And Configure FSTAB in a Chroot Enviormet
echo "Entering the new root environment with chroot..."
/usr/bin/chroot $MOUNT_POINT /bin/sh <<EOF_CHROOT
echo "Installing GRUB..."
/usr/sbin/grub-install --target=i386-pc --boot-directory=/boot $DISK
echo "Generating GRUB configuration..."
/usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg
echo '
set default=0
set timeout=5
insmod ext2
set root=(hd0,msdos1)
menuentry "DFS-Based OS" {
linux /bzImage root=/dev/sda1
initrd /initrd.img
}
' >> /boot/grub/grub.cfg
echo "Configuring fstab..."
cat <<EOF > /etc/fstab
$ROOT_PARTITION / ext4 defaults 1 1
$BOOT_PARTITION /boot ext4 defaults 1 2
EOF
EOF_CHROOT
- Unmount and Reboot the system
echo "Installation complete. Unmounting and rebooting..."
umount $MOUNT_POINT/boot
umount $MOUNT_POINT
reboot
- If you want a finished version click here
You will need to redo everything
- Discard previous code we will be recompiling the kernel
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.10.7.tar.xz
tar xf linux-6.10.7.tar.xz
make menuconfig
- Inside of the config menu select
Device Drivers \
Network device support \
Ethernet driver support
Wireless \
Generic IEEE 802.11 Networking Stack
- Compile the Kernel (if you want to use ARM follow the ARM and this tutorial)
make -j$(nproc)
sudo make modules_install
sudo make install
- Move the kernel to the distro directory
mkdir ~/dfs-distro
mv arch/x86/boot/bzImage ~/dfs-distro # Change bzImage to zImage if ARM
- Develop the user space
wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
tar xjf busybox-1.36.1.tar.bz2
cd busybox-1.36.1
- Configure busybox to build statically (select Build static binary (no shared libs) (NEW)
make menuconfig
- Compile busybox
make -j$(nproc)
mkdir ~/dfs-distro/initramfs
make CONFIG_PREFIX=/home/$USER/dfs-distro/initramfs install
create a new file called init
cd ~/dfs-distro/initramfs
touch init
echo "#!/bin/sh
/bin/sh" >> init
chmod +x init
- Implement the Links Browser
cd ~/
wget https://raw.githubusercontent.com/spartrekus/links2/master/links-1.03.tar.gz
tar xzf links-1.03
cd links-1.03
./configure
make
sudo make install
find . -name 'links*' -type f
mkdir -p ~/dfs-distro/usr/bin/links/
mv links ~/dfs-distro/usr/bin/links/links
cd ~/dfs-distro/usr/bin/links/
chmod +x link
- Create a CPIO archive
find . | cpio -o -H newc ../init.cpio
- Use a utility like
dd
to create the boot image
dd if=/dev/zero of=boot.img bs=1M count=50
ls
- Create a FAT fs on the boot
mkfs.vfat boot.img
- Create a new directory called BOOT-DFS for us to copy the Compiled (OS) files to the image
mkdir BOOT-DFS
mount boot.img BOOT-DFS
cp zImage init.cpio BOOT-DFS
unmount
umount BOOT-DFS
Now we can continue work on the Package Installer/Manager
- we will need to port wget on your host system run, I also recommend porting the installer packages so the installer packages can work
wget https://ftp.gnu.org/gnu/wget/wget-latest.tar.gz
tar xzf wget-latest.tar.gz
cd wget-1.24.5
- Now Compile wget
./configure --prefix=$HOME/dfs-distro --exec-prefix=$HOME/dfs-distro --with-ssl=openssl
make
sudo make install
- Implement it to the OS
cd dfs-distro
- Create a directory structure for your repository. For example:
/repo
/packages
package1 # This can be tar for example
package2 # This can be grub
- Package Manager : You will need to develop the Package manager by either creating it with shell or python, we will use shell since we want users to be able to run it by just typing
./usr/bin/package-manager
in the terminal - Create the variables
PACKAGE_NAME="$1"
REPO_URL="http://github.com/username/repo # Replace the Username with your username"
INSTALL_DIR="/root" # Change this to your desired install directory
- Check if the package is provided
if [ -z "$PACKAGE_NAME" ]; then
echo "Usage: $0 <package_name>"
exit 1
fi
- Construct the Package file name
PACKAGE_FILE="${PACKAGE_NAME}"
- Download the Package
wget -q "$REPO_URL/$PACKAGE_FILE" -O "$PACKAGE_FILE"
- Check if Download was successful
if [ ! -f "$PACKAGE_FILE" ]; then
echo "Package not found or failed to download."
exit 1
fi
- Tell User Package was installed
echo "Package $PACKAGE_NAME installed successfully."
And you have Successfully made A Package Manager if you want a finished version click here
You most likely want to port wine
, but first make sure 32 BIT
programs are supported in your kernel else Wine will not work, there is a way to get around this but this wont support most applications
- Download the official Wine git repository
git clone https://gitlab.winehq.org/wine/wine.git
cd wine
- Build standard Wine with support for both 32-bit and 64-bit Windows programs, First we need to build for
win64
mkdir win64
cd win64
../configure CC="ccache gcc" CROSSCC="ccache x86_64-w64-mingw32-gcc" --enable-win64
make -j $(nproc)
- Build for
win32
cd ..
mkdir win32
cd win32
../configure CC="ccache gcc" CROSSCC="ccache i686-w64-mingw32-gcc" --with-wine64=../win64
make -j $(nproc)
cd ..
- Now you have wine configured now we should add it to our PACKAGE REPOSITORY
git clone https://github.com/YourUsername/YourRepository
cd YourRepository
cp -r ~/path/to/compiled/wine .
git add .
git commit -m "Wine"
git push origin your-branch
git request-pull
And you have successfully done it
If you want to create your own bootloader for your Distro this chapter will guide you, this will teach you how to write a bootloader from scratch which will boot to your linux kernel
- Create a new file called
bootloader.asm
mkdir dfs-bootloader
cd dfs-bootloader
touch bootloader.asm
echo "org 0x7c00 ; Boot sector starts here
; Function to read a sector from the disk
read_sector:
mov ah, 0x02 ; BIOS interrupt for disk read
mov al, 1 ; Number of sectors to read
mov ch, 0 ; Cylinder number
mov cl, 2 ; Sector number (starting sector for kernel)
mov dh, 0 ; Head number
mov dl, 0x80 ; Drive number (first hard disk)
int 0x13 ; Call BIOS interrupt
jc disk_error ; Jump if there is a carry (error)
ret
disk_error:
; Simple error handling
hlt
; Read kernel (assuming it's at sector 2)
call read_sector
; Read initramfs (assuming it's at sector 3)
mov cl, 3
call read_sector
; Jump to kernel (assumes kernel is at 0x1000)
jmp 0x1000
times 510 - ($ - $$) db 0 ; Fill the rest of the boot sector with zeros
dw 0xaa55 ; Boot sector signature" >> bootloader.asm
- Use NASM to assemble the bootloader.
nasm -f bin bootloader.asm -o bootloader.bin
- alternatively you can create a new image with the bootloader using this technique
dd if=/dev/zero of=distro.img bs=1M count=512
ls -lh disk.img
dd if=bootloader.bin of=distro.img bs=512 count=1 conv=notrunc # Write the bootloader
dd if=/home/$USER/dfs-iso/boot/bzImage of=distro.img bs=512 seek=2 conv=notrunc # Write the kernel change to zImage if ARM
dd if=/home/$USER/dfs-iso/boot/init.cpio of=distro.img bs=512 seek=3 conv=notrunc
- Test the image
qemu-system-x86_64 -drive format=raw,file=distro.img
We will use nano
for the text editor because it is stable and vim
changes every day (every 5 hours)
- Obtain
ncurses
library
wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.6.tar.gz
tar xzf ncurses-5.6.tar.gz
cd ncurses-5.6
- Compile
ncures
./configure --prefix=/home/$USER/dfs-distro/usr
make
make install
- Obtain
nano
source
wget https://ftp.gnu.org/pub/gnu/nano/nano-8.1.tar.gz
tar xzf nano-8.1.tar.gz
cd nano-8.1
- Now compile
nano
./configure --prefix=/home/$USER/dfs-distro/usr
make
make install
You have now ported nano