Page 1 of 1

Two compile/link formats in the same file?

Posted: Mon Mar 05, 2012 3:59 pm
by rubymonk
Hello, I would like understand something please.

I'm thinking about writing a kernel in 64 bits.
This would be loaded by a multiboot1-header (grub 0.97)

What I don't get is: I need to have the header part compiled 32 bits.
An other part, after long mode has been enabled has to be compiled using 64 bits.

How should I do this to have it all in the same file?
Is it ever possible to compile a same executable in 2 different formats?

I certainly miss a piece somewhere.
Thank you.

Re: Two compile/link formats in the same file?

Posted: Mon Mar 05, 2012 4:14 pm
by xenos
You could write the 32 bit part of your kernel in assembly (there's really not much to do before you can jump into 64 bit mode). The only thing you need to do is prefix your 32 bit code with a .code32 directive. This is what it looks like in my kernel startup file:

http://xenos.svn.sourceforge.net/viewvc ... iew=markup

You can also include a multiboot header in some assembly file, or even use the linker script to create one, like this:

http://xenos.svn.sourceforge.net/viewvc ... iew=markup

Re: Two compile/link formats in the same file?

Posted: Mon Mar 05, 2012 4:41 pm
by rubymonk
XenOS wrote:You could write the 32 bit part of your kernel in assembly
Thanks for this answer.
True, but my 32 bits code as to have an output format compatible with the rest of the code, no?

I shall compile my assembly code (I use nasm) -felf64 to be able to link it with the rest of the kernel.

By the way, how will I ensure this piece of code will be at the begining of the file just by presenting it first in the command line calling ld?

Thank you.

Re: Two compile/link formats in the same file?

Posted: Mon Mar 05, 2012 5:55 pm
by Velko
rubymonk wrote:By the way, how will I ensure this piece of code will be at the begining of the file just by presenting it first in the command line calling ld?
Either that, or you could put different code in different sections and use linker script to ensure correct order.

Relevant part from my linker script:

Code: Select all

OUTPUT_FORMAT("elf64-x86-64")
ENTRY(boot_start32)
virt_start = 0xffff800000000000;
load_start = 0x00100000;
SECTIONS
{
    . = load_start;
    .lowtext load_start : AT(load_start)
    {
        *(.mb_header)
        *(.lowtext32*)
        *(.lowtext64*)
    }
    . = . + virt_start;
    .text : AT(code_start - virt_start)
    {
        code_start = .;
        *(.text*)
    }
-------- snip ------
I hope that section names are self-explanatory :D