Question

I'm trying to write a simple bootloader. So, I switched into Protected Mode, jumped to .code32 and trying to jump to ELF file, linked by ld. ld puts .ELF (7F 45 4C ...) into the begging of the file. Bochs interprets it as jnle .+69 command, so it is not that result, which I was wainting. How can I put entry point in the very beggining of the file?

There is a linker.ld script:

ENTRY (boot)

SECTIONS {
    .boot   ALIGN(0x1000)   :   {   bootstrap.o(.text)   }
    .text   ALIGN(0x1000)   :   {   *(.text)    }
    .rodata ALIGN(0x1000)   :   {   *(.rodata)  }
    .data   ALIGN(0x1000)   :   {   *(.data)    }
    .bss    ALIGN(0x1000)   :   {   *(.bss)     }
}
Was it helpful?

Solution

In order to execute an ELF binary, you must read the data from the file and interpret it accordingly. A description of this can be found in this PDF.

The ELF is a header which contains information about the various sections of the file and how to set them up. After performing all the neccessary steps, you can jump to the entry point, which is also found in that header.

OTHER TIPS

I used to create an ELF file with the main code written in C and compiled with gcc

gcc -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -O0 -c kernel.c

Then another assemble code [init.s] with a well known entry point (first instruction at the very first byte)

[bits 32]
[global start]
[global kbhit]
[global getscan]
[extern main]

start:  call main   ; jump to main() in kernel.c

hang:   hlt     ; halt the cpu
    jmp hang

kbhit:
   in al,0x64
   and al,1
   ret

getscan:
   in al,0x60
   ret

with some "firmware" functions to be used by the C program [kbhit(), getscan(),...] as we don't have access to BIOS in protected mode

Assemble with nasm, also in ELF:

nasm -f elf init.s

Then link both together and store the resulting file in sectors after the MBR in your USB (you MBR should read it from USB, put it in memory, go to protected mode and jumt to the first byte of "kernel.bin")

ld -T kernel.ld -o kernel.bin init.o kernel.o

The order of the object files (.o) is important, put init.o the first one

kernel.ld:

OUTPUT_FORMAT("binary")
ENTRY(start)
SECTIONS
{
  .text  0x100000 : {
    *(.text)
  }
  .data  : {
    *(.data)
  }
  .bss  :
  {                     
    *(.bss)
  }
}

Hope this help

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top