How BIOS boot from floppy and CD-ROM differently? - operating-system

My test OS boots from floppy before, now I am trying to boot it from CD-ROM. But I am not quite sure how BIOS treat the floppy boot sector and CD boot sector differently. It seems the CD boot sector is much bigger than floppy boot sector. Is there any other things I need to notice?
Could anyone elabrate the details about it or point me to some links?
Thanks.

I would recommend booting with GRUB. Use the eltorito image to make the CD bootable. Then include your kernel in the CD image and make an entry in the GRUB configuration file use your kernel file like: kernel mykernel
Include any initrd if you have and boot.
To know about CD boot sectors i would tell you to have a look to the ISO Specifications
Wikipedia link
The ISO 9660 File System
ISO9660 Simplified for DOS/Windows
OSDev Link
I hope these links would help

To start, you should know that the bios does not use sector one of the CDrom to boot but sector 17 if I remember right.
You can learn alot by looking at the cdrom boot files which bootloaders such as grub or lilo use. Maby even minix has a cdboot option.

Related

How is an efi application being set as the bootloader through code?

By following this tutorial, I am able to create a simple efi application that prints hello world when executed from an uefi shell. However, I was wondering how does one creates bootable EFI image. I tried to use bcfg command in the shell and added my efi binary as one of the booting sequence. However, is there anyway to do it without the need of going into the shell?
However, if you are actually building your own firmware, you can also
look at creating a bootable EFI image and set your default boot option
to this binary. This is most useful if you are including the binary as
a part of your ROM, but it might be a little involved to set up the
filesystem so that it is seen as a normal boot option.
In this question, Nicholas Embry gave a good answer but I was unable to find any resource to explore further into the topic that he mentioned. Any help would be appreciated. Thanks!
bcfg, just like efibootmgr in Linux, ultimately use the GetVariable() and SetVariable() runtime services (also available during boottime) to modify the system boot configuration.
The UEFI Shell, implementing the bcfg command, is itself a UEFI application. Since its source is publicly available, you can have a look at the implementation of the bcfg command - particularly the BcfgAdd() function.
Adding on to unixsmurf's answer, I figured that it is in the specification that UEFI will automatically look for a file name/located at EFI/BOOT/bootx64.efi. When making a UEFI application that is intended to be automatically loaded by the machine when booting, simply place the application at the specified path. Combining with what unixsmurf mentioned, I can make the computer load any UEFI application automatically at boot time.

How does GRUB load the kernel at 0x100000

I'm writing a bootloader and kernel from scratch and my goal is to create a kernel that can both be loaded by GRUB and my bootloader. The issue isn't with the kernel, though. I don't know how to load the kernel at 0x100000 which is where grub loads the kernel. 0x100000 is not small enough to fit into a 16 bit register and it is too large to reach using segmentation (using address buffer es:bx when reading the disk using BIOS interrupt).
So my question is, how does GRUB load the kernel that far into memory?
I am working on building a kernel through the Little Os Book and as far as I can tell the kernel is loaded at the 1MB address because it is specified in a linker script.
You can check out the book here, read the section Linking The Kernel

Make bootable flash drive of custom version of mikeOS

Using Hyper-V, I am running a Windows XP machine and I have a virtual floppy drive mounted too, where, using the following code, I am writing the bootloader.bin into the virtual floppy drive.
>debug
-n bootloader.bin
-l 0
-w 0 0 0 1
-quit
This is working well with a virtual floppy drive. I am compiling the asm files using NASM. However, I want to get my custom OS along with the new kernel.bin on a flash drive. Now, I saw that the mikeOS source has an ISO image, but I cannot get that on my flash drive using traditional methods, since it uses the own bootleader.
I am looking for a way in which I can get this OS working on any x86 PCs. I need a way to migrate the storage. Also, I do not wish to use a CD-R for this purpose. The memory should be rewritable.
You should be able to put a raw floppy image (or bootloader) straight onto the USB. Use a raw burning program to do so. If you have your own VFD or ISO, you could use UNetbootin to put in onto the USB as it will assist in the booting process. If you have just the files, you could use Winimage to create a VFD or ISO with those files. If you feel stuck, go back to the MikeOS handbooks. They have a lot of helpful information.
UPDATE
In your case, you can easily use UNetbootin.
Download it for your platform (I assume Windows). You should have only one executable file.
Run the the executable file. NOTE: It isn't an installer.
Select 'diskimage' instead of 'Distribution'.
Change 'ISO' to 'Floppy'.
Select your VFD's location.
Select the type of disk you want to write to. In this case, USB Drive is default.
Select the drive, in this case drive G:\. BE SURE THAT YOU PICK THE RIGHT ONE. THAT DRIVE WILL BE COMPLETELY WIPED BEFORE INSTALLATION!
Click OK. If everything goes good, you'll now have a bootable USB for your OS.
I hope this helps!
"Format" it in assembly language, assemble, mount the image with ImDisk and copy the files over. This can all be done with a cmd script.
While you're at it take a look at The 1.44MB FAT32 floppy disk and MikeOS-4.5 FAT32 (16-bit real mode) to see how simple it is to use FAT32 instead of FAT12.
PS. The formatting is done in bootload.asm in the MikeOS-4.5 FAT32 (16-bit real mode) distribution.

Running an EFI application automatically on boot

I can build and manually execute an EFI application in a UEFI environment. But, I'd like to have my application executed automatically at boot time.
Is there a way to tell the bootloader to do this or do I need to turn my application in to a driver to have it automatically executed? Is there maybe some entry in an FDF, DEC, DSC, or INF file I'm missing?
You can add a startup.nsh script file to your UEFI Shell boot drive that calls you application.
The following link should serve as a handy reference for working with scripts in the shell: UEFI Shells and Scripting. Look at section 3 (EFI Shell Scripts) specifically.
However, if you are actually building your own firmware, you can also look at creating a bootable EFI image and set your default boot option to this binary. This is most useful if you are including the binary as a part of your ROM, but it might be a little involved to set up the filesystem so that it is seen as a normal boot option.
Also, if you have complete access to your firmware source, you could also just load and call your binary from your BDS driver. I don't recommend this route, unless you are specifically aiming to create a standalone device that will never boot any other image.
#NicholasEmbry answer contain almost all what is needed, but I would like to clarify some things and add recent improvements in that area.
Adding UEFI application image to boot option is actually best known method when you don't have source code of your firmware, what is typical situation. You don't have to create any special bootable image it should be simple UEFI application image, what means that your INF should contain:
MODULE_TYPE = UEFI_APPLICATION
This option is not just for Option ROMs this is for all UEFI readable medium. For example you can create FAT32 partition on your storage (no matter if it is USB, HDD, SSD, etc. it just have to be readable by firmware) and place application image on this partition. Then boot to UEFI Shell and use bcfg command to affect your boot order.
bcfg command can be blocked by you BIOS vendor. In that situation please follow procedure from this post. This is booting rEFInd using USB stick. rEFInd contain bcfg tool and give you ability to use it.
How to use bcfg ?
All is described in help help bcfg -b. -b is UEFI pager. For those who like shortcuts, this command will display all boot options in system:
bcfg boot dump -v
You can add your application using command:
bcfg boot add <boot_pos> <path_to_uefi_image> <boot_order_name>
<boot_pos> - position in boot order. Note you usually want to put your application before OS. If there is no free boot option number before your OS you can of course move your OS one option down bcfg boot mv <old_pos> <new_pos> and then add your application image in between.
<path_to_uefi_image> - path to your UEFI image. This is UEFI readable path ie. fs0:\foobar.efi
<boot_order_name> - this is how you application will be visible in boot BIOS menu

How to test bootloader

I have a hello world bootloader code in assembly written (I'm sure I coded it right). I have the .bin file with me and .exe also.
I want to test it now with a USB, how do I do it? Everything I googled out and found on the topic pretty much didn't work out.
I have tried the way with "Disk Explorer NTFS 3.66". I have also tried the mkbt way. Both of them though mentioned highly in blogs/forums/etc don't seem to work for some reason.
Disk Explorer is not letting me paste from file onto the bootsector.
Any ideas/help is much appreciated.
I am 99.9% sure that you won't be able to use bootloader with USB. Because, bootloader is initialized first then it loads the Operating System, which loads USB drivers. It can work if you can trick your machine to look for USB as a primary booting device (I was using a P4 with XP and couldn't get my system to do it). The thing that worked for me was a Floopy Drive, it was back in 2006 !
You can use a Virtual Machine as suggested by Federico, and emulate the USB drive as a booting device, that's the best option.
Follow the link given below . I think it will help you to make bootloader as "Hello World" in your usb .
http://pcguide4you.blogspot.in/2011/09/designing-simple-hello-world-bootloader.html