Technical information

The primary purpose of this section of the documentation is to be a source of information for those who want to make their enhancements to chos, but is also an source of information for anyone interested in how things work.
There's a lot to do in here.

The boot process

  1. The BIOS loads the MBR at 0x7c00 (0x07c0:0000) and jumps there.
     (MBR (Master Boot Record) is the very first sector on storage devices. Normally bios first tries to boot off fd0 and then hda, but the sequence can usually be configured. Some bioses (at least mine) can also boot off an IDE CD.)
  2. Chos bootsector:
    1. First, if mbr rewrite is enabled, a safe copy of it will be made at 0x6000. (Data in the version at 0x7c00 will be modified and we don't wanna save the changes on disk.)
    2. 5 sectors of 2nd stage loader will be loaded at 0x8000 (STAGE2_OFF)
    3. 2 sectors of mapfile will be loaded right after it (at DATA_OFF and IMAGES_OFF) .
    4. Now it'll jump to the second stage loader
  3. 2nd stage loader:
    1. State of 'single-shot autoboot' will be checked. If it is enabled, the flag will be cleared and first mapfile sector will be rewritten on disk. Proceed to step 3.5
    2. First the state of autoboot will be checked. If it matches with the modifier keys pressed, proceed to step 3.5.
    3. The background file will be loaded at text video memory (0xb8000) and the image names will be printed on screen.
    4. Now the loader will just wait for user to choose an image to start. If there's no user input in given number of seconds, the first image will be chosen.
    5. Once the image to be started is known, the 2nd stage loader will first determine the required OS-specific loader and load it at 0x9000 (LOADER_OFF). After that, the sector specified by MF_ImageDes::device and MF_ImageDes::addr will be loaded at 0x8e00 (MAP_OFF).
    6. Control will be transferred to the OS-specific loader by jumping at 0x9000.
  4. OS-specific loader. Currently available are the bootsector loader and Linux loader:
    • The bootsector loader:
      1. The bootsector will be moved from MAP_OFF to it's rightful place at 0x7c00.
      2. If the partition table will be rewritten, now it's time to do that.
      3. If any drives will be swapped, new int13h handler will be installed at this point.
      4. If dos4boot is enabled, a flag in the bootsector at 0x7c00 will be set.
      5. Jump to the OS's bootsector at 0x7c00.
    • The Linux loader:
      1. If the image was started with space, let the user enter a new command line over the default at MAP_OFF+0x10..
      2. Process the command line. (Handle 'vga=' and copy rest at INIT_SEG::0xdc00.)
        Append 'auto' at the end of the command line if started automagically (i.e. with default command line).
        Append 'BOOT_IMAGE=<IMAGE_NAME>' at the end of the command line.
      3. Load initial ramdisk at given address if one's to be loaded.
      4. Load linux bootsector at INITSEG and setup variables there.
      5. Load linux setup sectors at SETUPSEG.
      6. In case of zImage, load the kernel at 0x10000. In case of bzImage load it at 0x100000 (1M).
      7. And now it's time the enter Linux at SETUPSEG::0.

Modules

Choose-OS supports OS-specific loader modules. Bootsector and Linux loaders exist at the moment. A loader module must begin with the following:
.globl 	_main
.org    LOADER_OFF
_main:  jmp     real_entry_point_of_this_module

.org    LOADER_OFF+2
chos_id:        .ascii  "CHO"
chos_stage:     .byte   BIT_xxx|0x10
chos_major:     .byte   CHOS_MAJOR 
chos_minor:     .byte   CHOS_MINOR 

...

real_entry_point_of_this_module:
LOADER_OFF is 0x9000, so the assembled/compiled loader will be big, but the extra 0x9000 bytes+32 bytes of header will be stripped from the final raw loader. This way the OS-specific loaders can use the same segment as the 2nd stage loader - which is compiled at 0x8000 - does.

A loader is also required to include chos/module.h, which defines the addresses for 2nd stage loader exported variables and function pointer table entries. Such functions should be called with the CALL(FN_NAME) macro. Variables can be accessed normally.

References

Here are some good sources of information: