I'm just falling in the kernel writing ocean now; i'm currently trying to write a bare minimal x64 kernel under qemu. It does not work.
I'm coding on Ubuntu x64.
Here are my files:
kernel.c (comes from the tuto)
Code: Select all
#include <stdint.h>
void kmain(void)
{
extern uint32_t magic;
if ( magic != 0x2BADB002 )
{
/* Something went not according to specs. Print an error */
/* message and halt, but do *not* rely on the multiboot */
/* data structure. */
}
volatile unsigned char *videoram = (unsigned char *)0xB8000;
videoram[0] = 65; /* character 'A' */
videoram[1] = 0x07; /* light grey (7) on black (0). */
while (1);
}
Code: Select all
.global loader # making entry point visible to linker
# setting up the Multiboot header - see GRUB docs for details
.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum required
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
# reserve initial kernel stack space
stack_bottom:
.skip 16384 # reserve 16 KiB stack
stack_top:
.comm mbd, 4 # we will use this in kmain
.comm magic, 4 # we will use this in kmain
loader:
movl $stack_top, %esp # set up the stack, stacks grow downwards
movl %eax, magic # Multiboot magic number
movl %ebx, mbd # Multiboot data structure
call kmain # call kernel proper
cli
hang:
hlt # halt machine should kernel return
jmp hang
Code: Select all
OUTPUT_FORMAT(elf64-x86-64)
ENTRY(kmain)
SECTIONS
{
. = 10000;
.text : AT(ADDR(.text) - 10000)
{
_code = .;
*(.text)
*(.rodata*)
. = ALIGN(4096);
}
.data : AT(ADDR(.data) - 10000)
{
_data = .;
*(.data)
. = ALIGN(4096);
}
.eh_frame : AT(ADDR(.eh_frame) - 10000)
{
_ehframe = .;
*(.eh_frame)
. = ALIGN(4096);
}
.bss : AT(ADDR(.bss) - 10000)
{
_bss = .;
*(.bss)
/*
* You usually need to include generated COMMON symbols
* under kernel BSS section or use gcc's -fno-common
*/
*(COMMON)
. = ALIGN(4096);
}
_end = .;
/DISCARD/ :
{
*(.comment)
}
}
The commands a used:
Code: Select all
$ as -o loader.o loader.s
$ gcc -m64 -ffreestanding -nostdlib -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -nostartfiles -nodefaultlibs -c kernel.c
$ ld -nostdlib -nodefaultlibs -T link.ld -o kernel kernel.o loader.o
The result:
Code: Select all
$ file kernel
kernel: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ qemu-system-x86_64 -kernel kernel
Cannot load x86-64 image, give a 32bit one.
Code: Select all
$ file vmlinuz
vmlinuz: Linux kernel x86 boot executable bzImage, version 3.5.0-23-generic (buildd@komainu) #35-Ubuntu SMP Thu Jan 24 13:, RO-rootFS, swap_dev 0x4, Normal VGA
What does that mean ?
I'm aware i miss a lot of understanding (the reason why i'm here), that i should start learning ld scripting also, which i'm likely to do, but my really first goal is to have a bare minimum stuff that works.
Thank you in advance !...