Page 1 of 1

Multiboot question

Posted: Mon Feb 02, 2009 10:38 pm
by neon
Hey everyone,

Do you think it is fine for a multiboot compliant boot loader to pass additional data to the loaded module/kernel for specific types of kernels? Just curious what others think :)

Re: Multiboot question

Posted: Tue Feb 03, 2009 12:52 am
by AndrewAPrice
Sure! Just make sure it's documented or else no one will use it! But don't they anyway? I've passed like VESA modes into Linux and the path of Initrd and the like..

Re: Multiboot question

Posted: Tue Feb 03, 2009 9:22 am
by JohnnyTheDon
Multiboot is kind of limited, so this would be a great idea. If you just put everything after the defined multiboot fields (and provide some way of testing if the your extended version of the spec is being used) there shouldn't be any problem with legacy software.

Re: Multiboot question

Posted: Thu Feb 05, 2009 3:02 pm
by Ready4Dis
I would advise against it, unless it's data that your OS doesn't actually require (then why are you passing it?). Or at least put something in there for people to detect which version (yours or standard) is currently installed. If your OS requires more information than the multi-boot spec gives you, then it's not multi-boot compliant. Example, if a user installs a multi-boot loader, then your OS without installing your own multi-boot loader, your kernel will be missing information that it is expecting to be there. You would (best case) detect the missing information and fill it in with generic information, and continue booting. Else, you need to warn the user that the OS will not operate correctly, worst case, assume it's there and crash since all the info is incorrect.

Also, your multi-boot loader must be able to recognize a file that is standard multi-boot compliant vs. extended. Otherwise, if your custom information is larger than a standard multi-boot header, you will overwrite part of the kernel while filling in the info! So you need two forms of error checking (one kernel side and one loader side) to determine if an old version is being run (for either). If the standard multi-boot spec is being followed in the kernel, you can only fill out that information (nothing extra). A better idea, would to simply add another structure, and fill it in if it's found, otherwise just fill in the multi-boot header. Then the kernel can see if the info has been updated, if not just refer to the standard multi-boot header (or throw error message). I don't see why you are even trying to use the multi-boot "standard" if you're doing something non-standards compliant, it goes around the entire reason to have a standard. I do not use the multi-boot standard for my OS because it's not easily extended for future hardware.

Re: Multiboot question

Posted: Thu Feb 05, 2009 10:23 pm
by Brendan
Hi,
neon wrote:Do you think it is fine for a multiboot compliant boot loader to pass additional data to the loaded module/kernel for specific types of kernels? Just curious what others think :)
What sort of information?

If it's something that can be provided when the OS is installed then load it as a module (e.g. some sort of boot script). If it's something that needs to be detected during boot then you could either extend the multi-boot information structure to include it (and have compatibility problems), or do what I always do - switch back to real mode as soon as your code is running so you can do things properly (with no compatibility problems).

If you do plan on extending GRUB and/or the multi-boot specification, remember that "GRUB legacy" has been mostly frozen by the official developers (AFAIK they want everyone to shift to "GRUB 2" one day). Because of this you could end up forking GRUB (or perhaps waiting several more years for "GRUB 2" to be canceled due to lack of progress)... ;)


Cheers,

Brendan

Re: Multiboot question

Posted: Thu Feb 05, 2009 11:40 pm
by neon
Brendan wrote:or do what I always do - switch back to real mode as soon as your code is running so you can do things properly (with no compatibility problems).
That was my original problem, actually. Basically there was no nice way for me to return to real mode because my systems image base is at 64k. Entering rmode limits CS to 0xffff (1 byte less then 64K) so a gpf would occur. I was originally thinking of passing my bootloaders rmode<>pmode routine (bad, I know.)

While my compiler does not allow me to rebase the image less then 64K, I have came up with a nice solution: I took my bootloaders relocate() routine and, upon entry of the program, the program will relocate itself to 0x1000 and continue execution from there which creates a nice environment for real mode code.

Re: Multiboot question

Posted: Fri Feb 06, 2009 1:27 am
by Brendan
Hi,
neon wrote:
Brendan wrote:or do what I always do - switch back to real mode as soon as your code is running so you can do things properly (with no compatibility problems).
That was my original problem, actually. Basically there was no nice way for me to return to real mode because my systems image base is at 64k.
I'd assume you'd be able to change your code so that your image base isn't at 64 KiB...
neon wrote:Entering rmode limits CS to 0xffff (1 byte less then 64K) so a gpf would occur. I was originally thinking of passing my bootloaders rmode<>pmode routine (bad, I know.)
No. In real mode, if CS is set to 0xFFFF then you'd be able to access from 0xFFFF:0x0000 to 0xFFFF:0xFFFF without getting a general protection fault because the offset is always below the segment limit. This works out to physical addresses 0x000FFFF0 to 0x0010FFEF.

I'm currently using "CS:IP = 0xFFFF:0x0010" where my code is mostly all 16-bit, and a separate piece of code (which switches to protected mode eventually) is loaded as a module. My code is a little different though - there's native boot loaders (floppy, CD, PXE/network) that all load certain files into memory and start a "common PC-BIOS" module (while in real mode), and then there's the GRUB thing which needs to emulate the native boot loaders.
neon wrote:While my compiler does not allow me to rebase the image less then 64K, I have came up with a nice solution: I took my bootloaders relocate() routine and, upon entry of the program, the program will relocate itself to 0x1000 and continue execution from there which creates a nice environment for real mode code.
The problem here is that you don't know what you're overwriting at 0x1000 (for e.g. you could be trashing the multi-boot information structure).

IMHO actually relocating the code shouldn't be necessary - it's usually enough to use the segment register's base address instead. For example, set CS/DS/ES/SS to 0xFFFF in real mode, and create GDT entries with "base = 0x000FFFF0" for protected mode. The only hassle here is that you'd need to convert physical addresses. For example, the video card's display memory might be at 0x000A0000, and you'd need to do "video_address = (0x000A0000) - 0x000FFFF0" (using 32-bit unsigned arithmetic) to convert it into an address suitable for your segment registers (so that 0x000A0000 becomes "DS:0xFFFA0010").

Of course you could do the same without changing your image base - use CS/DS/ES/SS = 0xFF00 (where the real mode address "0xFF00:0x1000" is the physical address "0x00100000") and then create GDT entries with "base = 0x000FF000".


Cheers,

Brendan

Re: Multiboot question

Posted: Fri Feb 06, 2009 8:18 am
by neon
No. In real mode, if CS is set to 0xFFFF then you'd be able to access from 0xFFFF:0x0000 to 0xFFFF:0xFFFF without getting a general protection fault because the offset is always below the segment limit. This works out to physical addresses 0x000FFFF0 to 0x0010FFEF.
Thats what I thought. Except its Bochs that is causing the gpf for that reason (cs:eip > limit) which is set to 0xffff whenever I enter real mode regardless of how my gdt entry flags are set up.
Of course you could do the same without changing your image base - use CS/DS/ES/SS = 0xFF00 (where the real mode address "0xFF00:0x1000" is the physical address "0x00100000") and then create GDT entries with "base = 0x000FF000".
...Although I have not tried that. Im going to give that a try when I get back from work and see what happens.

Thanks for your suggestions :)

Re: Multiboot question

Posted: Fri Feb 06, 2009 12:47 pm
by Ready4Dis
May want to check if A20 is enabled or disabled, it will behave differently depending. If it's disabled, it will wrap around, if it's enabled, it will not wrap around, may just be a bochs warning saying that it's being wrapped since A20 wasn't enabled.

Re: Multiboot question

Posted: Fri Feb 06, 2009 2:34 pm
by neon
A20 is enabled in the bootloader.

Nontheless, thanks to Brendan, I think I know where the problem is at. Ill post back if it works or not :)

Re: Multiboot question

Posted: Fri Feb 06, 2009 9:01 pm
by neon
I got it working :) I am now jumping to 0x1000:.rmode - 0x10000, where 0x10000 is the image base (64k), and .rmode is the linear address of the beginning of the real mode code. 0x1000:.rmode - 0x10000 == .rmode linear address.

Granted, I still have to finish the function but at least this problem is fixed :)

Thanks for your help :D