familiar question about "unsupported executable format&

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
HenryR
Posts: 2
Joined: Tue Apr 24, 2007 3:10 pm

familiar question about "unsupported executable format&

Post by HenryR »

Hi -

I have been following a simple tutorial and have my kernel up and booting under bochs. I ran into the usual trouble with having read only data, where the install image seems to get hosed and Grub refuses to load it, and changed the link script as suggested on the web, with successful results.

However, I'm now running into the same error, but it seems to be triggered by too much code getting linked into the kernel. In particular, I have a simple procedure to change the timer phase - if this gets linked in then the kernel becomes an 'unsupported executable format', and mbchk can't find a multiboot header. Pruning other code away fixes the problem temporarily, but obviously this is not a long term fix.

Can someone see what - probably very simple - mistake I'm making with my linking / makefile?

Thanks,

Henry

Code: Select all

 CC=gcc
CFLAGS=-Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions -nostdinc -fno-builtin -I ./include 
DEPS=system.h
OBJ=system.o scrn.o gdt.o idt.o isrs.o irq.o timer.o kbd.o

%.o: %.c $(DEPS)
        $(CC) $(CFLAGS) -c -o $@ $< 

kernel: kernel.asm $(OBJ)
        nasm -f elf -o kernel.o kernel.asm
        ld -T link2.ld -o kernel.bin $(OBJ) kernel.o 
install: kernel.bin
        /sbin/losetup /dev/loop1 floppy.img
        mount -o loop /dev/loop1 floppy
        cp -f kernel.bin floppy/
        umount floppy
        /sbin/losetup -d /dev/loop1

Code: Select all

OUTPUT_FORMAT("elf32-i386")
ENTRY(start)
phys = 0x00100000;
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 = .;
}
With a working kernel:

Code: Select all

[root@miles ~]# mbchk kernel.bin 
kernel.bin: The Multiboot header is found at the offset 8124.
kernel.bin: Page alignment is turned on.
kernel.bin: Memory information is turned on.
kernel.bin: Address fields is turned on.
kernel.bin: header_addr is less than load_addr (0xd4e85350 > 0xebfffff0).
[root@miles ~]# objdump -h kernel.bin 

kernel.bin:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00002000  00100000  00100000  00001000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00001000  00102000  00102000  00003000  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00003860  00103000  00103000  00004000  2**5
                  ALLOC
  3 .comment      0000018f  00000000  00000000  00004000  2**0
                  CONTENTS, READONLY
[root@miles ~]# ls -lart kernel.bin
-rwxr-xr-x 1 root root 20151 Apr 30 15:55 kernel.bin
After including more code, that breaks the kernel

Code: Select all

[root@miles ~]# mbchk kernel.bin 
kernel.bin: No Multiboot header.
[root@miles ~]# objdump -h kernel.bin 

kernel.bin:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00002000  00100000  00100000  00001000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00001000  00102000  00102000  00003000  2**5
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00003860  00103000  00103000  00004000  2**5
                  ALLOC
  3 .comment      0000018f  00000000  00000000  00004000  2**0
                  CONTENTS, READONLY
[root@miles ~]# 
[/b][/list]
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

You need to make sure the multiboot header is in the first 8 kb of the file. The most likely reason it isn't when you add code is simply that the stuff in your kernel that's linked before it is growing.
The method I (and at least several others that I know of) use is to put it in a separate section, and put that section first in the link script.
To do so add something like

Code: Select all

    /* Multiboot Header */
    mb-header : AT(...)  /*** FILL IN AS NEEDED ***/
    {
        /* Multiboot header, must be 4-byte aligned and in first 8k of file. */
        . = ALIGN(4);
        KEEP(*(mb-header)) /* so "ld --gc-sections doesn't remove it" */
    }
as the first section in your linker script, and put

Code: Select all

SECTION mb-header ALIGN=4
before your multiboot header. (And obviously switch the section to the correct one for whatever comes next afterwards)
HenryR
Posts: 2
Joined: Tue Apr 24, 2007 3:10 pm

Post by HenryR »

Brilliant, thanks, that works a charm. I had to play with the link script to get the text segment mapped to the right VMA (a concept I don't quite understand, because if paging is disabled, what does 'virtual' mean in this context?), but everything is working now.

Henry
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

HenryR wrote:I had to play with the link script to get the text segment mapped to the right VMA (a concept I don't quite understand, because if paging is disabled, what does 'virtual' mean in this context?)
It basically means "where the code expects to be at run-time", i.e. the address it is linked for.
LorenzoR
Posts: 3
Joined: Sat May 16, 2009 2:48 pm

Re: familiar question about "unsupported executable format&

Post by LorenzoR »

I am having the same problem.
I don't understand where I have to put

Code: Select all

SECTION mb-header ALIGN=4
Post Reply