*This post is under construction. I am in the process of trying to contribute to the Linux Kernel. This post is not finished and will get updated as I go*

I use a MacBook Pro (mid-2014) with macOS, so I need to have a virtual machine for running a linux system with my kernel. I will also be doing the coding on this linux virtual machine as building the kernel is easier in a linux system than macOS.

# Setting up the Virtual Machine (Archlinux)

I create a virtual machine with Archlinux on my macOS using QEMU:

2. Create a qemu disk
1. Start the machine and install Archlinux
1. Start the machine after installing (note I forward 2222 to 22 so I can SSH/SCP to the virtual machine. I also set 4 CPUs so I can use threads for faster builds in the VM)
1. Install dependencies for building the kernel
1. Clone linux
1. Install the necessary dependencies for building the kernel
1. Copy configuration of archlinux (optional: also use modprobed-db to remove unnecessary modules)
1. Make sure you enable debugging configurations
1. Make! The -j8 parameter specifies the number of threads to be used by the build. My CPU has 8 threads and so I use it all.
1. Install the newly built Kernel. I create this as a script file and run it after every build from the root of repository.
• Reboot and choose the new kernel (might be under “Advanced” in the bootloader)

# Development Environment

Setup your environment for development. Mine consists of setting up tmux so I can have multiple terminals and neovim.

In the guest machine:

And in the host:

One thing I found necessary, due to limited storage, is a script to cleanup each linux version after I’m done with them, since they create a couple of files in different places. I call this cleanup-linux.sh:

# Debugging

There is a pr_debug function used over the code, in order to enable those logs in dmesg for a specific module, you can do this:

Note that, this works if you have dynamic debug enabled in your .config:

You can then look at dmesg while running the code to see those logs:

## Kernel Oops, Bug and Panic

If you get a Kernel Oops, Kernel Bug or similar, here are some good resources on how to read and understand the output:

For example, I wanted to be able to understand the call trace of this Kernel Bug: bug-207773

The call trace section starts with:

[226832.533889] Call Trace:
[226832.534377]  <IRQ>
[226832.534776]  recent_entry_update+0x52/0xa0 [xt_recent]
[226832.535690]  recent_mt+0x167/0x328 [xt_recent]
[226832.536488]  ? set_match_v4+0x96/0xb0 [xt_set]
[226832.537407]  ipt_do_table+0x24f/0x610 [ip_tables]
[226832.538277]  ? ipt_do_table+0x33e/0x610 [ip_tables]
[226832.539146]  ? l4proto_manip_pkt+0xde/0x440 [nf_nat]
[226832.540049]  ? ip_route_input_rcu+0x40/0x280
[226832.540831]  nf_hook_slow+0x40/0xb0
[226832.541477]  ip_forward+0x424/0x450
[226832.542116]  ? ip_defrag.cold+0x37/0x37
[226832.542814]  ip_rcv+0x9c/0xb0


The way I did it was to run gdb on the vmlinux file in the root of the repository after build, and then load the symbol files of each module that is relevant: