Page 1 of 1

Help with C Kernel

Posted: Mon Nov 10, 2014 2:06 am
by Hanz
I am now creating my second operating system, this time in protected mode, using unformatted floppy. I have set up cross-complier, i686-elf-gcc, and created assembly boot loader that loads kernel and enters to Protected Mode. Now I am trying to create kernel using C, but I have difficulties about executing it from assembly. The "Kernel" is now nearly simplest possible C program:

Code: Select all

void main() {
    for (;;);
}
I can compile it using:

Code: Select all

i686-gcc -c kernel.c -o kernel.o -std=gnu99 -ffreestanding -O2 -Wall -Wextra
and it doesn't even produce any warnings. So, now I have kernel.o file, but how do I put it to floppy image and execute it. After that, I just used

Code: Select all

cat file.raw >> os.img
, but it don't work with C.

I have tried to search the web, but I found only those witch used grub, while I use my own custom bootloader.

Thanks for help in advance.

Re: Help with C Kernel

Posted: Mon Nov 10, 2014 7:23 am
by ExeTwezz
Hi,

GCC produces ELF executables, so the problem may be that your bootloader just loads the file and jumps to the beginning of the file (doesn't support ELF).

-----------------------------------------------------

I recommend you to use .iso with GRUB 2:

Code: Select all

$ # Compile and link the kernel into kernel.elf ELF executable.
$ sudo apt-get install grub2 xorriso
$ mkdir -p isofiles/boot/grub
$ echo "menuentry \"Entry Name\" {" >> isofiles/boot/grub/grub.cfg
$ echo "    multiboot /boot/kernel.elf" >> isofiles/boot/grub/grub.cfg
$ echo "}" >> isofiles/boot/grub/grub.cfg
$ cp kernel.elf >> isofiles/boot/kenrel.elf
$ grub-mkrescue -o os.iso isofiles
This will create a GRUB 2 CD-ROM (.iso) image called "os.iso". You can boot from this this way:

Code: Select all

$ qemu-system-i386 -cdrom os.iso -boot cd

Re: Help with C Kernel

Posted: Mon Nov 10, 2014 7:46 am
by sortie
You forgot to link the kernel.

I recommend you follow http://wiki.osdev.org/Bare_Bones - and instead of using GRUB, you implement your own ELF loading bootloader (and perhaps multiboot). This is the best approach if you really insist on doing a bootloader, which are boring parts that delay the fun kernel parts.

Re: Help with C Kernel

Posted: Mon Nov 10, 2014 2:11 pm
by Hanz
sortie wrote:You forgot to link the kernel.
Thanks. I know that I don't link kernel, I asked how to link ELF binaries the way I can call them from assembly. I am using my own bootloader, witch works very well, I can't even imagine using grub because before this point creating own bootloader has been so easy.
sortie wrote: I recommend you follow http://wiki.osdev.org/Bare_Bones - and instead of using GRUB, you implement your own ELF loading bootloader.
That looks very good. I was mainly following the BrokenThorn before it began to use windows-specific PE.
sortie wrote: This is the best approach if you really insist on doing a bootloader, which are boring parts that delay the fun kernel parts.


Even now I have so fun that I can't event imagine how fun it will be. (Or, maybe "the fun kernel parts" is sarcasm.) But I still enjoy this very much.

So, how can I link the object files the way I can use them with my OS. I have Stage1.bin, Stage2.bin and kernel.o.( *.bin files are compiled with nasm -f bin and kernel with my cross-compiler)

Edit: removed duplicate end quote tags, typos

Re: Help with C Kernel

Posted: Mon Nov 10, 2014 2:55 pm
by sortie
Hanz wrote:Even now I have so fun that I can't event imagine how fun it will be. (Or, maybe "the fun kernel parts" is sarcasm.)
Ah, it's not sarcasm. The kernel and user-space is the goal, it's where you can do useful things and be a real operating system. The bootloader itself is irrelevant directly, it's only task is loading the kernel. There are technical details and challenges all over the place, but in the kernel you become a real operating system and do real things.

I don't do bootloaders myself for the above reasons (and when I do, I won't use a naive approach), but the basic approach is that produce two binaries separately: The bootloader itself and the kernel. The bootloader you just do with your assembler and make a raw image that can be written to your boot media. The kernel should be linked like shown in Bare Bones (except that you might decide another load address, if you don't do multiboot). You then get a linked ELF kernel. If you implement multiboot, you load that kernel as is in the multiboot manner. Otherwise, you can use a tool like objcopy to convert the ELF kernel into whatever format you prefer. You now have the bootloader and the kernel in your favorite format. Somehow you mix that into a basic bootable image with your bootloader installed, which can then locate the kernel on the boot media (perhaps using a little filesystem), load it appropriately into memory and switch to it.

It's best to link to an ELF kernel first. This is a versatile format and contains a lot of useful meta information that makes them convenient, existing tools understand then natively, they can be dumped, studied, converted, all that good stuff you can't do with naive formats. You then convert the ELF binary into whatever format you prefer.

A naive way to do this: You link the kernel to 0x7E00 (512 bytes after the bootloader). You objcopy the kernel to a flat binary loadable at 0x7E00. Your 512 byte bootloader loaded at at 0x7C00, loaded from byte offset 0 of the harddisk, loads some sectors from byte offset 512 (where your kernel will be) to 0x7E00 and onwards. The bootloader switches to protected mode and all the other bootloader stuff and starts executing at 0x7E00. To make a harddisk image, you merely cat bootloader.bin kernel.bin and pad some zeroes.

A better way to do this: The harddisk contains an ext2 filesystem containing the kernel at /boot/myos.kernel as a 32-bit ELF multiboot kernel. The bootloader loads its part two and then parses the filesystem with its read-only ext2 driver, locates the kernel, loads it to the addresses written in the ELF program, switches to protected mode and starts executing the kernel as detailed in the multiboot standard.

I certainly think it can good experience to write a bootloader. I wouldn't recommend it as the way to start osdev. My recommendation is to use GRUB and multiboot to get started, write a good operating system, when GRUB isn't good enough, you write your own awesome bootloader with all your experience.

Re: Help with C Kernel

Posted: Mon Nov 10, 2014 4:57 pm
by Hanz
Ok, thanks.

The naive way looks such simple. I know that I can do it. But I will not do it.

The ext2 is hard to code, but looks better. I think I could use it. Just read-only driver maybe? How do I write my OS to VirtualBox disk image (or something that VB or qemu can boot?) automatically. Maybe bash script?

And those bootloaders... I think it's easier to code my own than use GRUB. And also not using any "cheats" like it motivates me.

Re: Help with C Kernel

Posted: Mon Nov 10, 2014 5:49 pm
by sortie
Some tips on the custom-bootloader-that-reads-ext2-and-loads-elf-kernel:
  • The Second Extended File System (some documentation on how ext2 works, it might look scary, but it's actually a pretty decent and simple proper Unix filesystem) (feel free ask me if you have any ext2 questions)
  • The System V ABI wiki article. ELF, the format of your kernel, is part of the system V ABI.
  • Multiboot wiki article, if you decide to support ELF.
  • vboxmanage, a virtualbox utility program that has a convertfromraw command that converts a raw harddisk image so VirtualBox can read it. See also the internalcommands converttoraw subcommand that does the opposite and is undocumented for odd reasons.
You should also get to know tools like readelf and objdump well (part of your cross-binutils).

Qemu uses raw harddisk images by default, so they are easy to use with -hda.

Re: Help with C Kernel

Posted: Tue Nov 11, 2014 2:51 am
by iansjack
And those bootloaders... I think it's easier to code my own than use GRUB.
I think you are completely wrong here; using Grub is trivial.

You'll certainly learn more by writing your own bootloader - you'll need to. Personally I would leave learning the details of ext2 filesystems and elf-format files until you have a little more experience.

Re: Help with C Kernel

Posted: Tue Nov 11, 2014 6:11 am
by Hanz
I have been using VBoxManage command/tool long time, but I haven't noticed this convertfromraw command before.

I am now developing my kernel with just pure assembly and, yes, gaining more experience with that (like writing device drivers etc). I will continue with C kernel when I know better all those protected mode things.