
Writing kernels that boot with Qemu and Grub – a tutorial - ingve
http://www.cs.vu.nl/~herbertb/misc/writingkernels.txt
======
exDM69
Nice but very incomplete article. Some observations below...

You _will_ need to build a cross compiler toolchain (binutils and GCC). I.e.
i686-pc-elf-gcc for 32 bit or x86_64-pc-elf-gcc for 64 bit. The compiler that
comes with your OS is built for a different target and may have downstream
patches, esp. if you're on Ubuntu. Things may seem to work initially but you
_will_ encounter strange bugs sooner or later.

Build a bootable and debuggable ELF file, not a flat binary. All it takes is a
slightly different linker script. You won't get very far without a debugger on
bare metal projects.

You need to zero fill .bss section in the boot code before jumping to C code.

I recommend using gas instead of nasm. You might like Intel syntax but you'll
need inline (at&t) assembly in C code anyway. Nicer to have just one syntax.
It's just an assembler syntax, you will get used to it in a matter of hours

Use a makefile. Fancy build systems (e.g. cmake) aren't nice with kernel
images.

See below for examples. The first one isn't my project but I contributed the
linker script, Makefile and README for making bootable ELFs. The latter is my
x86_64 toy kernel project from years ago.

[https://github.com/Overv/MineAssemble](https://github.com/Overv/MineAssemble)

[https://github.com/rikusalminen/danjeros](https://github.com/rikusalminen/danjeros)

~~~
grahamedgecombe
> You need to zero fill .bss section in the boot code before jumping to C
> code.

GRUB does this for you. See this thread from a few years ago:
[https://news.ycombinator.com/item?id=7590790](https://news.ycombinator.com/item?id=7590790)

~~~
exDM69
Hah, it was a response to my comment back then too.

Either that applies only to multiboot v2 or there was a bug in qemu loader
since I had a non-zero value in .bss.

------
deathanatos
I'm impressed they got grub onto a hard disk image without needing root; I
didn't think you could do that. I struggled with that for a while, before I
found grub2-mkrescue, which I think is much easier if you're just starting
out. The entire sequence to create a CD ISO is,

    
    
      # Stage the data we want in our image:
      mkdir -p isofiles/boot/grub
      cp grub.cfg isofiles/boot/grub/.
      cp kernel.bin isofiles/boot/.
    
      # Make the image:
      grub2-mkrescue -o os.iso isofiles
    
      # Clean up:
      rm -rf isofiles
    

Which I got from the tutorial here[1], which is also excellent.

[1]: [http://os.phil-opp.com/multiboot-kernel.html](http://os.phil-
opp.com/multiboot-kernel.html)

~~~
lahdekorpi
How is booting from a CD not being "root"?

~~~
pjc50
Booting from a CD is outside the OS permissions system. The parent poster is
talking about _making the CD image_.

~~~
therein
Why should creating an ISO need root? It shouldn't be any different than
creating a tarball or a zip file.

~~~
deathanatos
As pjc50 notes, it _shouldn 't_; absolutely nothing about creating either ISOs
or hard disk images requires root, in theory — it's just a file, after all.
But in practice, tools like losetup and mount both require it. The part I
found novel in the article was the mtools package, which I didn't know about.

Linux has made progress here, such as FUSE for mounting in user space. But
FUSE doesn't support file systems that the OS inherently supports, for
example. My understanding is that you need to write a FUSE driver for, e.g.,
ext2, even though Linux is perfectly capable of mounting ext2 as root.

Block devices and partition tables present another hassle.

I suspect ISOs are more easily done simply because non-root users have more
need to create them: UI applications for making ISOs readily exist, but I
can't think of any common applications that deal with disk images that don't
already have root.

------
orionblastar
This is a good resource.

About a few years ago I was offered a $10K bounty to make Solaris 7 work with
QEMU, and the only progress anyone ever made was mounting the ISO image as a
hard drive image and install from there. Nobody ever got the NIC card to get
on the Internet. I found out CDROM0: or something could access the ISO image.
Everytime I set up TCP/IP it would cause a kernel panic, or lock the system
up, or crash. I was given like a week and could not do it. Then I found out
about Hackers in Russia trying to do the same thing and not getting anywhere.
Apparently the Solaris 7 Kernel has a NIC bug in it where some pointers are
out of place. It was solved in a Y2K CD-ROM from Sun which is no longer
offered.

Client who wanted me to make it work has a failing SPARC Server with Solaris 7
and needed everything the same. Problem was fixed in Solaris 9, but they
needed Solaris 7 even if 9 is backward compatible.

Writing a new Kernel for Solaris 7 based on the old Kernel that works with
QEMU might just work. Remember it is QEMU SPARC that I was working with to get
networking going.

But if the best and brightest Hackers couldn't get Solaris 7 to have
networking, then I for sure couldn't do it either.

But there is a need to emulate any sort of hardware no longer supported or
made anymore because many businesses run on software created for those old
hardware and software standards and when they can't buy the old hardware or it
costs too much, it is better to just run it on QEMU.

~~~
viraptor
> businesses run on software created for those old hardware and software
> standards and when they can't buy the old hardware or it costs too much, it
> is better to just run it on QEMU.

Or rewrite the software. At some point they're just going to pay more for not
upgrading than it would cost them to start from scratch. And that's not
including the cost of teaching people to manage old solaris boxes and dealing
with non-accelerated QEMU draining your power budget.

~~~
nurettin
Or port the software. I was given the task to port a soap-based MLOC client-
server application from kylix-apache to modern delphi xe-apache.

All I had to do was to fix everywhere that used ansistring which meant
rewriting compression, variants handling, hashing and porting a bunch of
delphi library stuff that changed in the past 14 years.

After a few months and a gigantic commit on a few dozen files we can now debug
everything, all apache modules run smoothly on windows and even android
clients work.

~~~
viraptor
If you have access to the source, that's possible of course. But I'm assuming
that Solaris 7 also means you're stuck with proprietary, closed solution.

------
partycoder
If a lightweight operating system won't do and you don't want to create a full
OS from scratch you can try a unikernel based on includeOS or mirageOS (the
few ones I know of).

If this is still not good... try visiting
[http://wiki.osdev.org/Main_Page](http://wiki.osdev.org/Main_Page)

------
ploxiln
This mentions ubuntu 7.10, so must be from early 2008 - still very educational
and interesting, but probably worth mentioning the age, since x86_64 has
become ubiquitous, kvm / bhyve / xhyve have appeared, EFI, virtio, directly
booted kernels, other stuff I'm sure ...

~~~
exDM69
x86_64 is more work to get bootstrapped than 32 bit mode, it might still make
sense to do hobby hacking projects in 32 bit mode.

Although I've not worked with EFI (only multiboot) so I'm not sure how
different it would be.

~~~
ornitorrincos
well, the nice thing about EFI is that it already places you into long mode

~~~
exDM69
But how does it configure the page table?

There's no identity mapped mode in x86_64, which slowed down my work because
of chicken/egg problems in early boot page table configuration.

That being said, I'd probably be using EFI in long mode if I was starting a
bare metal project on x86_64 in 2016.

~~~
ornitorrincos
UEFI identity maps the memory.

UEFI applications are kind of weird, as until ExitBootServices is called they
are regular hosted applications that need to call the EFI boot services to do
things like allocating memory, once ExitBootServices is called they take full
control of the system

