Software Development flow is an elusive beast, easily frightened away. The easiest way to lose the flow is to have a long development cycle. Building the entire Linux Kernel takes time. If you are developing a single driver that can be built as a stand alone module, you do not want to have to rebuild the entire Kernel each time you make a change to that module. If that module crashes the machine when it runs into an error, you do not want to have to wait for that machine to reboot before digging in to the debugging process.
These two guidelines lead to a pattern of building on one machine and deploying on another. Here is one way to go about this process.
When I build and deploy on the same machine, I typically have a series of command linked together that build all of the steps and that error out if any of them fail. Typically, it looks like this:
make -j `nproc` && make -j `nproc` modules && make -j `nproc` modules_install && make -j `nproc` install
What I want to do is adapt this build to a format acceptable to transport to another machine. Our first choice is to build a package suitable for the remote machine. Since I am deploying to a Fedora base system, that would be an RPM. That command looks like this:
make -j `nproc` rpm-pkg
However, this takes an incredibly long time to complete, which breaks the development cycle. Part of the reason for this delay is that it builds the entire kernel from start every time. It also builds other packages, including both the production and debug packages. We likely do not need both for our work.
Instead, I want to manually copy the files over to the remote machine once, install, and then update only those files that get changed on a recompilation. I can use the tar target to get all of the binaries I need and copy them to the remote system. A build command for that looks like this:
make -j `nproc` && make -j `nproc` modules && make -j `nproc` tar-pkg
I chose not to zip the final package as the next step is to copy it across the network, and that happens pretty fast.
scp linux-6.12.1+-arm64.tar :root@$TEST_HOST
I tried untarring directly in the / directory, but it made my remote system unstable. I did not investigate why, and instead chose to continue with making my steps work manually. This is a one time cost, although it could be trivially automated. SSH in to the test system and
mkdir /root/tmp
cd /root/tmp
tar -xf ../linux-6.12.1+-arm64.tar
mv lib/modules/6.12.1+/ /lib/modules
kernel-install add 6.12.1+ boot/vmlinuz-6.12.1+
At this point I reboot and confirm that my newly built kernel is running.
# uname -a
Linux sut12sys-r112.scc-lab.amperecomputing.com 6.12.1+ #1 SMP PREEMPT_DYNAMIC Mon Dec 30 10:47:11 PST 2024 aarch64 GNU/Linux
Now if I want to redeploy a single module, I can do so by copying the file over and putting it into the appropriate place under /lib/modules . If my module crashes the system, I might need a rescue image to boot without getting an oops.