I'm trying to write a OS for my own use, I want to show a blank (black) screen with VGA output but I have some problems(questions):
Under FAT32, I have MBR bootloader to read the first sector of the virtual disk image generated by bximage from Bochs. Where (which sector) should I put the second compiled code that shows the black screen? How to do it with dd utility? My second compiled code file is 9 Bytes only.
Is VBR necessary?
How do I know where the data region (FAT32) starts and ends?
I rewrote the bootloader provided from this link.
My disk file specifications is: 20M, CHS 40/16/63
In chronological order...
Originally there were no hard disks and (if you weren't using "BASIC in ROM") computers booted from a floppy disk. In this case the first sector of the volume (the floppy disk) contains the operating system's boot loader.
Not long after hard disks got added, and worked using a similar scheme (where the first sector of the volume/hard disk contains the operating system's boot loader).
However, people soon realised that using a whole "large" hard disk for a single volume is silly/inflexible; so a partitioning scheme was invented to split the hard disk into multiple volumes. In this case the first sector of the disk (the MBR) contains a partition table where one is marked as the "active" partition, and some code to "chain load" the first sector of the active partition (the boot loader). This became "extremely standard", then people extended it to support multiple different operating systems, and most boot managers support multiple operating systems using this method.
Note 1: I define "boot manager" as something you use to choose which OS to boot, and "boot loader" as something designed to boot the specific OS that was chosen. Ideally these have nothing to do with each other, the boot manager should have nothing to do with any OS, and the end user should be able to change the boot manager with anything they like without upsetting or effecting any OS or any boot loader. Sadly, (for Windows) Microsoft are hostile towards allowing multiple different operating systems to boot using simple, sane and well supported methods (including allowing multiple instances of the same version of Windows to be installed at the same time, which could be useful - e.g. one OS for your work stuff and a separate OS for your kids both installed on the same computer) and try to smother sanity with their own "boot.ini" idiocy that mostly just makes everything horrid for no benefit (other than giving Microsoft more control over what you do with your computer). Of course when the user is only installing one OS on the computer it's nice for the OS installer to (optionally, if and only if the user wants it - e.g. because they don't already have their own boot manager) provide and install a minimal MBR that doesn't nothing more than chain load the operating system's boot loader.
As time passed more devices got added. The first was network cards and the ability to boot from network. This is nothing like "boot from disk". Instead, the network card's ROM (after some negotiation with a DHCP server) downloads an entire "boot file" (which is not limited to 1 sector and can be 500 KiB if you like) from a server, then provides an API (which became known as the "PXE API") that the boot loader can use to access networking (e.g. send/receive packets, download more files using the TFTP protocol, etc).
The other type of device that got added was CD-ROM. For these, a new specification ("El Torito bootable CD-ROM specification") was created, partly so that you could have a boot catalogue with multiple entries for multiple architectures (e.g. one for "80x86 PC", one for "PowerPC", etc) and let the firmware choose the most appropriate boot loader for the computer being booted. For this there are 3 methods for PCs - emulate a floppy disk, emulate a hard disk, or "no emulation". The emulation options work the same as original "boot from disk" method (and use 512-byte sectors, etc), but are limited and slow and probably shouldn't be used for anything other than compatibility with legacy operating systems. For "no emulation" it's completely different to the original "boot from disk" method, firmware is supposed to load an entire "boot file" (which is not limited to 1 sector and can be 500 KiB if you like), and sectors will be 2048 bytes (and not 512 bytes).
Even later; UEFI got invented. For 80x86 PCs this comes in 2 flavours - 32-bit 80x86 and 64-bit 80x86. In theory you can have a 64-bit UEFI boot loader that switches to protected mode/32-bit and starts a 32-bit OS; and you can have a 32-bit UEFI boot loader that switches to long mode/64-bit and starts a 64-bit OS. However, 32-bit UEFI is very rare (a few old Apple Mac's and almost nothing else) and these computers are likely to also support "BIOS compatible boot"; and isn't worth supporting 32-bit UEFI for that reason. For UEFI in general, it loads and executes an entire file (from whatever the boot device was) and provides an API that the boot loader can use (e.g. to setup a video mode, get a memory map, load other file/s, etc).
Note 2: UEFI tries to make it so that boot works the same regardless of which type of device you're booting from. In practice this doesn't work very well and you'll probably want a different boot loader for CD (that accesses file/s on the CD itself and isn't restricted to a weeny FAT file system image) and a different boot loader for network (even if it's only to allow you to pass IP addresses to the OS and avoid repeating the slow DHCP stuff after the OS boots).
With UEFI a new partitioning scheme was also introduced (GPT or "GUID Partition Table"). This has multiple advantages and (for new operating systems being installed as the only OS on a computer) should probably be considered the default (and the old "MBR partitions" should probably be considered obsolete for compatibility with old operating systems only).
Mostly; for 80x86 you'll probably need 4 or more different boot loaders:
Of course all of these cases are "different enough" that it's silly to try to have a generic boot loader that covers multiple different cases (and in cases where there are similarities things like "512-bytes only" restrictions are so limiting that you'll be doomed if you try).
I'd also "strongly recommend" having some kind of abstraction between boot loader and the rest of the OS (e.g. a "boot protocol" defined for the OS that describes how a boot loader sets things up, passes information to the OS and transfers control to the OS); such that none of the code in the entire OS needs to know or care what the firmware was (if it was BIOS or UEFI or something else, like maybe kexec()
). This means that anyone can create more boot loaders (to support other cases and other devices); and (as long as everything complies with your abstraction's specification) the entire OS will work with the new boot loader/s without any changes.
Under FAT32, I have MBR bootloader to read the first sector of the virtual disk image generated by bximage from Bochs. Where (which sector) should I put the second compiled code that shows the black screen? How to do it with dd utility? My second compiled code file is 9 Bytes only.
This is mostly wrong. For "BIOS hard disk" you should have an MBR (that has nothing to do with the OS at all) and partitions, and your operating system's boot loader should begin in the first sector of the partition (and should be designed to use DS:SI
to find the partition table entry that describes its partition, and dl
to determine which device the partition is on).
Is VBR necessary?
For some cases (booting from UEFI, network, CD-ROM) a VBR doesn't make sense. For some cases (booting from BIOS hard disk or BIOS USB flash) it's "theoretically optional" but extremely recommended; because some BIOSes may not recognise it (especially for the USB flash case), and other operating systems will assume that the disk isn't formatted (and will tell their users that the disk needs to be initialised/partitioned, convincing the user that your OS is garbage and leading to the user accidentally or intentionally wiping your OS off the disk).
How do I know where the data region (FAT32) starts and ends?
For FAT; there's fields in the BPB ("BIOS Parameter Block", which is misnamed as it's mostly not used by the BIOS at all) in the first sector of the volume/partition that tell you things like how many reserved sectors there are, how many sectors are in each cluster, etc. Really, if you're going to use one of the world's worst file systems for inappropriate things (e.g. for an operating system's main partition where things like effective permissions/security and fault tolerance are sorely needed) then you'll need to learn everything about FAT32 so that you can write code to allow the OS to support it after boot.