OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 2:32 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 13 posts ] 
Author Message
 Post subject: Using LD to output a flat binary?
PostPosted: Fri Nov 07, 2008 7:56 pm 
Offline
Member
Member
User avatar

Joined: Sun Oct 14, 2007 11:49 am
Posts: 150
Hello, I've been working on a bootloader, and have recently run into trouble getting my linker (LD from binutils-2.16 targeting i386-elf, compiled in Cygwin) to output a flat binary correctly. I've tried various scripts I found while searching google, as well as a few I wrote myself after reading the documentation from the LD manpages; however, in the cases where the script works and produces a binary file, my dispstr() function (similar to puts() ) doesn't work. When I disassemble the binary file it appears that the string pointer passed to the function is an address somewhere above 0x8048000, which is LD's default virtual address (I think). So basically, I'm not sure what exactly is messing up; if anyone's had this problem before, or can offer any advice, it'd be greatly appreciated.


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Fri Nov 07, 2008 9:39 pm 
Offline
Member
Member
User avatar

Joined: Fri Apr 18, 2008 4:40 pm
Posts: 1686
Location: Langley, Vancouver, BC, Canada
Hmm, I'm not sure. You mind posting your most successful script for us so we can check it out?

_________________
Image
Image
Solar wrote:
It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.

I wish I could add more tex


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Fri Nov 07, 2008 9:42 pm 
Offline
Member
Member
User avatar

Joined: Fri Jun 22, 2007 12:47 pm
Posts: 1598
Location: New Hampshire, USA
Below is pretty much the 'defacto' standard for a minimal linker script for flat binaries. It will link everything to 0x10000. In your linkers did you ever include the *(.rodata) placement section? Also, could you give more specifics on what you are using to compile the code with (using just n/f/m/y/tasm/gcc/etc...) and could you post the compilation script/makefile.

Code:
OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00010000;
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 = .;
}

_________________
Website: https://Joscor.com


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Fri Nov 07, 2008 10:11 pm 
Offline
Member
Member
User avatar

Joined: Sun Oct 14, 2007 11:49 am
Posts: 150
Well, the linker script posted worked just as well as the others, so that would be the most successful script; here's my makefile (I'm using MinGW's make tool, if you're wondering about the backwards slashes in the file paths)
Code:
L  = i386-elf-ld
LF = -T link -nostdlib -nostartfiles -nodefaultlibs

A  = nasm
AF = -f bin
AE = -f elf

C  = i386-elf-gcc
CF = --freestanding -fstrength-reduce -fomit-frame-pointer -finline-functions -fno-builtin -nostdlib -nostartfiles -nodefaultlibs -Wall -Werror -O0 -Iinc

all: bin\image.bin

bin\image.bin: bin\boot.bin
   imgtool bin\image.bin bin\boot.bin image 1440k
bin\boot.bin: bin\aboot.bin bin\cboot.bin
   copy /b bin\aboot.bin + bin\cboot.bin bin\boot.bin
   
bin\aboot.bin: boot.asm
   $(A) $(AF) -o bin\aboot.bin boot.asm
   
bin\cboot.bin: bin\stub.o bin\boot.o
   $(L) $(LF) -o bin\cboot.bin bin\stub.o bin\boot.o
bin\stub.o: stub.asm
   $(A) $(AE) -o bin\stub.o stub.asm
bin\boot.o: boot.c
   $(C) $(CF) -o bin\boot.o boot.c

You know, I'm actually not sure what every one of those GCC flags does; if any are redundant or possibly problematic, let me know and I'll rebuild everything without them and see if that fixes it.

EDIT: In case you're wondering, imgtool is a utility I wrote to make disk images, and all of this is a single-stage bootloader intended to be loaded from the first few sectors of the disk.

EDIT: I looked up what each of those flags does, and removed all the optimization-related ones, and it's still giving me weird addresses for strings (even when I declare them outside of the main function). I'm thinking it's something to do with .rodata having a weird virtual address, but the linker script posted has no indication of that being done. Still don't know exactly what's messing up.


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Sun Nov 09, 2008 1:52 pm 
Offline
Member
Member

Joined: Tue Oct 14, 2008 1:18 pm
Posts: 65
Location: Scotland
Perhaps it isn't actually using the linker script? Try passing the following to LD:

Code:
-Ttext [address] --oformat binary

_________________
All your base are belong to us.


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Sun Nov 09, 2008 6:05 pm 
Offline
Member
Member
User avatar

Joined: Sun Oct 14, 2007 11:49 am
Posts: 150
Just tried that and had the same result; the code links fine, but string addresses are way off. Also I tried compiling a later version of binutils (2.18) and using it instead made no difference. Maybe it's due to binutils' target (i386-elf); a while ago when I was targeting i386-aout things were working fine (granted, the code was somewhat different, but it was still outputting a flat binary in the same manner).


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Sun Nov 09, 2008 6:51 pm 
Offline
Member
Member

Joined: Tue Sep 23, 2008 1:45 pm
Posts: 158
Location: Eindhoven, Netherlands
Does including a .bss section really have any effect? AFAIK it needs file headers to be correctly initialised, which of course a flat binary lacks. So the effect is the same as if it hadn't been included at all.


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Sun Nov 09, 2008 6:55 pm 
Offline
Member
Member
User avatar

Joined: Sun Oct 14, 2007 11:49 am
Posts: 150
I was under the impression that the linker would just zero out a section of the binary and use that for the uninitialized data; I could be wrong though.


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Sun Nov 09, 2008 6:57 pm 
Offline
Member
Member

Joined: Tue Sep 23, 2008 1:45 pm
Posts: 158
Location: Eindhoven, Netherlands
No, the .bss section is normally initialised with zeroes only when loaded. The idea is that since it's not initialised anyway, there's no point in wasting space in the binary.


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Sun Nov 09, 2008 7:00 pm 
Offline
Member
Member
User avatar

Joined: Sun Oct 14, 2007 11:49 am
Posts: 150
But if space outside of the binary is used for data, and there is no formatting in the binary to tell where this space is, wouldn't that cause undefined behavior due to the fact that there's no way to tell how much memory is being used beyond the end of the actual file?


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Sun Nov 09, 2008 7:24 pm 
Offline
Member
Member

Joined: Tue Sep 23, 2008 1:45 pm
Posts: 158
Location: Eindhoven, Netherlands
That was my point in my first post. ;)


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Sun Nov 09, 2008 7:27 pm 
Offline
Member
Member
User avatar

Joined: Sun Oct 14, 2007 11:49 am
Posts: 150
What I was saying is that it's included in the binary as zeroes because of that. It wouldn't make sense to support flat binary output if such output would have unpredictable results from writing to unspecified memory locations.

EDIT: Could we get back on-topic? As far as I know, strings are in .rodata, not .bss.


Top
 Profile  
 
 Post subject: Re: Using LD to output a flat binary?
PostPosted: Fri Nov 14, 2008 9:04 pm 
Offline
Member
Member
User avatar

Joined: Sun Oct 14, 2007 11:49 am
Posts: 150
Yes, I'm bumping, but i've also got some new information regarding my problem. After simplifying my build setup to just compile one .c file to one .o file, then link that .o file to a flat binary, I ran across this warning:
Code:
/usr/cross/lib/gcc/i386-elf/4.2.0/../../../../i386-elf/bin/ld: warning: cannot find entry symbol _start; defaulting to 08048054

Now in the LD man page, it specifies that if start or _start aren't found, and no other start address is specified, the start address defaults to 0, so I'm not sure why it's doing this. What makes this interesting is that this start address is very close to my strange string addresses; it's almost as if whether I specify a start address or not, it silently sets it to 08048054 and links everything to that address. Does anyone know of what might be causing this problem, or how to fix it?


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: FAST WebCrawler [Crawler], Google [Bot] and 88 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