{"id":627,"date":"2022-09-19T12:53:16","date_gmt":"2022-09-19T19:53:16","guid":{"rendered":"https:\/\/sysprogs.com\/tutorials\/?p=627"},"modified":"2022-09-19T12:53:16","modified_gmt":"2022-09-19T19:53:16","slug":"using-code-explorer-to-navigate-the-linux-kernel","status":"publish","type":"post","link":"https:\/\/sysprogs.com\/VisualKernel\/tutorials\/codeexplorer\/","title":{"rendered":"Using Code Explorer to Navigate the Linux Kernel"},"content":{"rendered":"<p>This tutorial shows how to use Code Explorer to conveniently navigate the Linux kernel source using VisualKernel.<\/p>\n<p>We will create a basic kernel module that creates a file in <strong>\/proc <\/strong>and implements the callback functions required by the <strong>proc_create()<\/strong> API. We will then use the Code Explorer to quickly find other implementations of similar callbacks, and also understand the context where they are used.<\/p>\n<p>Before you begin, install Visual Studio and VisualKernel 4.0 or later.<\/p>\n<ol>\n<li>Start Visual Studio and locate the VisualKernel Linux Kernel Module Project Wizard:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/01-newprj-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-628\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/01-newprj-1.png\" alt=\"\" width=\"1014\" height=\"675\" \/><\/a><\/li>\n<li>Enter the name and location for your project: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/02-codeexp.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-629\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/02-codeexp.png\" alt=\"\" width=\"1014\" height=\"675\" \/><\/a><\/li>\n<li>In this tutorial we will use the project template for the <strong>\/proc<\/strong> file, however any other template will work as well:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/03-procfile.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-630\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/03-procfile.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Pick the target system where you would like to run the module. In this tutorial we will use <a href=\"https:\/\/sysprogs.com\/VisualKernel\/documentation\/vms\/\">a pre-built Ubuntu 22.04 VM<\/a>, however you can configure VisualKernel to target any other <a href=\"https:\/\/sysprogs.com\/VisualKernel\/documentation\/vms\">supported VM<\/a> or a physical machine: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/04-vm.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-631\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/04-vm.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>VisualKernel will suggest storing the source files for the module on the Windows machine and uploading them during build. Proceed with the suggested settings:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/05-sources.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-632\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/05-sources.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Select the debug settings that match your target and click &#8220;Finish&#8221; to generate a project: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/06-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-633\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/06-debug.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>Once the project is created, you can build it using the <strong>Build-&gt;Build Solution<\/strong> command.\u00a0 Depending on the kernel version you are using, you may need to replace the <strong>proc_ops<\/strong> structure with <strong>file_operations<\/strong>:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/07-build.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-634\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/07-build.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Set a breakpoint in the init() function and press F5 to begin debugging. The breakpoint will trigger, allowing you to step through the code:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/08-bkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-635\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/08-bkpt.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Press F5 to continue debugging. We will now test the created proc file by opening an SSH window connecting to the target: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/09-ssh.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-636\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/09-ssh.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Run the &#8220;sudo cat \/proc\/&lt;Project Name&gt;&#8221; command and make sure that the output shows the current time: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/10-cat.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-637\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/10-cat.png\" alt=\"\" width=\"905\" height=\"411\" \/><\/a><\/li>\n<li>While the debugger could be useful in understanding how this particular example works, it requires physically stepping through every relevant scenario, which could be slow. Static analysis tools like Code Explorer, on the other hand, allow quickly navigating the kernel code without having to step through it. Before we demonstrate it, make sure that the kernel sources are shown in the Solution Explorer:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/11-files.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-638\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/11-files.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a>If not, locate the kernel reference under the &#8220;Referenced Kernel&#8221; node inside the project, and double-click on it to load the sources.<\/li>\n<li>Go to the initialization of the <strong>proc_lseek<\/strong> field in the main file and click the &#8220;Go to Code Explorer&#8221; button in the top right corner of the text editor:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/13-seek-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-649\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/13-seek-1.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Click the <strong>Show Details<\/strong> button in the Code Explorer window to show the <strong>details<\/strong> view at the bottom:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/14-details.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-641\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/14-details.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a>Note how the <strong>Code Explorer Details<\/strong> view shows:\n<ul>\n<li>All functions throughout the kernel sources, &#8220;implementing&#8221; the <strong>proc_lseek<\/strong> field (i.e. functions that are ever assigned to that field).<\/li>\n<li>The functions &#8220;calling&#8221; the field (i.e. calling the function pointed by the field)<\/li>\n<li>The type returned by the function<\/li>\n<\/ul>\n<\/li>\n<li>You can quickly navigate the detail tree to find out that:\n<ol>\n<li>The <strong>proc_ops::proc_lseek<\/strong> field is &#8216;called&#8217; by the <strong>proc_reg_llseek()<\/strong> function.<\/li>\n<li>The <strong>proc_reg_llseek()<\/strong> function is indeed assigned to the <strong>file_operations::llseek<\/strong> field.<\/li>\n<li>The <strong>file_operations::llseek()<\/strong> field is access by multiple functions, particularly by <strong>vfs_llseek()<\/strong>.<\/li>\n<li>The <strong>vfs_llseek()<\/strong> is called by <strong>__do_sys_llseek()<\/strong> that implements the <strong>llseek<\/strong> system call.<\/li>\n<\/ol>\n<p>The Code Explorer relies on a heavily optimized code database generated by the VisualKernel&#8217;s Clang IntelliSense engine and can find those relations almost instantly once the kernel has been indexed (or if you are using a pre-indexed kernel image).<br \/>\n<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/15-usage.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-642\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/15-usage.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Similarly, you can navigate the &#8220;Implementing functions&#8221; view of <strong>proc_ops::proc_lseek<\/strong> to find existing implementations in the kernel. E.g. locate and navigate to <strong>kpagecount_read()<\/strong>, then use Code Jumps to find where it is assigned:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/16-kpagecount.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-643\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/16-kpagecount.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>Use Code Jumps again to quickly find out that it&#8217;s used by the <strong>\/proc\/kpagecount<\/strong> file: <a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/17-fn.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-644\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/17-fn.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>You can set a breakpoint in <strong>kpagecount_read()<\/strong> and try running &#8220;sudo cat \/proc\/kpagecount&#8221; to make sure the function gets invoked. VisualKernel will let you step through that function as if it was a part of your own project:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/18-step.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-645\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/18-step.png\" alt=\"\" width=\"1340\" height=\"825\" \/><\/a><\/li>\n<li>You can also use Code Explorer to quickly navigate within large files. Go to the implementation of the <strong>seq_lseek()<\/strong> function and take a note of the huge size of <strong>seq_lseek.c<\/strong> file:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/19-seq.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-646\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/19-seq.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a>You can get a good overview of the file structure by switching the Code Explorer to the outline mode and selecting the desired level of detail. In this example, Code Explorer shows the additional variables created by the <strong>EXPORT_SYMBOL()<\/strong> macro. In order to hide them, Shift+click on the &#8220;Code&#8221; checkbox under the type filter, automatically unchecking all other items. Then, disable the &#8220;group method implementations&#8221; checkbox and enable the display of blocks inside functions:<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/20-code.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-647\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/20-code.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<li>You can now conveniently view all functions defined in this file, and even see the basic outline of their contents (e.g. if\/while blocks):<a href=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/21-infunc.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-648\" src=\"https:\/\/sysprogs.com\/tutorials\/wp-content\/uploads\/2022\/09\/21-infunc.png\" alt=\"\" width=\"1340\" height=\"824\" \/><\/a><\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use Code Explorer to conveniently navigate the Linux kernel source using VisualKernel. We will create<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59],"tags":[60],"_links":{"self":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/627"}],"collection":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/comments?post=627"}],"version-history":[{"count":2,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/627\/revisions"}],"predecessor-version":[{"id":651,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/posts\/627\/revisions\/651"}],"wp:attachment":[{"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/media?parent=627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/categories?post=627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sysprogs.com\/tutorials\/wp-json\/wp\/v2\/tags?post=627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}