DFS Project

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

Chapter 1.0 : Installing Required Dependencies

newbie

/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 as `cpio` and pass it as a file called `init.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

# Chapter 1.3 : The 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 the `boot` file to be a `fat` format

mkfs.vfat boot.img

* after running it will create a `fat` fs on the `boot` file now we need to enable `syslinux` on the `boot` file

syslinux boot.img

* we still need to copy the `init.cpio` and `bzImage` to the `syslinux` bootloader, we will create a new directory we will call it as `BOOTLOADER` so we will copy those files to the `BOOTLOADER` 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

# Chapter 2.0 : Creating the ISO
![newbie](https://img.shields.io/badge/Level%20Newbie-green)
* 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


# Chapter 2.1 Further Beyond DFS: GUI
![Medium](https://img.shields.io/badge/Level%20Medium-yellow)
* 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 type `mousedev` enable it, now we need to compile it so hit `ESC` x2 times hit `YES` 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

## Chapter 2.2 Further Beyond DFS: User-space
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 hit `ESC` 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

# Chapter 2.3 Further Beyond DFS : The Desktop Enviorment
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

#include

#include

#include

#include

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

# Chapter 2.4 Further Beyond DFS : Bootloader & ISO
* 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

# Chapter 3 Further Beyond DFS: How to port `xorg`
![Hard](https://img.shields.io/badge/Level%20Hard-red) 
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


# Chapter 3.1 Further Beyond DFS : Porting A Browser
![Hard](https://img.shields.io/badge/Level%20Hard-red) 

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


# Chapter 3.2 Further Beyond DFS : Mobile Devices (Compiling the Kernel)
![hard](https://img.shields.io/badge/Level%20Hard-red) 
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

# Chapter 3.3 Further Beyond DFS : Mobile Devices (Compiling The User-space)
* 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
```zsh
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

Chapter 5.1 Further Beyond DFS : Installation Script (The Rootfilesystem)

Chapter 5.2 Further Beyond DFS : Installation Script (Script Development)

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

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 < /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](https://raw.githubusercontent.com/GuestSneezeOSDev/DFS2/main/ADFS/dfs-install.sh)

# Chapter 6 Further Beyond DFS : Package Managers
![critical](https://img.shields.io/badge/Level%20Extremely%20Hard-critical)
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

# Chapter 6.1 Further Beyond DFS : Package Managers (User-space)
* 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
```zsh
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

Chapter 7 Further Beyond DFS : Wine

critical 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

Chapter 7.1 Further Beyond DFS: Creating your own Bootloader

critical 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

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


# Chapter 8 Further Beyond DFS : Text Editors
We will use `nano` for the text editor because it is stable and `vim` changes every day (every 5 hours)
![critical](https://img.shields.io/badge/Level%20Extremely%20Hard-critical)
* 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 portednano`