Multiboot Kernel
Multiboot Kernel
This is my first attempt at a kernel in C, before I used ASM for a long time (and used it for OS dev). I moved on to C last year and it was time to try a kernel in it
I've followed the 'basickernel.pdf' from osdever.net and Tim Robinson's documents about C kernels.
I'm using a native GNU/Linux environment to build my kernel.
When trying to boot my kernel with GRUB; it says: "Invalid or unsupported executable format".
I've ran objdump against all object files and against the final executable, they are all in the ELF format. So, the AOUT kludge should not be needed (according to what I've read when searching for a solution at this forum).
Also, GRUB's "mbchk" tool says all test passed and that the multiboot header was found at offset 4096 in the final executable.
In the attachments I'm including the output of 'objdump -x'. If anyone needs more information regarding the problem or wants to view source codes, please ask.
EDIT: "mbchk" says "Address fields is turned off." (I'm using ELF though)
I've followed the 'basickernel.pdf' from osdever.net and Tim Robinson's documents about C kernels.
I'm using a native GNU/Linux environment to build my kernel.
When trying to boot my kernel with GRUB; it says: "Invalid or unsupported executable format".
I've ran objdump against all object files and against the final executable, they are all in the ELF format. So, the AOUT kludge should not be needed (according to what I've read when searching for a solution at this forum).
Also, GRUB's "mbchk" tool says all test passed and that the multiboot header was found at offset 4096 in the final executable.
In the attachments I'm including the output of 'objdump -x'. If anyone needs more information regarding the problem or wants to view source codes, please ask.
EDIT: "mbchk" says "Address fields is turned off." (I'm using ELF though)
- Attachments
-
- log.txt
- Output of 'objdump -x' ran on all object files and the final executable.
- (5.68 KiB) Downloaded 93 times
Not sure but it I copied it pretty much from tutorials so it should be fine. Do you want to see my linker script?Pyrofan1 wrote:Are you sure you're linking it properly?
How can I change this? In the linker script? In my multiboot stub?mystran wrote:Your trying to load at address zero. GRUB won't allow that. Load to 1MB instead.
In linker script. Here's the script I use:bughunter wrote:Not sure but it I copied it pretty much from tutorials so it should be fine. Do you want to see my linker script?Pyrofan1 wrote:Are you sure you're linking it properly?
How can I change this? In the linker script? In my multiboot stub?mystran wrote:Your trying to load at address zero. GRUB won't allow that. Load to 1MB instead.
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
load_address = 0x100000; /* at 1M */
SECTIONS
{
. = load_address;
.text :
{
*(.multiboot.header) /* must be within 8k, so put first */
*(.text)
*(.rodata*)
}
.data : {
data = .;
*(.data)
}
.bss : {
bss = .;
*(.bss)
*(COMMON)
}
_kernel_end = .;
}
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
Better for youbughunter wrote: Do you want to see my linker script?
something like that :bughunter wrote: How can I change this? In the linker script? In my multiboot stub?
Code: Select all
OUTPUT_FORMAT("elf32-i386")
ENTRY(entry)
virt = 0xC0000000; /* 3 GB */
phys = 0x100000; /* 1 MB */
SECTIONS
{ .text virt : AT(phys)
{ code = .;
*(.text)
. = ALIGN(4096);
}
.data : AT(phys + (data - code))
{ data = .;
*(.data)
. = ALIGN(4096);
}
.bss : AT(phys + (bss - code))
{ bss = .;
*(.bss)
*(COMMON)
. = ALIGN(4096);
}
end = .;
}
Code: Select all
ENTRY (start)
SECTIONS
{
. = 0x00100000;
.text :
{
*(.text)
}
.rodata ALIGN (0x1000) :
{
*(.rodata)
}
.data ALIGN (0x1000) :
{
*(.data)
}
.bss :
{
_sbss = .;
*(COMMON)
*(.bss)
_ebss = .;
}
}
Systems and Computer Engineering Researcher
"Do you pine for the nice days of Minix-1.1, when men were men and wrote their own device drivers?" -- Linus Torvalds
http://sce.carleton.ca/~maslan
"Do you pine for the nice days of Minix-1.1, when men were men and wrote their own device drivers?" -- Linus Torvalds
http://sce.carleton.ca/~maslan
I have absolutely no idea about Nasm. I've never even had it installed on any system I've had.. but in Gas you'd do it like this:
Look at NASM documentation. I would guess it can't be too different.
Code: Select all
.section .multiboot.header
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
Yeah I was already thinking about porting it to GAS, this encourages me to do so, as I also don't like to rely on the order of specifying files on the command line.
Anyways, I figured out my error. I was building on one system, and then transferring the files by FTP to another machine. You might already know what's wrong... I wasn't setting the transfer type to binary (I used Linux' console FTP program). It now works!
Another question though:
I've also setup a Cygwin environment on my XP box, and when building my kernel with Cygwin (using a cross compiler targeted for i586-elf) the output is about 6kB. But when compiling it under native Linux (slackware + GCC 3.4.2 is what I used) the final output is about 10kB. Does anybody have an idea why this happens?
EDIT: The Cygwin GCC cross compiler version is 4.1.2
Anyways, I figured out my error. I was building on one system, and then transferring the files by FTP to another machine. You might already know what's wrong... I wasn't setting the transfer type to binary (I used Linux' console FTP program). It now works!
Another question though:
I've also setup a Cygwin environment on my XP box, and when building my kernel with Cygwin (using a cross compiler targeted for i586-elf) the output is about 6kB. But when compiling it under native Linux (slackware + GCC 3.4.2 is what I used) the final output is about 10kB. Does anybody have an idea why this happens?
EDIT: The Cygwin GCC cross compiler version is 4.1.2
It's easy in NASM too. My multiboot header starts with:bughunter wrote:Yeah I was already thinking about porting it to GAS, this encourages me to do so, as I also don't like to rely on the order of specifying files on the command line.
Code: Select all
SECTION mb-header ALIGN=4
The 4.1.2 series GCC supposedly has much better optimizer, so maybe it can generate smaller code? The other possibility is that your native Linux compiler includes more symbols or something.. you could try playing with strip and see if it can bring the filesize down. Not that it should matter.bughunter wrote: Another question though:
I've also setup a Cygwin environment on my XP box, and when building my kernel with Cygwin (using a cross compiler targeted for i586-elf) the output is about 6kB. But when compiling it under native Linux (slackware + GCC 3.4.2 is what I used) the final output is about 10kB. Does anybody have an idea why this happens?
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
Thanks, but I already ported it to GAS now I also liked GAS because then everyone with the binutils can assemble it.urxae wrote: It's easy in NASM too. My multiboot header starts with:I use a different section name, but the principle is the same. (The ALIGN=4 may not be needed, but I added it to be safe. It may be ELF-specific though)Code: Select all
SECTION mb-header ALIGN=4
I don't think it should make _that_ much difference, as the test kernel I started with in C is just one or two functions. And I used '-s' already while compiling, but I'll try strip. Posting results here shortly.mystran wrote: The 4.1.2 series GCC supposedly has much better optimizer, so maybe it can generate smaller code? The other possibility is that your native Linux compiler includes more symbols or something.. you could try playing with strip and see if it can bring the filesize down. Not that it should matter.
EDIT: On Cygwin, using 'strip -s' on the compiled kernel resulted in 4688 bytes. On Slackware Linux it resulted in a kernel of 8648 bytes. Hmm? Big difference
Don't bother. Extra 4k for the kernel size hardly matters, especially as it's only the disk-size, not the final loaded size (assuming Candy is correct). Plus if you really care about disk-size, then you can gzip the resulting binary (Grub loads those as well) at which point the difference probably reduces to insignificance.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.