Page 1 of 1

Own bootloader to make a bootable USB stick in Linux

Posted: Tue Dec 17, 2019 3:07 am
by iman
Hi.
I am trying to write my own bootloader, after having done all of the operating system coding and testing based on the GRUB's mulitiboot bootloader. Now it is the time to touch the bootloader stuff from scratch.
I have a USB thumb drive which ultimately will be bootable and contained the necessary bootloader and kernel files to be booted by BIOS.

In windows, I have used RUFUS to make my USB drive bootable. I have simply a 2-stage bootloader where the first stage contains a FAT 12 bios-parameter-block and is only responsible to load the second stage bootloader which finally loads the kernel at the upper memory address (i.e. >1MB). Having used RUFUS, the OS is booted and no problem has been encountered.

But in Linux, which is my main developing operating system, I faced some problems. To make my USB drive bootable I used DD and MKFS utilities as below:
1.Create a blank floppy image

Code: Select all

dd bs=512 count=2880 if=/dev/zero of=floppy.img
2.Format the floppy image

Code: Select all

mkfs.msdos floppy.img
3.Writes your bootsector and other files to the image file

Code: Select all

dd if=BOOT1.bin of=floppy.img bs=512 count=1
cp BOOT2.bin floppy.img
cp KERNEL.bin floppy.img
4.Write the floppy image into the USB device

Code: Select all

dd if=floppy.img of=/dev/sdb/ bs=512 count=2880
5.reboot and see if the operating system is booted. NO!

The second try:
Directly writes things on the USB device:
1.Writes your bootsector and other files to the USB

Code: Select all

dd if=BOOT1.bin of=/dev/sdb/ bs=512 count=1
cp BOOT2.bin /dev/sdb/
cp KERNEL.bin /dev/sdb/
2.reboot and see if the operating system is booted. NO!

In another failed try, I did:
1.Create a blank floppy image

Code: Select all

dd bs=512 count=2880 if=/dev/zero of=floppy.img
2.Format the floppy image

Code: Select all

mkfs.msdos floppy.img
3.Cerate a virtual floppy device and mount it

Code: Select all

sudo mkdir /media/floppy/
sudo mount -o loop floppy.img /media/floppy/
4.Writes your bootsector and other files to the image file

Code: Select all

dd if=BOOT1.bin of=floppy.img bs=512 count=1
cp BOOT2.bin floppy.img
cp KERNEL.bin floppy.img
5.Writes your image file to the floppy drive

Code: Select all

dd if=floppy.img of=/media/floppy bs=512 count=2880
6.Writes all the floppy drive to your USB

Code: Select all

dd if=/media/floppy/ of=/dev/sdb/ bs=512 count=2880
Here the last command cannot be executed since it cannot operate to load a directory (/media/floppy/) to the USB device.

I am wondering what would be the procedure to do it in Linux, and what is wrong with my first and second tries in Linux which will not be ended up to booting.
Any other suggestions are highly welcomed.

Best regards.
Iman.

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Tue Dec 17, 2019 4:36 am
by FusT
iman wrote: 3.Writes your bootsector and other files to the image file

Code: Select all

dd if=BOOT1.bin of=floppy.img bs=512 count=1
cp BOOT2.bin floppy.img
cp KERNEL.bin floppy.img
cp is the "copy" command. You are overwriting your image file with the BOOT2.bin and then with the KERNEL.bin file.
iman wrote: The second try:
Directly writes things on the USB device:
1.Writes your bootsector and other files to the USB

Code: Select all

dd if=BOOT1.bin of=/dev/sdb/ bs=512 count=1
cp BOOT2.bin /dev/sdb/
cp KERNEL.bin /dev/sdb/
That looks better though not entirely there yet
iman wrote: In another failed try, I did:
....
4.Writes your bootsector and other files to the image file

Code: Select all

dd if=BOOT1.bin of=floppy.img bs=512 count=1
cp BOOT2.bin floppy.img
cp KERNEL.bin floppy.img
That is the pretty much correct way, but (again) you're overwriting the image file.

What the correct steps should be:
1. Create a floppy image
2. Format the image
3. Write the bootsector to the image file
4. Mount the image file to a directory
5. Write (copy) the BOOT2.bin and KERNEL.bin to the mounted directory
6. Unmount the image file
7. Write the image file to the USB flashdrive

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Tue Dec 17, 2019 5:02 am
by iman
Dear FusT. Thanks for your reply.
I have still missed something.
FusT wrote: 4. Mount the image file to a directory
5. Write (copy) the BOOT2.bin and KERNEL.bin to the mounted directory
6. Unmount the image file
7. Write the image file to the USB flashdrive
I mounted the image to a directory and then write (copy) files to the directory, then unmount the image file (*) and write the image file to the USB (**).

*: Is the image file now contains the copied file into the directory?
**: like above, since I copied the files into the directory, and then unmounted the image file, does the image file contains the binary files?

Best regards.
Iman.

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Tue Dec 17, 2019 5:12 am
by iman
FusT wrote:That is the pretty much correct way...
Would it be the correct code? I will try it later today.

Code: Select all

sudo dd bs=512 count=2880 if=/dev/zero of=FLOPPYIMAGE.img
sudo mkfs.msdos FLOPPYIMAGE.img
sudo dd if=BOOT.bin of=FLOPPYIMAGE.img bs=512 count=1
sudo mkdir /media/floppy/
sudo mount -o loop FLOPPYIMAGE.img /media/floppy/
sudo cp BOOT2.bin /media/floppy/
sudo cp KERNEL.bin /media/floppy/
sudo unmount FLOPPYIMAGE.img
sudo dd if=FLOPPYIMAGE.img of=/dev/sdb bs=512 count=2880

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Tue Dec 17, 2019 5:56 am
by FusT
That looks to be mostly correct, I don't know from the top of my head if you can pass the image name to umount, you might need to pass the directory it is mounted to instead.

I would recommend you get to know Linux better if you're using it as your main OS for development.
You should really know your toolchain to be able to use it correctly.

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Tue Dec 17, 2019 11:40 am
by VSlezak
What Linux distro are you use? In Linux Mint you have good graphical tool for doing bootable USB(you can fount it in menu, but I dont know how is it name in english).

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Tue Dec 17, 2019 1:04 pm
by bzt
Hi,

You should not use sudo for all commands. Only the "mount" and "umount" requires privileges, but not the rest.

Alternatively you could use a user-only solution without the need of sudo with mtools. Install it with your package manager, and add the line

Code: Select all

drive a: file="FLOPPYIMAGE.img"
to /etc/mtools.conf.

Do everything as you did (create an empty file, format it to fat, etc.), but instead of mounting it, use "mcopy BOOT2.bin a:". That's it.

To avoid needing root privileges for the last step, just add your user to the "disk" group, and you'll be able to dd the image to the USB drive without sudo. Oh, and if you add your user to the "disk" group, then you can also do

Code: Select all

mount -o loop,user
without sudo. All these solutions will allow you to create a toolchain without authentication. Using sudo with "NOPASSWD" is a really really really BAD idea, never do that!
FusT wrote:That looks to be mostly correct, I don't know from the top of my head if you can pass the image name to umount, you might need to pass the directory it is mounted to instead.
That's correct. If you've mounted a file image, then you can umount it by it's device name (/dev/loopX) or by the directory, but not the file's name.

Cheers,
bzt

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Wed Dec 18, 2019 4:11 am
by iman
Klakap wrote:What Linux distro are you use?
I use ubuntu 16.4. I prefer the terminal and writing scripts.
Thanks.

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Wed Dec 18, 2019 4:13 am
by iman
bzt wrote:You should not use sudo for all commands
Okay, I will do like this.
bzt wrote:Do everything as you did ...
Thanks for your comment. I finally got it worked. Now i have my USB stick bootable with my OS.
Best regards.

Re: Own bootloader to make a bootable USB stick in Linux

Posted: Wed Dec 18, 2019 4:17 am
by iman
This is the code that worked for me:

Code: Select all

dd bs=512 count=2880 if=/dev/zero of=FLOPPYIMAGE.img
mkfs.msdos FLOPPYIMAGE.img
dd if=BOOT.bin of=FLOPPYIMAGE.img bs=512 count=1, conv=notrunc
#notrunc is important, otherwise you will be ended up with an image file of only 512 bytes size

mkdir /media/floppy/
sudo mount -o loop FLOPPYIMAGE.img /media/floppy/
cp BOOT2.bin /media/floppy/
cp KERNEL.bin /media/floppy/
sudo umount FLOPPYIMAGE.img
dd if=FLOPPYIMAGE.img of=/dev/sdb bs=512 count=2880

reboot