Page 1 of 1

Booting ELF kernel converted to plain BIN

Posted: Wed Oct 18, 2017 10:39 am
by doubletriplefault
So, i have ELF kernel that has one part written in C and the other in NASM. These two parts are linked into the ELF kernel and converted to plain BIN with objcopy. The kernel has to be started from primary bootloader (I'm using one from MikeOS). But bootloader starts up, finds kernel, jumps to it and hangs the system. And i don't know where the problem is.
ASM part of kernel (_start is the entry point):

Code: Select all

;This part is needed for keyboard support and kernel launch
BITS 16
disk_buffer	equ	24576

global _start
extern kernel_main
_start:
	msg:    db "Entrypoint",10
	cli
	mov ax, 0
	mov ss, ax
	mov sp, 0FFFFh
	sti
	cld
	mov ax, 2000h
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	call kernel_main
    hlt

global keyboard_handler
global read_port
global write_port
global load_idt

extern keyboard_handler_main

read_port:
	mov edx, [esp + 4]
	in al, dx
	ret

write_port:
	mov   edx, [esp + 4]    
	mov   al, [esp + 4 + 4]  
	out   dx, al  
	ret

load_idt:
	mov edx, [esp + 4]
	lidt [edx]
	sti 
	ret

keyboard_handler:                 
	call    keyboard_handler_main
	iretd
C part:

Code: Select all

#if !defined(__cplusplus)
#include <stdbool.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include "keyboard_map.h"
#include "standard/strings.h"
#include "screen/terminal.h"
#include "owshell/execute.h"
#include "keyboard/kbdinit.h"
#include "keyboard/kbdhandle.h"
#include "screen/init.h"
#include "standard/stdio.h"
#include "owshell/die.h"

#if defined(__cplusplus)
extern "C"
#endif
void kernel_main(void) {
	console_init();
	idt_init();
	kb_init();
	while(!dead);
}


Re: Booting ELF kernel converted to plain BIN

Posted: Wed Oct 18, 2017 11:02 am
by MichaelPetch
There seems to be a lot missing. Do you have a more complete project on Github or similar service? I don't see where you enter protected mode but it seems like you are then trying call into 32-bit code while still in real mode? If so, that won't work. You shouldn't start the stack pointer on an odd address like 0xffff. Set it to 0x0000 then the first values pushed will end up at the top of the segment at 0xffff and 0xfffe after the first push (in real mode). This is a problem to:

Code: Select all

_start:
   msg:    db "Entrypoint",10
   cli
. In that code you have placed data before the instructions so that data will be executed as code as well and gosh knows what that'll do (if anything). There may be other things as well but not visible in the code provided.

Re: Booting ELF kernel converted to plain BIN

Posted: Wed Oct 18, 2017 11:59 am
by doubletriplefault
MichaelPetch wrote:Do you have a more complete project on Github or similar service?
Yes, on Github.
MichaelPetch wrote:it seems like you are then trying call into 32-bit code while still in real mode? If so, that won't work. You shouldn't start the stack pointer on an odd address like 0xffff. Set it to 0x0000 then the first values pushed will end up at the top of the segment at 0xffff and 0xfffe after the first push (in real mode).
Oh, yes. Fixed it.
MichaelPetch wrote:In that code you have placed data before the instructions so that data will be executed as code
The data was placed there just to check the entry point, I removed it.

Re: Booting ELF kernel converted to plain BIN

Posted: Wed Oct 18, 2017 12:08 pm
by MichaelPetch
Looking at that code I don't see where you enter protected mode before calling into your kernel_main function. Without entering protected mode you can't expect to have kernel_main and your 32-bit code to run properly.

As well in your linker script you use 1M as your origin point in memory (Starting Virtual Memory Address) but that's not the location in RAM you loaded kernel.bin. That will also cause issues.