Flat binary + ELF

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Flat binary + ELF

Post by Mikae »

Hello all!

I have a raw file, which contents some instructions. Also I have a C file, which contains some functions. My output should be a raw binary file. I use FASM to assemble the .asm file and GCC to compile the .c file. But how I can combine my .c and .asm files together? I wanted to call some (or at least one) functions from the .asm file, while functions are placed into the .c file. Which way is the best in this case? Since my .asm file is 16bit so I can't assemble it into ELF file and the link it with .c file using LD with --oformat=binary option. Any ideas?

TIA, Mikae
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

let the assembler output something else than binary format, i.e. ELF (linux, crosscompiler) or COFF (windows)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Post by Mikae »

No, finally I want flat binary format, since my FAT loader supports only flats :). I think I solved 1st problem: combining 'format ELF' and 'use16' I forced FASM to create ELF object file containing 16 bit code. But I've got a new one: now I have 2 files: .asm, which switchs CPU to PM, prepares sregs and so on and .c file, which contains some routines. So, object file, compiled from .asm should be at the beginning of the final flat file. But LD puts .c file as the beginning and .asm at the end. A question is, how I can to force LD to put .asm file at the beginning of my final flat?..
User avatar
JoeKayzA
Member
Member
Posts: 79
Joined: Wed Aug 24, 2005 11:00 pm
Location: Graz/Austria

Post by JoeKayzA »

You could either use objcopy to rename the sections within your asm object file, then adjust the linker script so that the renamed sections are put at the beginning of the output binary.

You could also adjust the linker script in a way that it puts the first object file at the beginning by hardcoding its name into the script, I can remember some examples on this forum a while ago.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Mikae wrote:So, object file, compiled from .asm should be at the beginning of the final flat file.
Erm... why?

I mean, you control (in your bootsector) where you jump at. You don't necessarily have to jump at offset 0... but I see your issue. I'm not a linker wizard, but doesn't 'ld' link objects in the order they appear on the command line?

I also have some voice in the back of my head nagging me to ask you: Is your C object file also 16 bit, or 32 bit? If it's 32 bit, are you calling its functions from your 16bit ASM code?
Every good solution is obvious once you've found it.
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Post by Mikae »

Erm... why?
Layout of my 1st file should be as follows:

.asm:
16 bit
1. Some routines to prepare GDT/IDT.
2. Switch to PM and jump to 32bit code.
32bit
1. Initialize segment registers.
2. Call a function in a .c file.

.c: Some 32bit routines to continue.

Since boot loader jumps to the beginning of loaded file, .asm file containing PM-switch should be the first.
I'm not a linker wizard, but doesn't 'ld' link objects in the order they appear on the command line?
It is a pitty, but it doesn't. I tried different orders in command line, and then executed 'diff' command to compare. Nothing changed. Also I tried the following linker script:

Code: Select all

STARTUP(pm.o)
SECTIONS
{
     . = 0x10000
     .text : { pm.o(.text) console.o(.text) }
     .data : { *(.data) }
     .bss : { *(.bss) }
}
OUTPUT(test)
OUTPUT_FORMAT(binary)
and again .text scetion of 'pm.o' is not at the beginning of 'test' flat file...
I also have some voice in the back of my head nagging me to ask you: Is your C object file also 16 bit, or 32 bit?
.c object file is 32 bit.
If it's 32 bit, are you calling its functions from your 16bit ASM code?
I call 32bit function from 32bit part of my .asm file.

Any ideas?..
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Post by Mikae »

Also I tried the following linker script:

Code: Select all

STARTUP(pm.o)
SECTIONS
{
     . = 0x10000
     .init : { pm.o(.text) }
     .text : { console.o(.text) }
     .data : { *(.data) }
     .bss : { *(.bss) }
}
OUTPUT(test)
OUTPUT_FORMAT(binary) 
but nothing changes :(...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Strange, i just tested with my toolchain and i can force one object file up front by putting it first on the command line.

Could you provide some information about your ld? (binutils version, os info, ./configure output, aliases for ld, etc)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Post by Mikae »

I use FreeBSD 6.0, ld version 2.15 [FreeBSD] 2004-05-23. It was installed with BSD 6.0 by default.
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Post by Mikae »

It is very strange, but I found that ld version 'GNU ld version 2.11.2 20010719 [FreeBSD] (with BFD 2.11.2 20010719 [FreeBSD])' running at FreeBSD 4.6.2 preserves order of object files given at command line, but version 2.15 not. Is it possible to correct it? (ld 2.11.2 is placed at remote server, so it is very uncomfortable to link my files there)...
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

You could just setup a cross-compiler environment... Search the OSDev Wiki :)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

both my 2.15 (cygwin's default) and 2.17 (custom built toolchain) work properly. You might want to build your own binutils as well to brute force fix the problem. You could also try copying your 2.11 build and use that even though its kindof dated.
On another note, have you checked .bashrc and those sort files for options automatically passed to ld (are any linker optimisation enabled).
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

<rant>

"Have you updated to the latest version?"

It can drive you up the walls when you have called the "hot"line, spent half an hour on hold, seeing your phone bill skyrocket, only to have this said to you by a call-center person giving you the distinct impression that he just wants to get rid of you.

But what we are doing here - linking to non-standard targets (like, flat binary or non-Linux ELF) using custom linker scripts - is hardly the most common use of the toolchain, so it is not unheard of that older versions of the toolchain have problems with this.

Usually I am the first to say, "the chance that the bug is in the toolchain is next to nil". But this is meant to say, the current toolchain...

Current Linux distributions use something like binutils 2.16.1 / gcc 3.4.2 for compiling their packages.

binutils 2.17 / gcc 4.1.2 are marked "stable" by upstream.

In OS development, where you have very few dependencies to maintain, and with the easy availability of binutils / gcc source and tutorials how to build them, all I can say is:

"Have you updated to the latest version?"

</rant>
Every good solution is obvious once you've found it.
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Post by Mikae »

Well, I tried the following thing:

Downloaded version 2.17 of binutils, then configured it without options and installed. The result is the same. Also I tried to install version 2.11 but I've got error:

strerror.c:468: error: conflicting types for 'sys_nerr'
/usr/include/stdio.h: error: previous declaration of 'sys_nerr' was here
strerror.c:468: error: conflicting types for 'sys_nerr'
/usr/include/stdio.h: error: previous declaration of 'sys_nerr' was here
***Error code 1

Stop in /tmp/binutils-2.11/libiberty.
***Error code 1

Stop in /tmp/binutils-2.11.

Also I tried a little program, which just prints given arguments in an order which they was typed in. Everything is Ok... Thinking about to change ld to watcom linker :).
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

It looks more like you're compiling and linking with the runtime libraries that are made for the host OS... Make sure that GCC and LD are run properly, because if you don't specify the right commands you're just making another application for your host OS.

GCC uses something like --nostdlib etc... See the wiki.
Post Reply