OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 23, 2024 6:44 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: How to link 32- and 64-bit code together?
PostPosted: Wed Mar 18, 2020 7:47 am 
Offline

Joined: Wed Mar 18, 2020 7:23 am
Posts: 4
So, I'm compiling my 32-bit bootstrap code with the following commands:
Code:
i686-elf-gcc -c $(C_FILE) -o $(O_FILE) -std=gnu99 -ffreestanding -O2 -Wall -Wextra -DKERNEL_MODE=64 #for C source files
i686-elf-gcc $(S_FILE) -o $(O_FILE) -ffreestanding -nostdlib -r -DKERNEL_MODE=64 #for .S assembly files
i686-elf-as $(S_FILE) -o $(O_FILE) #for .s assembly files
i686-elf-gcc -T boot32.ld -o boot32.o -ffreestanding -O2 -nostdlib -r $(OBJ32) -lgcc


Then compiling my 64-bit kernel with:
Code:
x86_64-elf-gcc -c $(C_FILE) -o $(O_FILE) -std=gnu99 -ffreestanding -O2 -Wall -Wextra -DKERNEL_MODE=64 #for C source files
x86_64-elf-gcc $(S_FILE) -o $(O_FILE) -ffreestanding -nostdlib -r -DKERNEL_MODE=64 #for .S assembly files
x86_64-elf-objcopy -O elf64-x86-64 -B i386 -I binary $(BINARY_DATA) $(BINARY_OBJECT) #for binary data


Finally, I link everything with:
Code:
x86_64-elf-gcc -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib boot32.o $(OBJ64) -lgcc


At which point I get an error message:
Code:
[...]x86_64-elf/bin/ld: i386 architecture of input file `boot32.o' is incompatible with i386:x86-64 output


And then, a couple undefined references in boot32.o to symbols defined in the 64-bit code. Now, what is the best way to link this together? I know I could manually parse the 64-bit symbol table, or even use objcopy somehow to move the 64-bit sections into the 32-bit object file by hand, with the two exported symbols at defined addresses. But this looks extremely ugly to do, and I think I'm missing something about 32- and 64-bit executable formats.

Also, I'm using Multiboot, so the bootstrap code *must* be 32-bit, and the entire image loadable by the bootloader.


Top
 Profile  
 
 Post subject: Re: How to link 32- and 64-bit code together?
PostPosted: Thu Mar 19, 2020 1:13 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
Compile everything as 64 bit. Link as 64 bit too. In your .S files add .code32 directive in places where you have 32 bit code and .code64 where you have 64 bit code (I am not very familiar with GNU assembler, but I think, this is how you do it). There is even .code16 directive if you need it. Loader file can be either raw binary, 32 bit ELF or 64 bit ELF. QEMU's built-in loader can't load 64 bit ELF files (not without a patch), but GRUB can. You will still start in 32 bit mode, but ELF file itself can be 64 bit.
Try lower half kernel first, since high half one needs some extra linker script tweaks and compiler flags.


Top
 Profile  
 
 Post subject: Re: How to link 32- and 64-bit code together?
PostPosted: Thu Mar 19, 2020 4:19 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4594
Location: Chichester, UK
Have a look at this wiki article, but be sure to read the linked material too: https://wiki.osdev.org/Creating_a_64-bit_kernel

I use Grub to start a 32-bit "kernel" which then jumps to a 64-bit module, as described in the article. Some information needs to be passed to the 64-bit code; I do this in a structure located at a fixed address (which can be overwritten once the data has been transferred).


Top
 Profile  
 
 Post subject: Re: How to link 32- and 64-bit code together?
PostPosted: Thu Mar 19, 2020 8:06 am 
Offline

Joined: Wed Mar 18, 2020 7:23 am
Posts: 4
I think I've come up with a solution:

Code:
x86_64-elf-objcopy -O elf32-x86-64 -I elf32-i386 boot32.o boot32.o
x86_64-elf-objcopy -O elf32-x86-64 -I elf64-x86-64 kernel.o kernel.o
x86_64-elf-gcc -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib boot32.o kernel.o -Xlinker -m -Xlinker elf32_x86_64
x86_64-elf-objcopy -O elf32-i386 -I elf32-x86-64 myos.bin myos.bin


It links everything together and emits no errors. All symbols are linked properly and have the right addresses as far as I've tested. I still haven't managed to get the 64-bit code to run though...


Top
 Profile  
 
 Post subject: Re: How to link 32- and 64-bit code together?
PostPosted: Thu Mar 19, 2020 10:22 am 
Offline

Joined: Wed Mar 18, 2020 7:23 am
Posts: 4
Okay, now it works perfectly. Does anybody want me to put this in the wiki? I mean, the solution wasn't really that obvious, it would be useful to have it in "Creating a 64-bit kernel" in case somebody wants to code (parts of) their 32-bit bootstrap in C and not just use assembly and ".code32" or have to write a dedicated loader.


Top
 Profile  
 
 Post subject: Re: How to link 32- and 64-bit code together?
PostPosted: Thu Mar 19, 2020 10:52 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
Correct me if I am wrong, but I think this method may be a little bit problematic for high half kernels and address spans larger that 4GiB. I mean, 32 bit ELF expects 32 bit addresses. Some relocation types may be impossible if you use 64 bit addresses in 32 bit ELF.


Top
 Profile  
 
 Post subject: Re: How to link 32- and 64-bit code together?
PostPosted: Fri Mar 20, 2020 5:34 am 
Offline

Joined: Wed Mar 18, 2020 7:23 am
Posts: 4
Don't worry, my original idea was to put my kernel in the first 4 GiB so addresses were the same in 32 and 64 bit modes. In fact, I'll possibly make a lower half kernel. I know it's a bad idea, but I think I know what I'm doing. Well, if someone finds out how to link this better, please tell me :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], SemrushBot [Bot] and 114 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group