<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ddupard</title>
    <description>The latest articles on DEV Community by ddupard (@ddupard).</description>
    <link>https://dev.to/ddupard</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3949744%2Fab1a1cf3-7a46-4fa9-92d1-8ac9855809d3.png</url>
      <title>DEV Community: ddupard</title>
      <link>https://dev.to/ddupard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ddupard"/>
    <language>en</language>
    <item>
      <title>Building a comfortable workflow for debugging an old version of the Linux kernel</title>
      <dc:creator>ddupard</dc:creator>
      <pubDate>Mon, 25 May 2026 01:38:52 +0000</pubDate>
      <link>https://dev.to/ddupard/building-a-comfortable-workflow-for-debugging-an-old-version-of-the-linux-kernel-557c</link>
      <guid>https://dev.to/ddupard/building-a-comfortable-workflow-for-debugging-an-old-version-of-the-linux-kernel-557c</guid>
      <description>&lt;p&gt;When you want to work on the Linux kernel, for example to see how an exploit acts (like Dirty COW on kernel 4.7), you need to build a comfortable working environment.&lt;/p&gt;

&lt;p&gt;I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; for compiling sources in their original version (with the GCC/LD versions corresponding to the source era).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;QEMU&lt;/strong&gt; for running the executables in a virtual machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VS Code&lt;/strong&gt; as a debugger.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Through this article, I will show you how I configured my environment to achieve an efficient setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Compiling source code
&lt;/h2&gt;

&lt;p&gt;The first step is to retrieve the kernel source code.&lt;/p&gt;

&lt;p&gt;For relatively recent versions (beyond 5.10), the simplest way is to download the tar file from &lt;a href="https://www.kernel.org/" rel="noopener noreferrer"&gt;kernel.org&lt;/a&gt;. For older versions, the best solution is to fetch them via git.&lt;/p&gt;

&lt;p&gt;For example, for 4.7, we start by retrieving the tags:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;git ls-remote --tags git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git | grep "v4.7"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then we clone it to get the version without downloading the entire history:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;git clone --depth 1 --branch v4.7 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 4.7&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After a few minutes, you have a &lt;code&gt;4.7/&lt;/code&gt; directory containing a working version of the 4.7 kernel sources.&lt;/p&gt;

&lt;p&gt;However, these sources are not compilable as-is. Compiling a 4.7 kernel (released in 2016) with a modern compiler (GCC 13+) produces compilation errors due to changes in C language standards or security attribute handling. This is why you need to load versions of GCC and LD compatible with these sources (see the table below), and the easiest way to do this is via Docker.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kernel Version&lt;/th&gt;
&lt;th&gt;Ubuntu Version&lt;/th&gt;
&lt;th&gt;Codename&lt;/th&gt;
&lt;th&gt;Release Date&lt;/th&gt;
&lt;th&gt;Default GCC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;v2.6.x&lt;/td&gt;
&lt;td&gt;6.06&lt;/td&gt;
&lt;td&gt;Dapper Drake&lt;/td&gt;
&lt;td&gt;June 2006&lt;/td&gt;
&lt;td&gt;GCC 4.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.2&lt;/td&gt;
&lt;td&gt;12.04&lt;/td&gt;
&lt;td&gt;Precise Pangolin&lt;/td&gt;
&lt;td&gt;April 2012&lt;/td&gt;
&lt;td&gt;GCC 4.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.13&lt;/td&gt;
&lt;td&gt;14.04&lt;/td&gt;
&lt;td&gt;Trusty Tahr&lt;/td&gt;
&lt;td&gt;April 2014&lt;/td&gt;
&lt;td&gt;GCC 4.8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v4.4&lt;/td&gt;
&lt;td&gt;16.04&lt;/td&gt;
&lt;td&gt;Xenial Xerus&lt;/td&gt;
&lt;td&gt;April 2016&lt;/td&gt;
&lt;td&gt;GCC 5.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v4.15&lt;/td&gt;
&lt;td&gt;18.04&lt;/td&gt;
&lt;td&gt;Bionic Beaver&lt;/td&gt;
&lt;td&gt;April 2018&lt;/td&gt;
&lt;td&gt;GCC 7.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v5.4&lt;/td&gt;
&lt;td&gt;20.04&lt;/td&gt;
&lt;td&gt;Focal Fossa&lt;/td&gt;
&lt;td&gt;April 2020&lt;/td&gt;
&lt;td&gt;GCC 9.3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v5.15&lt;/td&gt;
&lt;td&gt;22.04&lt;/td&gt;
&lt;td&gt;Jammy Jellyfish&lt;/td&gt;
&lt;td&gt;April 2022&lt;/td&gt;
&lt;td&gt;GCC 11.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v6.8&lt;/td&gt;
&lt;td&gt;24.04&lt;/td&gt;
&lt;td&gt;Noble Numbat&lt;/td&gt;
&lt;td&gt;April 2024&lt;/td&gt;
&lt;td&gt;GCC 13.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We need to retrieve the Docker container corresponding to the kernel version we are interested in. For 4.7, it is Ubuntu 16.04.&lt;/p&gt;

&lt;p&gt;To search for available containers, there are 2 solutions:&lt;br&gt;
a) Run the command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;skopeo list-tags docker://docker.io/library/ubuntu&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you should see something like &lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
    "Repository": "docker.io/library/ubuntu",&lt;br&gt;
    "Tags": [&lt;br&gt;
        "10.04",&lt;br&gt;
        "12.04",&lt;br&gt;
        "12.04.5",&lt;br&gt;
        "12.10",&lt;br&gt;
        "13.04",&lt;br&gt;
        "13.10",&lt;br&gt;
        "14.04",&lt;br&gt;
        "14.04.1",&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;...then run the command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker pull ubuntu:16.04&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;b) Go to Docker Hub &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52j4gppztvssbvxchx44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52j4gppztvssbvxchx44.png" alt="Docker Hub" width="800" height="394"&gt;&lt;/a&gt;&lt;br&gt;
and download it.&lt;/p&gt;

&lt;p&gt;After a few minutes, you can run the following command to check that your container was downloaded &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker images&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and you should see&lt;/p&gt;

&lt;p&gt;kernel-builder-515:latest   9f311ec05f16        580MB          147MB    U&lt;br&gt;&lt;br&gt;
ubuntu:16.04                1f1a2d56de1d        195MB         46.5MB    U   &lt;/p&gt;

&lt;p&gt;I always favor LTS (Long Term Support) versions like 16.04, because they guarantee library longevity and compilation tool stability, which is critical to avoid linking errors when generating &lt;code&gt;vmlinux&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;See the difference here: ubuntu:16.04 is the raw image we just downloaded, while kernel-builder-515 represents the kernel 5.15 image that I customized to include all the necessary compilation tools. We will now cover this customization step using the Dockerfile.&lt;/p&gt;

&lt;p&gt;To customize the downloaded Docker container, we use a &lt;code&gt;Dockerfile&lt;/code&gt;, here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;### Example for kernel 4.7 (based on Ubuntu 16.04 - Xenial)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ubuntu:16.04&lt;/span&gt;

&lt;span class="c"&gt;### Install compilation dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    build-essential &lt;span class="se"&gt;\
&lt;/span&gt;    libncurses5-dev &lt;span class="se"&gt;\
&lt;/span&gt;    bison &lt;span class="se"&gt;\
&lt;/span&gt;    flex &lt;span class="se"&gt;\
&lt;/span&gt;    libssl-dev &lt;span class="se"&gt;\
&lt;/span&gt;    libelf-dev &lt;span class="se"&gt;\
&lt;/span&gt;    gcc-5 g++-5 &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; update-alternatives &lt;span class="nt"&gt;--install&lt;/span&gt; /usr/bin/gcc gcc /usr/bin/gcc-5 100

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/linux&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a personal container version, just run the command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker build -t my-ubuntu:16.04 .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;if we launch sudo docker images, you should see  the following result&lt;/p&gt;

&lt;p&gt;kernel-builder-515:latest   9f311ec05f16        580MB          147MB    U&lt;br&gt;&lt;br&gt;
my-ubuntu:16.04             3aa5b81c120f        822MB          188MB    U&lt;br&gt;&lt;br&gt;
ubuntu:16.04                1f1a2d56de1d        195MB         46.5MB    U   &lt;/p&gt;

&lt;p&gt;You can find other Dockerfile examples at &lt;a href="https://github.com/ddupard/low-level-security-research" rel="noopener noreferrer"&gt;https://github.com/ddupard/low-level-security-research&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have followed all previous steps, you should be able to compile without issues by running these commands in a shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; ~/Desktop/KERNEL/4.7:/build &lt;span class="se"&gt;\&lt;/span&gt;
  my-ubuntu:16.04

make x86_64_defconfig

scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_DEBUG_INFO
scripts/config &lt;span class="nt"&gt;--disable&lt;/span&gt; CONFIG_DEBUG_INFO_REDUCED
scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_GDB_SCRIPTS
scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_DEBUG_KERNEL
scripts/config &lt;span class="nt"&gt;--disable&lt;/span&gt; CONFIG_RANDOMIZE_BASE

make olddefconfig
make scripts_gdb

make &lt;span class="nt"&gt;-j&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;et voila&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa52f4xs6l1dpoifdhshi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa52f4xs6l1dpoifdhshi.png" alt="kernel compilation" width="799" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Creating the runtime
&lt;/h2&gt;

&lt;p&gt;This step consists of two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieving and compiling BusyBox.&lt;/li&gt;
&lt;li&gt;Creating the &lt;code&gt;initramfs.cpio.gz&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike a complete Linux distribution that weighs gigabytes, BusyBox bundles essential utilities (ls, cat, sh, etc.) into a single binary executable.&lt;/p&gt;

&lt;p&gt;We start by creating a shell script (&lt;code&gt;build_busybox.sh&lt;/code&gt;) to download the BusyBox sources and compile them within Docker using &lt;code&gt;my-ubuntu:16.04&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;BUSYBOX_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.36.1"&lt;/span&gt;
&lt;span class="nv"&gt;BUSYBOX_TAR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"busybox-&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_VERSION&lt;/span&gt;&lt;span class="s2"&gt;.tar.bz2"&lt;/span&gt;
&lt;span class="nv"&gt;BUILD_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/busybox_build"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_TAR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Downloading BusyBox &lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_VERSION&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;
    wget &lt;span class="s2"&gt;"https://busybox.net/downloads/&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_TAR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;tar &lt;/span&gt;xvf &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_TAR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"busybox-&lt;/span&gt;&lt;span class="nv"&gt;$BUSYBOX_VERSION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

make defconfig
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/.*CONFIG_STATIC.*/CONFIG_STATIC=y/'&lt;/span&gt; .config

&lt;span class="c"&gt;### 4. Compilation&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Compilation of BusyBox..."&lt;/span&gt;
make &lt;span class="nt"&gt;-j&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
make &lt;span class="nb"&gt;install &lt;/span&gt;&lt;span class="nv"&gt;CONFIG_PREFIX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUILD_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"BusyBox compiled in : &lt;/span&gt;&lt;span class="nv"&gt;$BUILD_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then we launch the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; /build &lt;span class="se"&gt;\&lt;/span&gt;
  my-ubuntu:16.04 &lt;span class="se"&gt;\&lt;/span&gt;
  /bin/bash ./build_busybox.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the compilation fails with the following message indicating that wget and other executables are missing&lt;/p&gt;

&lt;p&gt;sudo docker run -it \&lt;br&gt;
  -v "$(pwd)":/build \&lt;br&gt;
  -w /build \&lt;br&gt;
  my-ubuntu:16.04 \&lt;br&gt;
  /bin/bash ./build_busybox.sh&lt;br&gt;
Téléchargement de BusyBox 1.36.1...&lt;br&gt;
./build_busybox.sh: line 11: wget: command not found&lt;br&gt;
tar: busybox-1.36.1.tar.bz2: Cannot open: No such file or directory&lt;br&gt;
tar: Error is not recoverable: exiting now&lt;/p&gt;

&lt;p&gt;so we need to modify the Dockerfile in order to include these new executables&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ubuntu:16.04&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    build-essential &lt;span class="se"&gt;\
&lt;/span&gt;    gcc &lt;span class="se"&gt;\
&lt;/span&gt;    make &lt;span class="se"&gt;\
&lt;/span&gt;    libncurses5-dev &lt;span class="se"&gt;\
&lt;/span&gt;    libssl-dev &lt;span class="se"&gt;\
&lt;/span&gt;    bc &lt;span class="se"&gt;\
&lt;/span&gt;    bison &lt;span class="se"&gt;\
&lt;/span&gt;    flex &lt;span class="se"&gt;\
&lt;/span&gt;    nano &lt;span class="se"&gt;\
&lt;/span&gt;    git &lt;span class="se"&gt;\
&lt;/span&gt;    cpio &lt;span class="se"&gt;\
&lt;/span&gt;    openssh-client &lt;span class="se"&gt;\
&lt;/span&gt;    wget &lt;span class="se"&gt;\
&lt;/span&gt;    bzip2 &lt;span class="se"&gt;\
&lt;/span&gt;    ca-certificates &lt;span class="se"&gt;\
&lt;/span&gt;    linux-headers-generic &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;


&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /opt&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;git clone https://github.com/radareorg/radare2 &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; radare2/sys/install.sh &lt;span class="nt"&gt;--install&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; radare2

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now we can recreate the container using &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker build -t my-ubuntu:16.04 .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;then we rebuild busybox with the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;:/build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-w&lt;/span&gt; /build &lt;span class="se"&gt;\&lt;/span&gt;
  my-ubuntu:16.04 &lt;span class="se"&gt;\&lt;/span&gt;
  /bin/bash ./build_busybox.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F694oirrooyyeo53sgqbe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F694oirrooyyeo53sgqbe.png" alt=" " width="799" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;however the compilation process wil fail with the following message&lt;/p&gt;

&lt;p&gt;CC      miscutils/mt.o&lt;br&gt;
  CC      miscutils/nandwrite.o&lt;br&gt;
  CC      miscutils/partprobe.o&lt;br&gt;
  CC      miscutils/raidautorun.o&lt;br&gt;
  CC      miscutils/readahead.o&lt;br&gt;
  CC      miscutils/runlevel.o&lt;br&gt;
  CC      miscutils/rx.o&lt;br&gt;
  CC      miscutils/seedrng.o&lt;br&gt;
miscutils/seedrng.c:45:24: fatal error: sys/random.h: No such file or directory&lt;/p&gt;

&lt;p&gt;it's because you are compiling a recent version of BusyBox with an old Ubuntu 16.04 base.&lt;br&gt;
in order to solve our problem, we will launch the following commands&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo docker ps -a&lt;br&gt;
in order to get the list of the last docker commands launched&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CONTAINER ID&lt;/th&gt;
&lt;th&gt;IMAGE&lt;/th&gt;
&lt;th&gt;COMMAND&lt;/th&gt;
&lt;th&gt;CREATED&lt;/th&gt;
&lt;th&gt;STATUS&lt;/th&gt;
&lt;th&gt;PORTS NAMES&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;49c7144e4dbb&lt;/td&gt;
&lt;td&gt;my-ubuntu:16.04&lt;/td&gt;
&lt;td&gt;"/bin/bash ./build_b…"&lt;/td&gt;
&lt;td&gt;13 minutes ago&lt;/td&gt;
&lt;td&gt;Exited (0) 10 minutes ago&lt;/td&gt;
&lt;td&gt;mystifying_mayer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;eb9d3d19f3a0&lt;/td&gt;
&lt;td&gt;58aacbfbda6f&lt;/td&gt;
&lt;td&gt;"/bin/bash ./build_b…"&lt;/td&gt;
&lt;td&gt;23 minutes ago&lt;/td&gt;
&lt;td&gt;Exited (0) 23 minutes ago&lt;/td&gt;
&lt;td&gt;wonderful_jemison&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;then&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker start 49c7144e4dbb
&lt;span class="nb"&gt;sudo &lt;/span&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; 49c7144e4dbb /bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to restart the docker environment  (root@49c7144e4dbb:/build#)&lt;br&gt;
then the following commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /build/busybox-1.36.1
&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/CONFIG_SEEDRNG=y/CONFIG_SEEDRNG=n/'&lt;/span&gt; .config

make clean
make &lt;span class="nt"&gt;-j&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;compilation should restart and go to the end.&lt;/p&gt;

&lt;p&gt;then we launch the following command to make the install&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;make install CONFIG_PREFIX="$(pwd)/../busybox_build"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;at the end a new directory should appear &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fyxsmkse0un5knc5tjd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5fyxsmkse0un5knc5tjd.png" alt=" " width="736" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that BusyBox has copiled, it's time to create initramfs.cpio.gz that sets up the file structure (&lt;code&gt;/proc&lt;/code&gt;, &lt;code&gt;/sys&lt;/code&gt;, etc.) &lt;/p&gt;

&lt;p&gt;we are going to create and lauch a new shell script (create_initramfs.sh)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;BUILD_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/busybox_build"&lt;/span&gt;
&lt;span class="nv"&gt;ROOTFS_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/initramfs_staging"&lt;/span&gt;

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOTFS_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOTFS_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUILD_DIR&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOTFS_DIR&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;

&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ROOTFS_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; proc sys dev etc/init.d

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt; &amp;gt; init
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
echo "--- Système démarré avec succès ---"
exec /bin/sh
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x init

find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-print0&lt;/span&gt; | cpio &lt;span class="nt"&gt;--null&lt;/span&gt; &lt;span class="nt"&gt;-ov&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;newc | &lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ../initramfs.cpio.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;at the end of its execution, we should see something like &lt;br&gt;
./bin/mknod&lt;br&gt;
./bin/more&lt;br&gt;
./bin/zcat&lt;br&gt;
./bin/pidof&lt;br&gt;
./bin/egrep&lt;br&gt;
./bin/watch&lt;br&gt;
./bin/link&lt;br&gt;
./bin/pwd&lt;br&gt;
./bin/dd&lt;br&gt;
./bin/netstat&lt;br&gt;
./bin/fgrep&lt;br&gt;
./bin/stty&lt;br&gt;
./bin/mt&lt;br&gt;
./bin/gunzip&lt;br&gt;
./proc&lt;br&gt;
./etc&lt;br&gt;
./etc/init.d&lt;br&gt;
./init&lt;br&gt;
5556 blocks&lt;/p&gt;

&lt;p&gt;and a new file in the root directory (initramfs.cpio.gz)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyg3s2h7jf12x4uze6p9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffyg3s2h7jf12x4uze6p9.png" alt=" " width="736" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;to check that everything is fine , we are going to launch the VM using the following command&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;qemu-system-x86_64 \&lt;br&gt;
  -kernel ./4.7/arch/x86/boot/bzImage \&lt;br&gt;
  -initrd ./initramfs.cpio.gz \&lt;br&gt;
  -append "console=ttyS0 nokaslr" \&lt;br&gt;
  -nographic &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and something like below should appear&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2hxpzfg0zra09ijqy444.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2hxpzfg0zra09ijqy444.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;if it happens , congrats your environment is working now&lt;/p&gt;
&lt;h2&gt;
  
  
  3) Debugging setup
&lt;/h2&gt;

&lt;p&gt;To debug the kernel, the base tool is GDB, but it isn't very user-friendly. The idea here is to use VS Code's overlay for GDB.&lt;/p&gt;

&lt;p&gt;First, ensure you compile with debug options in your &lt;code&gt;compile_4.7.sh&lt;/code&gt; script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_DEBUG_INFO
./scripts/config &lt;span class="nt"&gt;--disable&lt;/span&gt; CONFIG_DEBUG_INFO_REDUCED
./scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_GDB_SCRIPTS
./scripts/config &lt;span class="nt"&gt;--enable&lt;/span&gt; CONFIG_DEBUG_KERNEL
./scripts/config &lt;span class="nt"&gt;--disable&lt;/span&gt; CONFIG_RANDOMIZE_BASE

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;file ./4.7/vmlinux&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(You should see a line containing "with debug_info")&lt;/p&gt;

&lt;p&gt;Then, launch QEMU with the &lt;code&gt;-s&lt;/code&gt; and &lt;code&gt;-S&lt;/code&gt; options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-s&lt;/code&gt;: Opens a GDB server on &lt;code&gt;tcp::1234&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-S&lt;/code&gt;: Freezes QEMU at the first instruction.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;qemu-system-x86_64 \&lt;br&gt;
  -kernel ./4.7/arch/x86/boot/bzImage \&lt;br&gt;
  -initrd ./initramfs.cpio.gz \&lt;br&gt;
  -append "console=ttyS0 nokaslr" \&lt;br&gt;
  -nographic \&lt;br&gt;
  -s -S&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In VS Code, install the &lt;strong&gt;C/C++&lt;/strong&gt; extension from Microsoft and create a &lt;code&gt;.vscode/launch.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"(gdb) Attacher au Kernel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cppdbg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}/4.7/vmlinux"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"miDebuggerServerAddress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"localhost:1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"miDebuggerPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/usr/bin/gdb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"setupCommands"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"-enable-pretty-printing"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Debugging Workflow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Launch QEMU (using your script with &lt;code&gt;-s -S&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;In VS Code, go to the 4.7 directory and launch the "Debug Kernel LKM" configuration.&lt;/li&gt;
&lt;li&gt;This triggers the kernel to start. You can now set breakpoints, view registers, and use the debug console to launch commands like the following&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;-exec info functions&lt;/code&gt;&lt;br&gt;
&lt;code&gt;-exec p/x $rax&lt;/code&gt;&lt;br&gt;
&lt;code&gt;-exec monitor xp/512gx  0x4786000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsnsf7tq0aehypb1i6l3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffsnsf7tq0aehypb1i6l3.png" alt=" " width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: If you load an LKM, you must load the symbol file and tell GDB where the source files are located using:&lt;/em&gt;&lt;br&gt;
&lt;code&gt;-exec add-symbol-file /path/to/my_attack.ko ...&lt;/code&gt;&lt;br&gt;
&lt;code&gt;-exec set substitute-path ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Happy kernel debugging!&lt;/p&gt;


&lt;h2&gt;
  
  
  Appendix: Automation Script
&lt;/h2&gt;

&lt;p&gt;To make the environment setup more efficient, I use a script (&lt;code&gt;run_qemu.sh&lt;/code&gt;) to quickly switch between different kernel versions and automate the LKM injection process for the 5.15 LTS kernel.&lt;/p&gt;

&lt;p&gt;You can save the following code into a file named &lt;code&gt;run_qemu.sh&lt;/code&gt; in your &lt;code&gt;~/Desktop/KERNEL&lt;/code&gt; directory. Make sure to give it execution permissions with &lt;code&gt;chmod +x run_qemu.sh&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;# This script runs on the host (Ubuntu) in ~/Desktop/KERNEL&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Desktop/KERNEL"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------------------------"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"  COGNITIVE FIREWALL LAB - TEST ENVIRONMENT"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------------------------"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Select the kernel version to test:"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"1) Kernel 4.7  (Dirty COW vulnerable)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"2) Kernel 4.8  (Intro XDP)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"3) Kernel 4.9  (Dirty COW patched)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"4) Kernel 5.15 (LTS)"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"q) Quit"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"-------------------------------------------------------"&lt;/span&gt;

&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Your choice [1-4] : "&lt;/span&gt; choice

&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$choice&lt;/span&gt; &lt;span class="k"&gt;in
    &lt;/span&gt;1&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"4.7"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;KERNEL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./4.7/arch/x86/boot/bzImage"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    2&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"4.8"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;KERNEL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./4.8/arch/x86/boot/bzImage"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    3&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"4.9"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;KERNEL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./4.9/arch/x86/boot/bzImage"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;        
    4&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"5.15"&lt;/span&gt;
        &lt;span class="nv"&gt;KERNEL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./5.15/arch/x86/boot/bzImage"&lt;/span&gt;
        &lt;span class="nv"&gt;LKM2_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./lkm/poc/my_attack.ko"&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LKM2_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Building initramfs for Kernel 5.15..."&lt;/span&gt;
            &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .initramfs_root
            &lt;span class="nb"&gt;cd&lt;/span&gt; .initramfs_root
            zcat ../initramfs.cpio.gz | cpio &lt;span class="nt"&gt;-idmv&lt;/span&gt; &amp;amp;&amp;gt;/dev/null
            &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="s2"&gt;"../&lt;/span&gt;&lt;span class="nv"&gt;$LKM2_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;

            &lt;span class="c"&gt;# Automatic LKM injection script&lt;/span&gt;
            &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; init
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev 2&amp;gt;/dev/null
if [ -f /my_attack.ko ]; then insmod /my_attack.ko; fi
exec /bin/sh
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;            &lt;span class="nb"&gt;chmod&lt;/span&gt; +x init
            find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-print0&lt;/span&gt; | cpio &lt;span class="nt"&gt;--null&lt;/span&gt; &lt;span class="nt"&gt;-ov&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;newc 2&amp;gt;/dev/null | &lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ../initramfs.cpio.gz
            &lt;span class="nb"&gt;cd&lt;/span&gt; ..
            &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; .initramfs_root
        &lt;span class="k"&gt;fi
        &lt;/span&gt;qemu-system-x86_64 &lt;span class="nt"&gt;-kernel&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KERNEL_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-initrd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Desktop/KERNEL/initramfs.cpio.gz"&lt;/span&gt; &lt;span class="nt"&gt;-nographic&lt;/span&gt; &lt;span class="nt"&gt;-append&lt;/span&gt; &lt;span class="s2"&gt;"console=ttyS0 loglevel=7 nosmep nosmap nokaslr"&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt;
        &lt;span class="nb"&gt;exit &lt;/span&gt;0
        &lt;span class="p"&gt;;;&lt;/span&gt;
    q&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;0 &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Invalid choice"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1 &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;

&lt;span class="c"&gt;# Launch QEMU for versions 1, 2, 3&lt;/span&gt;
qemu-system-x86_64 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-kernel&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$KERNEL_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-initrd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/Desktop/KERNEL/initramfs.cpio.gz"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-nographic&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-append&lt;/span&gt; &lt;span class="s2"&gt;"console=ttyS0 nokaslr loglevel=7"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>linux</category>
      <category>kernel</category>
      <category>security</category>
    </item>
  </channel>
</rss>
