Page 1 of 1
Passing settings
Posted: Fri Feb 12, 2010 6:15 am
by tera4d
Hello, Users!
Currently I am writing my own bootloader. And I was thinking what is the best way to pass through information from the bootloader to the kernel. I have a multiple stage bootloader the first stage searches the second stage by a fat12 specification and the second stage sets everything up and then it loads the kernel also by a fat12 specification. However I would like to pass on some information from my bootloader to my kernel? What would be the best way to do this? I thought maybe reserve a memory address and store the information there so that the kernel can also access it and read it out. Or is it somehow possible to pass a parameter to the kernel like grub does?
-Tera4D
Re: Passing settings
Posted: Fri Feb 12, 2010 6:35 am
by AJ
Hi,
There are a few ways to do this - here are my thoughts on each. I don't know what language you have used for your kernel, but I'll assume C/C++ because that's what I'm familiar with.
1. Fixed address (e.g. 0x1000) - simple to implement but makes the assumption that memory at 0x1000 (or whatever) is free, when you should be allocating dynamically from the BIOS System Memory Map.
2. Pass by register (a la GRUB) - if in long mode, do this in RDI and your compiler (which follows the System V ABI) will just pick up the value as the first function parameter without troubling the stack. In 32 bit mode, you will need a specialist assembly stub to set up a stack and store / pass the function for your C code.
3. Pass by stack or your compiler's usual calling convention (my preferred option). My second stage loader for CBoot always set up a stack for the kernel and passed the usual argc / argv combination. This meant that the kernel's main function looked just like an application's main function - but the whole thing needed a bit more setting up. One of the nice, clean things about this is that you do not need a statically linked assembly stub.
Whatever you do, use a magic number and / or checksum so that the kernel can verify it has been booted by your loader.
Cheers,
Adam
Re: Passing settings
Posted: Fri Feb 12, 2010 6:50 am
by tera4d
Thank you for your fast response Adam.
You are right my kernel is going to be written in C (I actually have not started a kernel yet)
I made some simple kernels which only display a message for testing.
But with a magic number you mean first I write a number (0xAFFAAFFA for example) to the adress space (0x1000 for example) and then in my kernel ill verify that it actually is 0xAFFAAFFA and then read on?
But if doing this wouldnt it be better like lets say. Create a configure program which loads this and then jumps to the kernel?
-Tera4D
Re: Passing settings
Posted: Fri Feb 12, 2010 7:13 am
by AJ
tera4d wrote:But with a magic number you mean first I write a number (0xAFFAAFFA for example) to the adress space (0x1000 for example) and then in my kernel ill verify that it actually is 0xAFFAAFFA and then read on?
That's it. You should do this whichever method you use to pass settings.
But if doing this wouldnt it be better like lets say. Create a configure program which loads this and then jumps to the kernel?
Not too sure what you mean here, but let me outline a fairly dynamic system as outlined in point 3 above:
- Stage 1 loader, a boot sector which loads stage 1.5 from the FAT12 disk, passes (in ax, for example) the address of its "readFile" function and then jumps to your second stage.
- Stage 2 loader, a combination of 16 and 32 bit code, written in assembly. This creates a system memory map and then loads the kernel using stage 1's readFile function. The kernel can be loaded above 1 MiB if you keep switching between RMode and PMode. The Stage 2 loader could even contain an ELF relocator if your kernel is in ELF format.
- Stage 2 now sets up paging and an initial stack. It also sets up your information table, with the magic number, address of the memory map and whatever else you like. Because Stage 2 has access to the system memory map, it can do all this in memory which you *know* to be free.
- Push argc (1) and argv (the address of stage 2's information table) and call the kernel entry point.
- The kernel checks that argc == 1 and that *argv == MAGIC_NUMBER. If so, it continues as normal.
If you want to extend the above scheme with config files that let you read a custom kernel name or whatever, feel free to do so. Although there are plenty of ways to do the same thing, the above outlines my prefered system.
Cheers,
Adam
Re: Passing settings
Posted: Fri Feb 12, 2010 8:10 am
by tera4d
Thank you very much!
You stated it clearly enough for me to understand hahha ^^
Re: Passing settings
Posted: Fri Feb 12, 2010 8:58 am
by Solar
Doing it via command line has the additional benefit that users could employ a different bootloader (e.g. GRUB or LILO) with minimum adaption work.
Re: Passing settings
Posted: Fri Feb 12, 2010 9:52 am
by tera4d
Thats true, However I dont think that I can pull that off haha.
I'd better stick with something easy as I am not very expirienced with both asm and osdevelopment.
Altough I am learning on the go
Re: Passing settings
Posted: Mon Apr 05, 2010 11:39 am
by Love4Boobies
I see all the usual ways already mentioned. I'll provide links to the Multiboot specifications in case anyone cares:
- Multiboot 1 - using a register to pass the address to a structure
- Multiboot 2 (WIP!) - using a tag-based approach
Note: The Multiboot 2 draft on GRUB's wiki has been abandoned, this is the true Multiboot 2.