c - Unrecognised emulation mode: elf_i386 on MinGW32 -
i'm trying make kernel, , cannot link c output assembly. ld
. i'm getting error:
unrecognized emulation mode: elf_i386
i'm using windows 10 professional mingw32 , msys. code using:
link.ld
/* * link.ld */ output_format(elf32-i386) entry(start) sections { . = 0x100000; .text : { *(.text) } .data : { *(.data) } .bss : { *(.bss) } }
kernel.c
/* * kernel.c */ void kmain(void) { const char *str = "my first kernel"; char *vidptr = (char*)0xb8000; //video mem begins here. unsigned int = 0; unsigned int j = 0; /* loops clears screen * there 25 lines each of 80 columns; each element takes 2 bytes */ while(j < 80 * 25 * 2) { /* blank character */ vidptr[j] = ' '; /* attribute-byte - light grey on black screen */ vidptr[j+1] = 0x07; j = j + 2; } j = 0; /* loop writes string video memory */ while(str[j] != '\0') { /* character's ascii */ vidptr[i] = str[j]; /* attribute-byte: give character black bg , light grey fg */ vidptr[i+1] = 0x07; ++j; = + 2; } return; }
kernel.asm
;;kernel.asm bits 32 ;nasm directive - 32 bit section .text global start extern kmain ;kmain defined in c file start: cli ;block interrupts mov esp, stack_space ;set stack pointer call kmain hlt ;halt cpu section .bss resb 8192 ;8kb stack stack_space:
to compile , link use:
nasm -f elf32 kernel.asm -o kasm.o gcc -m32 -c kernel.c -o kc.o ld -m elf_i386 -t link.ld -o kernel kasm.o kc.o
i'm using:
- gcc 4.8.1
- ld 2.25.1
- nasm 2.11.09rc1
why getting error, , how can fix it?
the standard mingw/32 ld linker doesn't output elf binaries. preferably using i686 cross-compiler, if you're not may able away tips below.
it appears using arjun's let's write kernel tutorial. if following tutorial have missed step make kernel.asm
compatible grub boot loader , qemu's -kernel
option. before start should read rest of tutorial. following code adds multiboot header kernel.asm
make grub compatible:
;;kernel.asm bits 32 ;nasm directive - 32 bit global entry extern _kmain ;kmain defined in c file section .text entry: jmp start ;multiboot spec align 4 dd 0x1badb002 ;magic dd 0x00 ;flags dd -(0x1badb002 + 0x00) ;checksum. m+f+c should 0 start: cli ;block interrupts mov esp, stack_space ;set stack pointer call _kmain hlt ;halt cpu section .bss resb 8192 ;8kb stack stack_space:
besides adding header i've put entry
label in file , jmp start
jump on multiboot header. i've done make easy set breakpoint @ 0x100000 in future if start debugging.
one other change on mingw, gcc adds underscore function names default. i've changed references c function kmain
_kmain
. differs linux convention.
since entry point of our code entry
instead of start
i've modified link.ld
be:
/* * link.ld */ output_format(pei-i386) entry(entry) sections { . = 0x100000; .text : { *(.text) } .data : { *(.data) } .bss : { *(.bss) } }
another important change in file above usage of output_format(pei-i386)
. output portable executable image (32-bit) rather elf (which isn't supported).
in order build kernel , produce elf image pei-i386 can use these commands:
nasm -f elf32 kernel.asm -o kasm.o gcc -m32 -c kernel.c -o kc.o -ffreestanding -nostdlib -nostdinc ld -t link.ld -o kernel kasm.o kc.o -build-id=none objcopy -o elf32-i386 kernel kernel.elf
the ld command has been modified not write out build-id executable avoid multiboot header being shifted outside first 8k of executable. gcc options have been modified produce freestanding code (without standard library , includes) using options -ffreestanding -nostdlib -nostdinc
. use objcopy
convert pei-i386 file (kernel
) elf32 image called kernel.elf
. want using kernel.elf
grub and/or qemu.
Comments
Post a Comment