4

So, I have this assembly file, which I assemble with GNU as and link with GNU ld using a linker script.

Linker script (boot.ld):

INPUT(boot.o)
OUTPUT(boot.out)
ENTRY(boot_start)

SECTIONS {
        . = 0x7c00;
        .text : { *(.text) }
        .data : { *(.data) }
        . = 0x7dfe;
        .boot_end : { *(.boot_end) }
}

As you see I try to make the file exactly 512 bytes as needed for a bootloader by doing . = 0x7cdfe. .boot_end contains the boot signature and thus fills up the remaining two bytes.

I create the bootloader as follows:

m4 boot.S | as -o boot.o
ld -T boot.ld
objcopy -O binary boot.out boot.img

boot.out contains the sections already with absolute addresses and everything seems fine. .boot_end is at 0x7dfe and I expect the holes to be filled with zeros, but no, boot.img is a total of 55 bytes. The, for me, weird thing is that the file does not even contain the boot signature. It's just .text and .data without either .boot_end or the skipped bytes.

How do I move ld to skip those bytes? And where is my boot signature gone?

cadaniluk
  • 15,027
  • 2
  • 39
  • 67
  • What section names did you use for the missing parts and what flags did you set (what do you feed into `as`) ? Whether you use ELF or COFF or whatever object format can also matter. – tofro Oct 06 '16 at 11:42
  • @tofro `.boot_end` is the section I'm missing and I assembled with `as` just like written in my question. I use ELF. – cadaniluk Oct 06 '16 at 12:46
  • And you still didn't say what `.section` flags you give in `as` code. Point is, if no section flags are given to `as` in ELF for a non-standard (not `.text` or `.data` or the like) section name, the section will not be allocated. Try to replace your (presumably) naked `.section boot_end` directive in `as` input with `.section boot_end,"a"` (or more flags, for example to make it executable, depending on what you need) and try again. – tofro Oct 06 '16 at 13:06
  • @tofro Oh, OK, I'll try. – cadaniluk Oct 06 '16 at 13:25
  • @tofro Thanks very much, it did work. I tried with `.section .boot_end "", @progbits` first, but the result was the same. I tried again with `.section .boot_end "a", @progbits`, just for the sake of it, and it worked. The thing is `a` indicates allocatable sections, which `.boot_end` is not. Any thoughts on which flag I could use? And why won't GNU as generate data for custom sections without flags? – cadaniluk Oct 06 '16 at 15:28
  • @tofro Also, I am using `.boot_end` just because I didn't find any other way to place user-defined data at a physical address in the linker script. I want to stay independent of other sections, so I didn't simply place the boot signature in `.data`. Creating a new section and placing it at the end seemed the only viable solution. Is there a simpler, more straightforward way to place data in an executable at a certain location? – cadaniluk Oct 06 '16 at 15:35
  • You can place a boot signature in the linker script with something like `.boot_end : AT(0x7DFE) { SHORT(0xaa55); }` – Michael Petch Oct 06 '16 at 15:48
  • You might mis-understand *allocatable* - That just says "goes into the image" in ELF terminology. That method is allright for placing stuff at specific addresses, so "a" is fine. Actually, it's `objcopy` that was made to exclude non-allocatable sections from the image dump. Why they did that is both beyond my knowledge and my understanding. I'd rather have a flag in a section if you *don't* want it to go into the image (maybe because you only want it to resolve I/O addresses) – tofro Oct 06 '16 at 15:49
  • @MichaelPetch I saw it in your answer and tried it, but it somehow gave a syntax error. I'm going to try it again later, maybe I mistyped something. – cadaniluk Oct 06 '16 at 15:51
  • @tofro Alright, I understand, thanks. Feel free to write an answer and enjoy some additional rep. – cadaniluk Oct 06 '16 at 15:52
  • I removed the answer because of a technical inaccuracy when I first typed it up and then realized it really didn't answer the question. Was better to delete it than keep it around. Although you should still be able to use _SHORT_ to output a 16-bit word to a file. – Michael Petch Oct 06 '16 at 15:53

1 Answers1

3

You are most probably missing a section flag. Point is, if no section flags are given to as when you are later linking to ELF for a non-standard (not .text or .data or the like) section name, the section will not be allocated in the dump (i.e, silently be ignored by objcopy, note that this behaves differently when producing coff files)

Try to replace your (presumably) naked

.section boot_end 

directive in your assembler input file with

.section boot_end,"a" 

(or more flags, for example to make it executable, depending on what you need) and try again.

The "a" flag makes the section allocatable, i.e. tells both ld and objcopy you want it in your binary.

tofro
  • 5,640
  • 14
  • 31