I've created an extremely useful tool for kernel developers

This forums is for OS project announcements including project openings, new releases, update notices, test requests, and job openings (both paying and volunteer).
Post Reply
ckotinko
Posts: 1
Joined: Fri May 08, 2009 6:37 am

I've created an extremely useful tool for kernel developers

Post by ckotinko »

Hello

I'm writing my own kernel, and after month of hitting the wall with my head I've found a way to
a) boot 64bit kernels from GRUB without assembly files
b) eliminate global offset table

I hope it will be useful for you.

My goal was to write 32bit code which deals with GRUB, creates page tables, GDT and other stuff in C++. Linker refuses to link 32bit and 64bit object files, but feels ok if you translate 32bit sources to assembly(with gcc -S), and them compile them as 64bit object files. The tool detects "#define MULTIBOOT_INTERFACE" line in source files and builds them with -m32 -S flags, then postprocesses assembly code and compiles the result into 64bit object files. Another problem is GOT with I don't want to see in my binary. This problem is solved during postprocessing stage.

During postprocessing stage I insert dummy section in file header:

Code: Select all

.text
.Ltext_offset:
Also I remove .file directive because I dislike it, and #APP / #NOAPP lines - gcc wraps my inline assembly with them.

Then each GOT address calculation is modified:

Code: Select all

	call	__x86.get_pc_thunk.bx
//	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
	addl	$(.Ltext_offset - .), %ebx
Then each reference to GOT is replaced with address of label relative to .Ltext_offset:

Code: Select all

//	leal	.LC0@GOTOFF(%ebx), %eax
	movl	$(.LC0-.Ltext_offset), %eax
	addl	%ebx, %eax
Upd: there is an unfixed problem with static variables:

Code: Select all

int foo;
void bar() {
    m = foo;
    ...
    foo = n;
}
Please move all such variables into a static structure and get a pointer to this structure:

Code: Select all

struct fb_parameters {
    uint64 address = 0xB8000;
    uint32 width   = 80;
    uint32 height  = 24;
    uint32 pitch   = 0;
    uint32 bpp     = 0;
    uint32 color   = 0;
    uint32 x = 0, w = 0;
    static void (*putchar)(int);
};
static fb_parameters fb;

void print32 (const char *format, ...) {
    auto f = &::fb;
    ...
}
There are still problems with instructions like movzbl, I'll fix them soon.

Regards,
Dmitry
Attachments
main.cpp
compiler wrapper, updated
(8.32 KiB) Downloaded 111 times
MichaelPetch
Member
Member
Posts: 712
Joined: Fri Aug 26, 2016 1:41 pm
Freenode IRC: mpetch

Re: I've created an extremely useful tool for kernel develop

Post by MichaelPetch »

Why not use objcopy to convert 32-bit object to 64-bit objects?
Octocontrabass
Member
Member
Posts: 5218
Joined: Mon Mar 25, 2013 7:01 pm

Re: I've created an extremely useful tool for kernel develop

Post by Octocontrabass »

ckotinko wrote:b) eliminate global offset table
There's an easier fix: -fno-pic.

There's an even easier fix: use a proper cross-compiler.
Post Reply