Hacker News new | past | comments | ask | show | jobs | submit login
Writing kernels that boot with Qemu and Grub – a tutorial (vu.nl)
111 points by ingve on July 28, 2016 | hide | past | favorite | 24 comments



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/rikusalminen/danjeros


> 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


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.


What problems do you have with cmake and kernel images?


Using a linker script was more painful than it should have been. Pre-processed assembly files (.S) didn't work (they should run through C pre processor). Writing toolchain file for cross compiling wasn't easy.

CMake works great for user space apps, and cross compiling works very well for them. But bare metal projects, kernel modules, etc just are not great.


> 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.

Then a good idea would be to bootstrap it with a build environment on the emulator


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


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


Booting from a CD is outside the OS permissions system. The parent poster is talking about making the CD image.


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


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.


It shouldn't. However, many of the tools assume the ability to e.g. mount filesystem images as part of the process. Which does require root.


Exactly. Physical access is root access.


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.


> 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.


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.


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.


Yeah but they had a problem. The people who wrote the software for their business never gave them the source code and either died or retired. It apparently only works with Solaris 7 under SPARCServers and SPARC Stations.

They claim without the source code, the cost of rewriting it would be more than the cost of running a QEMU virtual machine on a Linux box.

They even had an OpenBSD Box with the same problem using an old version of software with no source code. But I think they could run the old OpenBSD on an X86 box or QEMU machine as there was no SPARC factor like with Solaris 7.

Apparently a lot of small IT shops pay people to write software in the 1990s, and get binaries but no source code because the contract didn't specify they get the source code. Contractors had the source code but kept it from the client to make sure they still get business to modify the software and the client doesn't hire someone else. During the Dotcom busts the contractors went out of business or one of them died from being old and nobody knows where the source code is located. Might be in a storage locker, they forgot to pay, and it was auctioned off. Might belong to a lawyer or underwriting who bought out the stock and IP and nobody knows who that person is.


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


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 ...


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.


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


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.


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




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: