Boot Loader Tutorial Idea
Boot Loader Tutorial Idea
Hey all,
I've been pretty inactive for a while, but slowly getting back into my os coding. I know from my early works how much trouble I had with my boot loaders. The tutorials and information out there are pretty good at explaining the very basic concepts but there isn't much out there in the way of a comprehensive guide to all the things you should/could do as part of your boot-loaders.
My 2 stage loaders were designed with a few assumptions specific to my requirements in that I do not want to support partitions and I wanted to have a single unified boot-code that could be deployed to USB(floppy emulated or hdisk emulated) as well as bootable cd, proper hdisk and floppy disk and boot correctly from all of these scenarios. I didn't investigate network boot as it's not something I require.
I did do some investigations into EFI/UEFI and although it has some promising features it looks to me like it's still not widely adopted enough to be that useful (correct me if i'm wrong on this?)
I know that the MAC uses UEFI (but then they have exclusive control of their mainboard/platform).
I think there would be some value in compiling a full detailed guide with all our thoughts/findings/samples for what should go into a "modern" boot loader setup. I know a lot of ppl will be using GRUB and other ready-to-go setups, but this is after all all about rolling your own. We could cover many of the nuances of usb boot that I've found over time in home some mainboards require an FDD-emulated boot sector to have BPB and others not, as well as TPM modules. Much is already documented in sub tutorials and we could just reference those as needed like unreal mode/a20 gate/vbe/vga hw/pmode/longmode etc..
The end result should be something along the lines of.. "what are all the various steps and stages that need to be taken into account to boot a modern OS like win7/lux" but with the specifics left out like choice of FS (ie how to locate files under fat16/fat32 etc).
And we could (hopefully) compile a near-complete list of all the subtle nuances like fdd-emulation differences in bioses / 13h extended functions work sometimes/not others / can u use 13h ext. functions to load files of el-torito or should you load them use iso9660 spec. etc
Anyhow, it's just a thought and something I'd be happy to contribute all the code and notes i've compiled thus far into if anyone else is keen.
I've been pretty inactive for a while, but slowly getting back into my os coding. I know from my early works how much trouble I had with my boot loaders. The tutorials and information out there are pretty good at explaining the very basic concepts but there isn't much out there in the way of a comprehensive guide to all the things you should/could do as part of your boot-loaders.
My 2 stage loaders were designed with a few assumptions specific to my requirements in that I do not want to support partitions and I wanted to have a single unified boot-code that could be deployed to USB(floppy emulated or hdisk emulated) as well as bootable cd, proper hdisk and floppy disk and boot correctly from all of these scenarios. I didn't investigate network boot as it's not something I require.
I did do some investigations into EFI/UEFI and although it has some promising features it looks to me like it's still not widely adopted enough to be that useful (correct me if i'm wrong on this?)
I know that the MAC uses UEFI (but then they have exclusive control of their mainboard/platform).
I think there would be some value in compiling a full detailed guide with all our thoughts/findings/samples for what should go into a "modern" boot loader setup. I know a lot of ppl will be using GRUB and other ready-to-go setups, but this is after all all about rolling your own. We could cover many of the nuances of usb boot that I've found over time in home some mainboards require an FDD-emulated boot sector to have BPB and others not, as well as TPM modules. Much is already documented in sub tutorials and we could just reference those as needed like unreal mode/a20 gate/vbe/vga hw/pmode/longmode etc..
The end result should be something along the lines of.. "what are all the various steps and stages that need to be taken into account to boot a modern OS like win7/lux" but with the specifics left out like choice of FS (ie how to locate files under fat16/fat32 etc).
And we could (hopefully) compile a near-complete list of all the subtle nuances like fdd-emulation differences in bioses / 13h extended functions work sometimes/not others / can u use 13h ext. functions to load files of el-torito or should you load them use iso9660 spec. etc
Anyhow, it's just a thought and something I'd be happy to contribute all the code and notes i've compiled thus far into if anyone else is keen.
Re: Boot Loader Tutorial Idea
I like your idea. I have made a lot of boot loaders in the past, but I think the tutorial should be kept simple, after all it is for new developers.
I'm willing to help there, if everyone else thinks it is a good idea.
However, to state on the other side of the case, there are a lot of people who like theory tutorials, (me being one) because it gives the concepts to apply, and thus what you figure out is more your own code. But I think there are enough people who would appreciate this.
David
I'm willing to help there, if everyone else thinks it is a good idea.
However, to state on the other side of the case, there are a lot of people who like theory tutorials, (me being one) because it gives the concepts to apply, and thus what you figure out is more your own code. But I think there are enough people who would appreciate this.
David
President of the Useless OS project
Re: Boot Loader Tutorial Idea
Not just good, but great idea!
I'm trying to make a more robust and practical CD/DVD-ROM bootloader now. It was hard to ever get started because nearly everyone uses floppies or a pre-existing bootloader. What I have so far definitely isn't tutorial worthy, but I'll be more than happy to share whatever I learn when its in better condition (which will be soon).
I think moving in this direction overall is a great idea. When you go buy Mac OS or Windows, you get a CD/DVD, not a floppy! Not being critical of anyone (as I have NO room to be), but I think CDs, DVDs and USB drives are much more elegant, and of course, grant you much more space. My computer doesn't even HAVE a floppy drive, lol. I think it's an all around more modern and robust solution for deployment, and can often be required for certain projects (like my [non-desktop] research project). I say, out with the 80s and in with the 90s! Well, at least some more tutorials and collaboration on alternative deployment options!...
I'm trying to make a more robust and practical CD/DVD-ROM bootloader now. It was hard to ever get started because nearly everyone uses floppies or a pre-existing bootloader. What I have so far definitely isn't tutorial worthy, but I'll be more than happy to share whatever I learn when its in better condition (which will be soon).
I think moving in this direction overall is a great idea. When you go buy Mac OS or Windows, you get a CD/DVD, not a floppy! Not being critical of anyone (as I have NO room to be), but I think CDs, DVDs and USB drives are much more elegant, and of course, grant you much more space. My computer doesn't even HAVE a floppy drive, lol. I think it's an all around more modern and robust solution for deployment, and can often be required for certain projects (like my [non-desktop] research project). I say, out with the 80s and in with the 90s! Well, at least some more tutorials and collaboration on alternative deployment options!...
There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence. - Jeremy S. Anderson
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
Re: Boot Loader Tutorial Idea
Greetings,
Master Boot Record (512 bytes):
Part 1 (512 bytes; CD):
Part 3 (a file on the disk):
Network booting isn't actually supported because I don't need it at the moment. All I know about it is that you could either use the PXE API or write your own drivers for each network device.
Boot loaders are really specific to your requirements, like I said before some people might just do everything in the 512 bytes they got and then just set up everything else in the kernel.
Regards,
Stephan J.R. van Schaik
There are actually way too many things you could do. Here's a list of what my boot loader does:johnsa wrote:I've been pretty inactive for a while, but slowly getting back into my os coding. I know from my early works how much trouble I had with my boot loaders. The tutorials and information out there are pretty good at explaining the very basic concepts but there isn't much out there in the way of a comprehensive guide to all the things you should/could do as part of your boot-loaders.
Master Boot Record (512 bytes):
- Relocate itself to 0000:0600.
- Search for the active entry in the partition table (Note: test BYTE [si], 0x80 will tell you this, most MBRs I've seen use cmp instead).
- Check if the active entry uses LBA (unofficial) or CHS (Note: test BYTE [si], 0x01 will tell you this, but you might drop this support as it is unofficial).
- Get the disk geometry if it is a hard disk (Note: it should be possible to use a MBR on a floppy, but nobody really does this).
- Check for the availability of the extended read/write functions.
- Load the actual boot sector and jump to 0000:7C00 (Note: dl is reset to the disk drive and si to the start of the partition table).
- Support extended partitions (Note: the lazy way could simply be booting the extended partition's MBR).
- Support GPT and perhaps (U)EFI.
- Support your own partition table, as it is theoretically possible, however all other operating systems will not be able to support it.
- Set up VGA properly and display error messages and/or use the PC Speaker.
- Nullify cs (a.k.a. jump to 0000:7C00).
- Set up the other segments and set up the stack at 0000:1000.
- Get the disk geometry if it is a hard disk.
- Check for the availability of the extended read/write functions.
- Load the second part and jump to 0000:1000 (Note: dl is set to the disk drive).
Part 1 (512 bytes; CD):
- Nullify cs (a.k.a. jump to 0000:7C00).
- Set up the other segments and set up the stack at 0000:1000.
- Check if the CD is booted as non-emulated.
- Relocate the second part and jump to 0000:1000 (Note: dl is reset to the disk drive; CD-ROM bootsectors are generally 2kB).
- Get the disk geometry if it is a hard disk.
- Check for the availability of the extended read/write functions (Note: actually optional for CDs).
- Parse the filesystem and search for the third part.
- Load the file off the disk and jump to 0000:1600 (Note: dl is set to the disk drive).
Part 3 (a file on the disk):
- Test if the CPU is actually supported (80386+ and required instructions).
- Check if the system is a multi-processor system and what processors are on-board and also check their co-processor.
- Ensure that CPUID is enabled if it is available (Note: required for Cyrix and NexGen processors, if I remember well)
- Check for the availability of long mode, PAE, PSE36, etc.
- Set up a memory map using int 0x15.
- Ensure VGA is set up properly (or set up VBE).
- Load the 32-bit kernel or the 64-bit kernel (and additional modules) off the disk depending on whether long mode is properly supported or not (TODO: separate filesystems drivers to use in the boot loader) (Note: unreal mode, switching in between real and protected mode).
- Enter protected/long mode and execute the kernel (Note: includes setting up A20, GDT, etc.).
Network booting isn't actually supported because I don't need it at the moment. All I know about it is that you could either use the PXE API or write your own drivers for each network device.
Boot loaders are really specific to your requirements, like I said before some people might just do everything in the 512 bytes they got and then just set up everything else in the kernel.
I only know some/most Itanium/Intel servers support it as well as the x86(-64) Macintosh platform.johnsa wrote:I did do some investigations into EFI/UEFI and although it has some promising features it looks to me like it's still not widely adopted enough to be that useful (correct me if i'm wrong on this?)
I know that the MAC uses UEFI (but then they have exclusive control of their mainboard/platform).
Also, some BIOSes support booting USB as HD or USB as CD as well as Zip100, LS120, etc., although Zip100 and such aren't really worthwhile to actually support. I am not sure if there actually BIOSes which support direct USB though. Most articles on the Wiki covering boot loading provide a lot of information already, but seem to missing some things here and there like perhaps USB-booting and proper A20 setup.johnsa wrote:I think there would be some value in compiling a full detailed guide with all our thoughts/findings/samples for what should go into a "modern" boot loader setup. I know a lot of ppl will be using GRUB and other ready-to-go setups, but this is after all all about rolling your own. We could cover many of the nuances of usb boot that I've found over time in home some mainboards require an FDD-emulated boot sector to have BPB and others not, as well as TPM modules. Much is already documented in sub tutorials and we could just reference those as needed like unreal mode/a20 gate/vbe/vga hw/pmode/longmode etc..
The end result should be something along the lines of.. "what are all the various steps and stages that need to be taken into account to boot a modern OS like win7/lux" but with the specifics left out like choice of FS (ie how to locate files under fat16/fat32 etc).
And we could (hopefully) compile a near-complete list of all the subtle nuances like fdd-emulation differences in bioses / 13h extended functions work sometimes/not others / can u use 13h ext. functions to load files of el-torito or should you load them use iso9660 spec. etc.
Regards,
Stephan J.R. van Schaik
Re: Boot Loader Tutorial Idea
To get started with here are the first 6 steps in my 1st stage loader. Shall we review this confirm accuracy and refine. Then We can update the doc. and move on.
Once it's all complete we add to wiki?
Once it's all complete we add to wiki?
Code: Select all
;=============================================================================================================
INTRODUCTION
;=============================================================================================================
*** add intro text about what is a boot-sector etc from other wiki/tuts ***
Our objective is to create a single unified 512 byte first stage boot loader that can be deployed to any
modern boot device and work as planned.
The first thing we need to understand and identify is what are these devices and what are the subtle
differences between them? (IE: BIOS bugs, incompatabilities or generally poorly followed standards).
Is it possible to have a single boot-sector that works for all devices?
The list of bootable devices we wish to support are:
- Real Floppy Disk
- Real Hard Disk
- USB Flash Stick (under FDD emulation from BIOS)
- USB Flash Stick (under HDD emulation from BIOS)
- CDROM/DVDROM (either natively or via FDD image emulation)
USB boot is achieved through emulation. The BIOS will either assume the USB Stick to be a floppy or hard-disk
and emulate accordingly both in terms of what is passed into the boot-loader in the DL register as well as the
INT 13h disk functions. It is also possible that USB sticks will appear as ZIP drives but this is something
we're not interested in and can ignore.
Some BIOSes (most new ones i've tested) are capable of booting from USB there are however several pre-requisites:
#1 the BIOS must support it and not have a bug
#2 the USB stick in question must be bootable (probably a USB2.0 stick)
#3 some BIOSes that boot USB under FDD emulation specifically require there to be a BPB / FAT table at the beginning
of the boot-code. For this reason I have listed it below even though in my design it's completely redundant.
The file system I plan to use doesn't work like a traditional FS and as such I make the following assumptions:
1) I don't support or believe in partitions. In 20 years and hundreds of machines I've never needed or used one.
My policy is if you need multiple logical volumes, install multiple physical volumes. My OS is not intended to
support multi-boot.
2) There is no manadatory requirement to store the OS loaders or kernel binary within the file-system (confirm?)
I chose to store these linearly at the beginning of whatever device is in question and the relevant file
system information comes directly after that. There maybe some pros/cons to this?
3) Because I don't use/need the BPB and my boot code is intended to be unified it will be present even in the
boot-sector of a hard-disk/cd etc.
; Initial Memory-Map after POST (Power on self test).
;
; 0000:0000 - 0000:03FF [ IVT Interrupt Vector Table ]
; 0000:0400 - 0000:04FF [ BIOS Data Area 40h:0000 ]
; 0000:0500 - 0000:7B00 [ Free use memory ]
; 0000:7B00 - 0000:7C00 [ Boot Loader Stack ]
; 0000:7C00 - 0000:7DFF [ BIOS Boot Load Area ]
; 0000:7E00 - 9000:FFFF [ Free use memory ]
; A000:0000 - B000:FFFF [ VGA Video Memory ]
; C000:0000 - F000:FFFF [ BIOS ROM Memory Area ]
; FFFF:0010 - FFFF:FFFF [ Free use memory - A20 enabled ]
; FEC00000 - FFFFFFFF [ motherboard BIOS, PnP NVRAM, ACPI etc ]
;=============================================================================================================
STEP 0 (BPB table for compatability with USB FDD emulated booting)
;=============================================================================================================
org 0h
start:
;-----------------------------------------------------------------------------------
; Some BIOSes look for this BPB/BS to enable USB-FDD emulation, we'll never use it again...
; -> We'll cheat and use some of it's entries as our variables to save space.
;-----------------------------------------------------------------------------------
jmp short begin
nop
OEM DB "VXOS "
m_sectorsize DW 512 ; We're using this as our sector size variable.
Sectors_per_cluster DB 1
Reserved_sectors DW 1
Number_of_FATs DB 2
Root_entries DW 224
Total_sector_count DW 2880 ; 80*2*18
Media_descriptor DB 0F0H ; Floppy
Sectors_per_FAT DW 9
Sectors_per_track DW 18
Heads DW 2
m_cylinders DD 80
m_sectors DD 18
bsDriveNumber DB 0
Unused DB 0
bsExtBootSignature DB 29h
m_heads DD 2
bsVolumeLabel DB "VXOS "
bsFileSystem DB "FAT12 "
;=============================================================================================================
STEP 1 (Load Address Normalization)
;=============================================================================================================
Some BIOSes will load the bootsector (512bytes) to 07c0:0000 while some will load it to 0000:7c00.
The flat binary assembler source will have been create to be at one of these by use of either:
org 0h (assuming the segment is 07c0)
or
org 7c00h (assuming the segment is 0 and the offset is 7c00)
Either way you need to ensure this is always fixed.
In my first stage loader I work with a segment and the offset at 0.
So org 0h in the source and then a hardcoded far jump to force the segment to set
db 0eah
dw offset cs_correction, 07c0h
cs_correction:
;=============================================================================================================
STEP 2 (Stack location choice and setup)
;=============================================================================================================
Setup the stack (I chose to keep it just below the initial load address of the boot loader).
xor ax,ax
mov es,ax ; Set ES = 0000.
mov ss,ax ; Configure Temporary Stack Just below Bootloader.
mov sp,(7c00h-16)
;=============================================================================================================
STEP 3 (Obtain boot drive number)
;=============================================================================================================
The possible values the BIOS will give us are:
00h (First floppy)
01h (Second foppy)
80h (First hard disk)
81h (Second hard disk) and so on..
Store the drive number that the BIOS passes us in DL. We must ensure DS is valid and = to CS.
mov m_driveNo,dl
;=============================================================================================================
STEP 4 (Transfer code location and jump)
;=============================================================================================================
Move the first stage loader to a safe location and continue execution.
The reason I previously selected to use 07c0:0000 instead of the offset model is that it makes this
step a bit easier. I can copy the entire boot-loader code (512 bytes) to a new segment address
and then use a label directly after the far jump as the same offset for that jump (as the labels
offsets relative to the segment remain unchanged, this applies to variables etc as well).
I chose 0060:0000 as the destination (this is the address used by DOS 1.x apparently) and from looking
at a memory map after boot this space should be safe.
xor si,si ; DS:SI = begin of original bootloader (7c00:0000).
mov di,600h ; ES:DI = destination (0000:0600).
mov cx,100h ; Copy 256 words (512 bytes).
rep movsw ; Copy bootloader.
db 0eah ; Hardcode force far jmp.
dw offset bootloader_exc0,0060h ; new code addr = (0060:bootloader_exc0).
;---------------------------------------------------
; Bootloader will commence from here at new address.
;---------------------------------------------------
bootloader_exc0:
;=============================================================================================================
STEP 5 (Ensure segment registers are setup).
;=============================================================================================================
Ensure the data segment register correlates to CS.
push cs ; CS and DS = 0060h.
pop ds
;=============================================================================================================
STEP 6 (Determine code path based on drive number)
;=============================================================================================================
In theory, if all emulations work correctly we only need to know if the boot drive number (DL)
was >=80h or not. That way we can use two pieces of code to load 2nd stage loader which should support
FDD/USB emulated FDD/CDROM FDD image/DVDROM FDD image
and HDD/USB emulated HDD
;--------------------------------------------------------------------------------
; Did we get booted from a floppy, harddisk, usb or cdrom?
; -> USB will emulate a HDD boot (80h) or FDD (00h). same for CD-ROM (ElTorito).
;--------------------------------------------------------------------------------
cmp m_driveNo,80h
jae skip_not_floppy
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Boot Loader Tutorial Idea
You forgot the EBDA - if you're paranoid you shouldn't load above 8000:0000 without checking. I haven't personally seen cases myself where 9000:7FFF as a limit doesn't work.; 0000:7E00 - 9000:FFFF [ Free use memory ]
Re: Boot Loader Tutorial Idea
Nice spot! thanks, I'll add that in. Any other thoughts? These are purely my observations that I've seen to work sofar, but we all know how fickle pc hardware is especially with a complete lack of standards adoption
I'm not 100% sure if my thoughts around my BPB cheating/no partitions etc are legitimate and will work in all cases.. This is obviously purely for my design and others may want to stick to a traditional MBR and file-systems like fat16/32.
I'm not 100% sure if my thoughts around my BPB cheating/no partitions etc are legitimate and will work in all cases.. This is obviously purely for my design and others may want to stick to a traditional MBR and file-systems like fat16/32.
Re: Boot Loader Tutorial Idea
Just on the EBDA note, In my stage 2 loader I do the following:
giving the segment address of the ebda.
which we'll come to later (for now in stage 1 we just assume not to load over 8000:0000). I actually think I did have an issue with this once before on some machines, which oddly only turned up when i booted them from CD(fdd emulation) but from USB it worked. Obviously some data was getting over-written that affected something specific to the EBDA/emulation when trying to then read sectors via INT13 ext. This happen when loading kernel image in stage 2 and I moved it down to load at 7000:0000.
I also assume the EBDA to be max 4kb in size? correct? (Else it would run into video memory). Safe way to work would be to get the EBDA address , subtract from A0000 and not use anything in that range?
For my machines It always seemed to be located at the following address:
0009FC00 or segment of 0x9fc0:0000.
Perhaps we should make some quick notes about selection of these load addresses, is there a std. we should all use, like 7c00->move to 600h->load stage2 to 7c00->load kernel in blocks somewhere in mem and then transfer it to hi-mem(1mb)?
Code: Select all
;--------------------------------------------------------------------------------
; Locate and Store BIOS EBDA Address.
;--------------------------------------------------------------------------------
mov ax,40h
mov es,ax
movzx eax,word ptr es:[0eh]
shl eax,4
mov fs:[BIOS_EBDA_ADDRESS],eax
which we'll come to later (for now in stage 1 we just assume not to load over 8000:0000). I actually think I did have an issue with this once before on some machines, which oddly only turned up when i booted them from CD(fdd emulation) but from USB it worked. Obviously some data was getting over-written that affected something specific to the EBDA/emulation when trying to then read sectors via INT13 ext. This happen when loading kernel image in stage 2 and I moved it down to load at 7000:0000.
I also assume the EBDA to be max 4kb in size? correct? (Else it would run into video memory). Safe way to work would be to get the EBDA address , subtract from A0000 and not use anything in that range?
For my machines It always seemed to be located at the following address:
0009FC00 or segment of 0x9fc0:0000.
Perhaps we should make some quick notes about selection of these load addresses, is there a std. we should all use, like 7c00->move to 600h->load stage2 to 7c00->load kernel in blocks somewhere in mem and then transfer it to hi-mem(1mb)?
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
Re: Boot Loader Tutorial Idea
Basically USB is supported via FD-emulation, HD-emulation and CD-emulation and CDs and DVDs are generally supported via FD-emulation and HD-emulation as for emulation. CDs and DVDs should also be supported natively by most BIOSes nowadays, not sure if the same counts for USB.johnsa wrote: - Real Floppy Disk
- Real Hard Disk
- USB Flash Stick (under FDD emulation from BIOS)
- USB Flash Stick (under HDD emulation from BIOS)
- CDROM/DVDROM (either natively or via FDD image emulation)
Zip100, LS-120 and LS-240 are assumably supported as floppy disks or hard disks.johnsa wrote:USB boot is achieved through emulation. The BIOS will either assume the USB Stick to be a floppy or hard-disk
and emulate accordingly both in terms of what is passed into the boot-loader in the DL register as well as the
INT 13h disk functions. It is also possible that USB sticks will appear as ZIP drives but this is something
we're not interested in and can ignore.
IMO a Wiki article should tend to be objective. However, it might be easier for a beginner to not support the partition table or GPT. What your OS is intended or not intended to support doesn't matter, the Wiki article is targeted at (new) OS developers.johnsa wrote: 1) I don't support or believe in partitions. In 20 years and hundreds of machines I've never needed or used one.
My policy is if you need multiple logical volumes, install multiple physical volumes. My OS is not intended to
support multi-boot.
Basically, you could store the binary everywhere on the disk, as long as you know how to get it into memory.johnsa wrote: 2) There is no manadatory requirement to store the OS loaders or kernel binary within the file-system (confirm?)
I chose to store these linearly at the beginning of whatever device is in question and the relevant file
system information comes directly after that. There maybe some pros/cons to this?
You don't need the EBPB (FAT) though (assuming that this is present, as you mentioned it; I'm assuming it is not needed, but it may be by some BIOS, but that would be biased). BPB is simply required for compatibility, but may be dropped as well.johnsa wrote: 3) Because I don't use/need the BPB and my boot code is intended to be unified it will be present even in the
boot-sector of a hard-disk/cd etc.
If all that memory is actually available and if you aren't using the EBDA, like Combuster mentioned.johnsa wrote: ; 0000:7E00 - 9000:FFFF [ Free use memory ]
Virtually, a BIOS could load it to any segment:offset address as long as it represents 0x7C00, but that would be a BadIdea(tm).johnsa wrote: Some BIOSes will load the bootsector (512bytes) to 07c0:0000 while some will load it to 0000:7c00.
The flat binary assembler source will have been create to be at one of these by use of either:
org 0h (assuming the segment is 07c0)
or
org 7c00h (assuming the segment is 0 and the offset is 7c00)
Either way you need to ensure this is always fixed.
Basically, the BIOS could provide you any disk drive it wants to. If it is masked with 0x80, it's safe to assume that it is a hard disk, otherwise it's a floppy disk.johnsa wrote: The possible values the BIOS will give us are:
00h (First floppy)
01h (Second foppy)
80h (First hard disk)
81h (Second hard disk) and so on..
That's only required for the MBR actually, unless this is your intention.johnsa wrote: ;=============================================================================================================
STEP 4 (Transfer code location and jump)
;=============================================================================================================
Move the first stage loader to a safe location and continue execution.
The reason I previously selected to use 07c0:0000 instead of the offset model is that it makes this
step a bit easier. I can copy the entire boot-loader code (512 bytes) to a new segment address
and then use a label directly after the far jump as the same offset for that jump (as the labels
offsets relative to the segment remain unchanged, this applies to variables etc as well).
I chose 0060:0000 as the destination (this is the address used by DOS 1.x apparently) and from looking
at a memory map after boot this space should be safe.
xor si,si ; DS:SI = begin of original bootloader (7c00:0000).
mov di,600h ; ES:DI = destination (0000:0600).
mov cx,100h ; Copy 256 words (512 bytes).
rep movsw ; Copy bootloader.
db 0eah ; Hardcode force far jmp.
dw offset bootloader_exc0,0060h ; new code addr = (0060:bootloader_exc0).
This might be of use.johnsa wrote:Just on the EBDA note, In my stage 2 loader I do the following:
giving the segment address of the ebda.Code: Select all
;-------------------------------------------------------------------------------- ; Locate and Store BIOS EBDA Address. ;-------------------------------------------------------------------------------- mov ax,40h mov es,ax movzx eax,word ptr es:[0eh] shl eax,4 mov fs:[BIOS_EBDA_ADDRESS],eax
which we'll come to later (for now in stage 1 we just assume not to load over 8000:0000). I actually think I did have an issue with this once before on some machines, which oddly only turned up when i booted them from CD(fdd emulation) but from USB it worked. Obviously some data was getting over-written that affected something specific to the EBDA/emulation when trying to then read sectors via INT13 ext. This happen when loading kernel image in stage 2 and I moved it down to load at 7000:0000.
I also assume the EBDA to be max 4kb in size? correct? (Else it would run into video memory). Safe way to work would be to get the EBDA address , subtract from A0000 and not use anything in that range?
For my machines It always seemed to be located at the following address:
0009FC00 or segment of 0x9fc0:0000.
Perhaps we should make some quick notes about selection of these load addresses, is there a std. we should all use, like 7c00->move to 600h->load stage2 to 7c00->load kernel in blocks somewhere in mem and then transfer it to hi-mem(1mb)?
Regards,
Stephan J.R. van Schaik.
Re: Boot Loader Tutorial Idea
Thanks for the detailed response!
I've made some updates regarding the boot emulation/devices, changed the wording and info to avoid being biased towards my design but keeping it simple without a file-system/mbr/partitions. These should be trivial to add if you have the file-system format and plan to do so - and it's all available on the wiki.
I'm leaving the EBPB/BPB bit in as I know some machines I have won't boot a USB at all without that there, even if it's not used. So as you say for compatability I'll keep it - and based on the agreement that it doesn't affect the loading of the
boot loader from any other device type it's of no harm (part of the goal to have a single source / unified loader).
Updated re the EBDA/wiki mem map.
Updated regarding the seg/ofs combinations but basically results in the same thing that you need to force it to a known (IE: compatible with the way you assembled the source).
Updated regarding the code-relocation only being necessary for MBR.
I've made some updates regarding the boot emulation/devices, changed the wording and info to avoid being biased towards my design but keeping it simple without a file-system/mbr/partitions. These should be trivial to add if you have the file-system format and plan to do so - and it's all available on the wiki.
I'm leaving the EBPB/BPB bit in as I know some machines I have won't boot a USB at all without that there, even if it's not used. So as you say for compatability I'll keep it - and based on the agreement that it doesn't affect the loading of the
boot loader from any other device type it's of no harm (part of the goal to have a single source / unified loader).
Updated re the EBDA/wiki mem map.
Updated regarding the seg/ofs combinations but basically results in the same thing that you need to force it to a known (IE: compatible with the way you assembled the source).
Updated regarding the code-relocation only being necessary for MBR.
Re: Boot Loader Tutorial Idea
Objection.johnsa wrote:1) I don't support or believe in partitions. In 20 years and hundreds of machines I've never needed or used one. My policy is if you need multiple logical volumes, install multiple physical volumes. My OS is not intended to support multi-boot.
1) Installing multiple physical volumes is usually not an option with laptops.
2) Whether or not partitions are supported is not up to the filesystem. A filesystem resides inside a partition.
3) If you do not support partitions, you are effectively asking people to completely wipe their system before they can give your OS a try. Freeing up a partition is easy, when compared to the task of backing up (and restoring) hundreds of gigs of data just for a peek-and-try.
3a) Most laptops have hidden partitions that hold recovery data. Not-so-experienced users might wipe out their fallback scenario by accident.
4) It's the task of the OS to enable users. You don't believe in partitions, I never owned a hard drive that had less than three of them (including at least two different OS installations). I never set up a system with less than two partitions (because seperating the OS and the data is a real nice win, especially for backup purposes). You can go ahead and use only a single partition / OS on your system, but not being able to use multiple partitions / OSs on my system is a showstopper for me (and many, many others).
5) I suspect you don't believe in partitions because you find them difficult to support.
Bottom line, anything that goes as "tutorial" must support partitions, IMNSHO.
Every good solution is obvious once you've found it.
Re: Boot Loader Tutorial Idea
I agree that many people like and use partitions. They're not an issue to support really, it's only a little bit of extra work to have an mbr and select a bootable partition. There's quite a lot of info and examples on how to do this.
I see this in two ways, for my OS.. I don't need them, for the tutorial it adds additionally complexity which once the basic "no-partition/no-fs" model is working for you adding the file-system/partition support is relatively easy and well
documented. My main goals here are:
1) the concept of unified boot-loader
2) getting your own boot loaders up and running as quickly as possible (you can expand later with your own requirements/features)
3) ensuring that these boot loaders work under all conditions and on as many systems as possible (if not all)
So many of the boot code sample i've seen are FD specific, too basic. And with most they don't deal with all the little quirks and subtleties. If one never took their boot-loader past these tutorial stages it's unlike that it would actually boot
on more than 50% of the machines out there while the linux/win guys manage to get everything(mostly) booted.
While we're not trying to compete with them (maybe some are) it would be nice to know that we're following the same steps to get to our
kernel (the real meat) up and running on all machines.
A quick question then in terms of native CDROM/DVDROM support.
Sectors are not 512byte (usually 2kb for CD?) so would the BIOS load a 2kb sector and expect the signature to be at the end of the sector or still at the end of the 512 byte block?
Would one use the normal int 13 read functions?
Would it then NOT supply a drive number of 00h or 80h but the "actual" drive number, like 81h etc?
How to check the CD is running natively and not under emulation?
I see this in two ways, for my OS.. I don't need them, for the tutorial it adds additionally complexity which once the basic "no-partition/no-fs" model is working for you adding the file-system/partition support is relatively easy and well
documented. My main goals here are:
1) the concept of unified boot-loader
2) getting your own boot loaders up and running as quickly as possible (you can expand later with your own requirements/features)
3) ensuring that these boot loaders work under all conditions and on as many systems as possible (if not all)
So many of the boot code sample i've seen are FD specific, too basic. And with most they don't deal with all the little quirks and subtleties. If one never took their boot-loader past these tutorial stages it's unlike that it would actually boot
on more than 50% of the machines out there while the linux/win guys manage to get everything(mostly) booted.
While we're not trying to compete with them (maybe some are) it would be nice to know that we're following the same steps to get to our
kernel (the real meat) up and running on all machines.
A quick question then in terms of native CDROM/DVDROM support.
Sectors are not 512byte (usually 2kb for CD?) so would the BIOS load a 2kb sector and expect the signature to be at the end of the sector or still at the end of the 512 byte block?
Would one use the normal int 13 read functions?
Would it then NOT supply a drive number of 00h or 80h but the "actual" drive number, like 81h etc?
How to check the CD is running natively and not under emulation?
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
Re: Boot Loader Tutorial Idea
All will not be possible, unless you treat x86(-64) as the only architecture around and even then it is still impossible as not all x86(-64) systems have a BIOS.johnsa wrote:3) ensuring that these boot loaders work under all conditions and on as many systems as possible (if not all)
People who use Linux generally use GRUB as their boot loader or perhaps LILO, ELILO or ISOLINUX. The only general difference I've seen between most "basic" bootsectors and LILO is their Award BIOS bug fix, however, there might still be more that I haven't actually seen.johnsa wrote:So many of the boot code sample i've seen are FD specific, too basic. And with most they don't deal with all the little quirks and subtleties. If one never took their boot-loader past these tutorial stages it's unlike that it would actually boot
on more than 50% of the machines out there while the linux/win guys manage to get everything(mostly) booted.
The bootsector should commonly be 2kB on a non-emulated CD and 512B on an emulated CD.johnsa wrote:A quick question then in terms of native CDROM/DVDROM support.
Sectors are not 512byte (usually 2kb for CD?) so would the BIOS load a 2kb sector and expect the signature to be at the end of the sector or still at the end of the 512 byte block?
This contains some interesting information about CD sectors.
In my boot loader I check if the INT 0x13 extensions (INT 0x13; AX=0x4100) are available and if it is a hard disk, otherwise I'll just use the "normal" INT 0x13 functions.johnsa wrote:Would one use the normal int 13 read functions?
Not sure what you're exactly asking here.johnsa wrote:Would it then NOT supply a drive number of 00h or 80h but the "actual" drive number, like 81h etc?
The easy/lazy way is to put a signature at the end of the 2K sector so you can simply check if 0x83FC (assuming you're using a DWORD signature) is equal to the signature.johnsa wrote:How to check the CD is running natively and not under emulation?
Regards,
Stephan J.R. van Schaik.
Re: Boot Loader Tutorial Idea
I would hope that unless it's itanium/UEFI it would have a BIOS and then as such our series of steps should work to boot it
All the non server x86-64 machines ive seen sofar are still BIOS, and most of the servers too.
What I was referring to in terms of the non-emulated CD was if the normal int 13 functions still read 2kb sectors correctly, or do you/should you use the extensions if available and on a native CD?
All the non server x86-64 machines ive seen sofar are still BIOS, and most of the servers too.
I do the same. (Although I've often noted funnies with this, where the extensions are reported but then sector reads fail.. but do work with normal int13) .In my boot loader I check if the INT 0x13 extensions (INT 0x13; AX=0x4100) are available and if it is a hard disk, otherwise I'll just use the "normal" INT 0x13 functions.
What I was referring to in terms of the non-emulated CD was if the normal int 13 functions still read 2kb sectors correctly, or do you/should you use the extensions if available and on a native CD?
I like this..The easy/lazy way is to put a signature at the end of the 2K sector so you can simply check if 0x83FC (assuming you're using a DWORD signature) is equal to the signature.
-
- Member
- Posts: 127
- Joined: Sat Sep 29, 2007 5:43 pm
- Location: Amsterdam, The Netherlands
Re: Boot Loader Tutorial Idea
Basically you could assume that INT 0x13 extensions are always available when booting a CD natively as the El Torito standard was made when the INT 0x13 extensions already existed. You could however still check if the INT 0x13 extensions are still available anyway. The normal INT 0x13 functions should still work as the CHS limit is only 8GB. Also, you might want to write a floppy bootsector for booting the CD when the BIOS doesn't have proper support for it, although that is completely optional as most modern systems should support native CD booting.johnsa wrote:I do the same. (Although I've often noted funnies with this, where the extensions are reported but then sector reads fail.. but do work with normal int13) .
What I was referring to in terms of the non-emulated CD was if the normal int 13 functions still read 2kb sectors correctly, or do you/should you use the extensions if available and on a native CD?
Regards,
Stephan J.R. van Schaik.