My question is can I just compile my regular 32bit kernel like this (listed below are all compiler/linker options I wish to try), and then compile a seperate kernel file to be my module and load it in grub using
# module (fd0)/kernel64.bin while in grub setup utility?
If this can be done, when I go to jump to my 64 bit code after getting all the data structures in place how would I go about calling that from C code? Or would I have to make a assembly instruction that does jmp 0x200000:start64 ?
Any input is apreciated ^^
Kernel 32 compile options(below this i put the kernel 64 compile options):
CFLAGS=-Wall -O -fstrength-reduce -finline-functions -nostdinc -fno-builtin -m32 --no-warn -I./
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata*)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}
KERNEL 64 Compile options ? :(since long mode uses PSE and 2MB pages i figure loading the kernel at 2mb would be a good idea)
CFLAGS=-Wall -O -fstrength-reduce -finline-functions -nostdinc -fno-builtin -m64 --no-warn -I./
OUTPUT_FORMAT("elf64-x86_64")
ENTRY(start64)
phys = 0x00200000;
SECTIONS
{
.text phys : AT(phys) {
code = .;
*(.text)
*(.rodata*)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{
data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{
bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .;
}
Grub amd64 load moudle question.
-
- Posts: 13
- Joined: Sat Apr 28, 2007 1:57 am
Hello,
Grub can load into memory any kind of module. However, that does not mean that it can actually read/execute it. It will be the job of your 32-bit kernel to read (and then execute) the 64-bit module from the memory address Grub has loaded it. In addition to the above, your kernel should also set up long mode, before loading the 64-bit module, which implies that paging should also be enabled.
I was thinking of doing the same thing to load a 64-bit kernel by Grub. However, it is not as trivial as you may think. I propose you use the patch at http://savannah.gnu.org/bugs/?17963 to load directly a 64-bit kernel. I have used it and it works fine. It will save you a whole lot of trouble.
Grub can load into memory any kind of module. However, that does not mean that it can actually read/execute it. It will be the job of your 32-bit kernel to read (and then execute) the 64-bit module from the memory address Grub has loaded it. In addition to the above, your kernel should also set up long mode, before loading the 64-bit module, which implies that paging should also be enabled.
I was thinking of doing the same thing to load a 64-bit kernel by Grub. However, it is not as trivial as you may think. I propose you use the patch at http://savannah.gnu.org/bugs/?17963 to load directly a 64-bit kernel. I have used it and it works fine. It will save you a whole lot of trouble.
What memory address GRUB loads the module at?
What memory address GRUB loads the module at? How does it inform the loaded kernel about the address? Does it load the module at fixed address, which would eliminate having to inform the memory location to kernel?
I searched for this information but could not find it anywere. Thanks for the help in advance.
Saurabh
I searched for this information but could not find it anywere. Thanks for the help in advance.
Saurabh
I think I found it
I think I found the answer. The multiboot_info structure has a member mods_addr and this structure is passed to the kernel as shown in the "simple-kernel" code available on web. I believe the mods_addr tells the kernel the memory address where GRUB has loaded the module.
Did I get it right?
Saurabh
Did I get it right?
Saurabh
Sorry I have not responded in a while.
I tried that grub bootloader patch and it failed miserably.
I decided to stay way from making a 64bit kernel as setting up the development environment and bootloader was such a pain. I could not get the GCC x86_64-elf to work properly ill wait a few gcc versions and hope they fix it.
I have been learning a good deal just sticking to x86_32.
Thanks for taking time though to post 13postures.
saurabhg:
This is way easier than relying on the multiboot.
I added linker script symbols for start and end which has helped alot
. = 0x100000;
kernel_start = .;
...
kernel_end=.
Im sure you can figure out where they fit in :p
Anyhow once you add thoose you will be able to extern u32 kernel_start; and then access it like that. To figure kernel size do not add and subtract the variables themselfs, but instead the addresses of them &kernel_start - &kernel_end. There should be a thread on this already but I do not feel like looking for it.
I tried that grub bootloader patch and it failed miserably.
I decided to stay way from making a 64bit kernel as setting up the development environment and bootloader was such a pain. I could not get the GCC x86_64-elf to work properly ill wait a few gcc versions and hope they fix it.
I have been learning a good deal just sticking to x86_32.
Thanks for taking time though to post 13postures.
saurabhg:
This is way easier than relying on the multiboot.
I added linker script symbols for start and end which has helped alot
. = 0x100000;
kernel_start = .;
...
kernel_end=.
Im sure you can figure out where they fit in :p
Anyhow once you add thoose you will be able to extern u32 kernel_start; and then access it like that. To figure kernel size do not add and subtract the variables themselfs, but instead the addresses of them &kernel_start - &kernel_end. There should be a thread on this already but I do not feel like looking for it.