Search code examples
cwindowsassemblygccelf

Compiling C to ELF32 on Windows


I am trying to compile a C program to ELF format on Windows, so I tried to do several things:

  1. Compiled with MinGW gcc -Wall -c test.c -o test.o, but got no test.o as an output
  2. Downloaded https://github.com/nativeos/i386-elf-toolchain/releases (the 32 bit version), and compiled with "[...]/i386-elf-gcc" -c test.c -o test.o, but I got the error i386-elf-gcc/libexec/gcc/i386-elf/5.2.0/cc1.exe: error while loading shared libraries: ?: cannot open shared object file: No such file or directory

What I'm trying to do is to follow this tutorial here: https://github.com/cfenollosa/os-tutorial, but I'm stuck on the part of making the actual link between Assembly and C. I'm well aware of the fact that this tutorial is made for Linux, not Windows, but I just... Let's just say I'm having trouble using Linux.

I don't know what files are needed to resolve my issue, so here's:

  1. kernel.c
void my_function() {
}

int main() {
    return 0;
}
  1. kernel_entry.asm
[bits 32]
[extern main]
call main
jmp $
  1. boot.asm
[org 0x7c00]

kernel_offset equ 0x1000

    mov [bootDrive], dl

    mov bp, 0x9000
    mov sp, bp

    call switch_to_pm

    call BEGIN_PM

    jmp $

%include "gdt_init.asm"
%include "switch_32.asm"

bootDrive db 0

[bits 32]
BEGIN_PM:
    call clear_screen
    call kernel_offset

    mov ebx, errorMSG
    call print_string_pm

    jmp $

%include "io/clear.asm"
%include "io/print.asm"


errorMSG db "Something went terribly wrong. Restart the PC to fix it", 0

; bootsector
times 510-($-$$) db 0
dw 0xaa55

The other files are a near copy-paste, so I didn't think it is necessary to include them


Solution

  • So, it's a little complicated, so buckle up.

    First, I've used NASM and MinGW. Here's a list of my following actions:

    1. Assembled bootsector.asm as normal (nasm bootsect.asm -o bootset.o)
    2. Assembled kernel_entry.asm with nasm kernel_entry.asm -f elf32 -o kernel_entry.o,after
    3. Compiled kernel.c with gcc -m32 -c kernel.c -o kernel.o -ffreestanding -nostdlib -nostdinc
    4. Linked kernel_entry.o and kernel.tmp with ld -m i386pe -o kernel.tmp -Ttext 0x1000 kernel_entry.o kernel.o
    5. Transformed kernel.tmp to bin with objcopy -O binary -j .text kernel.tmp kernel.bin
    6. Merged together bootsect.o and kernel.bin with type bootsect.o kernel.bin > drive.bin