Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ass:cursuri:04:theory:00 [2024/08/09 16:08]
radu.mantu
ass:cursuri:04:theory:00 [2024/08/15 19:20] (current)
radu.mantu [QEMU setup for kernel development]
Line 48: Line 48:
 $ chroot rootfs /bin/bash $ chroot rootfs /bin/bash
 </​code>​ </​code>​
- 
  
 === The Linux kernel === === The Linux kernel ===
Line 54: Line 53:
 This step is very straightforward. Just clone the Linux repo (with depth=1 to squash the commit history, reducing the amount of downloaded data) and compile it for the **arm64** target. Notice in the instructions below that we also specify ''​kvm_guest.config''​. We don't plan to perform a //perfect// emulation of arm64 devices but instead be transparent to the kernel and let it know that it's running in a virtual environment. This permits us to cut some corners and save some crucial clock cycles, increasing the performance of the VM. This is also the main difference between //​emulation//​ and //​simulation//​. This step is very straightforward. Just clone the Linux repo (with depth=1 to squash the commit history, reducing the amount of downloaded data) and compile it for the **arm64** target. Notice in the instructions below that we also specify ''​kvm_guest.config''​. We don't plan to perform a //perfect// emulation of arm64 devices but instead be transparent to the kernel and let it know that it's running in a virtual environment. This permits us to cut some corners and save some crucial clock cycles, increasing the performance of the VM. This is also the main difference between //​emulation//​ and //​simulation//​.
  
-Optionally, you can enable the generation of debug symbols and **gdb** helper scripts. The config options are ''​CONFIG_DEBUG_INFO_DWARF5''​ and ''​CONFIG_GDB_SCRIPTS'',​ found under ''​Kernel hacking -> Compile-time checks and compiler options''​.+Optionally, you can enable the generation of debug symbols and **gdb** helper scripts. The config options are ''​CONFIG_DEBUG_INFO_DWARF5''​ and ''​CONFIG_GDB_SCRIPTS'',​ found under ''​Kernel hacking -> Compile-time checks and compiler options''​. Also, make sure ''​CONFIG_DEBUG_INFO_REDUCED''​ is disabled so that the compiler will generate debug info for //​structures//​.
  
 <code bash> <code bash>
Line 85: Line 84:
 Unfortunately,​ the server does not have any foolproof method of inferring the structure of the project. For example, it has no idea whether you are using the //arm64// or the //x86// definition of a function. Luckily for us, the Linux build system contains a script that's able to generate a file names ''​compile_commands.json''​. This file contains all compiler invocations used during the boot and can deduce include paths, compiled source, macro definitions,​ etc. The language server will automatically load it and generate indices for the compiled source code. Unfortunately,​ the server does not have any foolproof method of inferring the structure of the project. For example, it has no idea whether you are using the //arm64// or the //x86// definition of a function. Luckily for us, the Linux build system contains a script that's able to generate a file names ''​compile_commands.json''​. This file contains all compiler invocations used during the boot and can deduce include paths, compiled source, macro definitions,​ etc. The language server will automatically load it and generate indices for the compiled source code.
  
-Note that this script only forks for the Linux kernel. If you want to generate ''​compile_commands.json''​ for other projects, consider using [[https://​github.com/​rizsotto/​Bear|Bear]]. This is a tool that hooks the ''​exec()''​ family of library calls via LD_PRELOAD hooking in order to extract the command arguments.+<code bash> 
 +linux$ ./​scripts/​clang-tools/​gen_compile_commands.py 
 +</​code>​ 
 + 
 +Note that this script only works for the Linux kernel. If you want to generate ''​compile_commands.json''​ for other projects, consider using [[https://​github.com/​rizsotto/​Bear|Bear]]. This is a tool that hooks the ''​exec()''​ family of library calls via LD_PRELOAD hooking in order to extract the command arguments
 + 
 +Also, for such a large codebase, expect the language server to take up //a lot// of your CPU when you first open your editor, while doing the indexing (usually in a ''​.cache/''​ directory).
 </​note>​ </​note>​
  
Line 100: Line 105:
  
 # boot up the VM # boot up the VM
-qemu-system-aarch64 ​                                                  ​+qemu-system-aarch64 ​                    ​
-    -machine virt                                                     ​+    -machine virt                       ​
-    -cpu cortex-a53 ​                                                  ​+    -cpu cortex-a53 ​                    ​
-    -smp 1                                                            +    -smp 1                              
-    -m 512M                                                           ​+    -m 512M                             ​
-    -nographic ​                                                       +    -nographic ​                         
-    -kernel linux/​arch/​arm64/​boot/​Image ​                              ​\+    -kernel linux/​arch/​arm64/​boot/​Image \
     -virtfs local,​path=${WS_DIR}/​rootfs,​mount_tag=rootfs,​security_model=passthrough,​id=rootfs,​multidevs=remap \     -virtfs local,​path=${WS_DIR}/​rootfs,​mount_tag=rootfs,​security_model=passthrough,​id=rootfs,​multidevs=remap \
     -append "​root=rootfs rootfstype=9p rootflags=trans=virtio,​version=9p2000.L rw console=ttyAMA0"​     -append "​root=rootfs rootfstype=9p rootflags=trans=virtio,​version=9p2000.L rw console=ttyAMA0"​
Line 119: Line 124:
   * ''​kernel'':​ Pretty self-explanatory. It's the kernel image that will be loaded.   * ''​kernel'':​ Pretty self-explanatory. It's the kernel image that will be loaded.
   * ''​virtfs'':​ This options specifies virtual storage device based on [[https://​www.kernel.org/​doc/​html/​latest/​filesystems/​9p.html|9p]] remote filesystem protocol. Using this instead of a disk image (like the one you had to create with **partx** in the second session) can be chalked up to personal preference. With 9p you can manipulate the guest filesystem from the host while the VM is running. If we used a disk image, we'd have to double mount it to obtain the same functionality and this would lead to corruptions with //100% certainty// due to the lack of synchronization mechanisms at the VFS driver level (between host and guest kernels). For more information regarding it's key-value list of arguments, check out the [[https://​wiki.qemu.org/​Documentation/​9psetup|documentation]].   * ''​virtfs'':​ This options specifies virtual storage device based on [[https://​www.kernel.org/​doc/​html/​latest/​filesystems/​9p.html|9p]] remote filesystem protocol. Using this instead of a disk image (like the one you had to create with **partx** in the second session) can be chalked up to personal preference. With 9p you can manipulate the guest filesystem from the host while the VM is running. If we used a disk image, we'd have to double mount it to obtain the same functionality and this would lead to corruptions with //100% certainty// due to the lack of synchronization mechanisms at the VFS driver level (between host and guest kernels). For more information regarding it's key-value list of arguments, check out the [[https://​wiki.qemu.org/​Documentation/​9psetup|documentation]].
-  * ''​append'':​ The command line arguments for the kernel.+  * ''​append'':​ The command line arguments for the kernel. Check [[https://​www.kernel.org/​doc/​html/​v4.14/​admin-guide/​kernel-parameters.html|this]] out for more kernel cli arguments.
     * ''​root=rootfs'':​ The rootfs device, it's value must match that of the ''​mount_tag''​ attribute from the previous flag.     * ''​root=rootfs'':​ The rootfs device, it's value must match that of the ''​mount_tag''​ attribute from the previous flag.
     * ''​rootfstype=9p'':​ Informs the kernel what the backing storage device for the rootfs will be.     * ''​rootfstype=9p'':​ Informs the kernel what the backing storage device for the rootfs will be.
Line 133: Line 138:
 Some terminal emulators such as [[https://​github.com/​kovidgoyal/​kitty|kitty]] support custom ''​TERM''​ values such as **xterm-kitty** but most shells won't have any idea how to particularize the output for it. Stick to **xterm** :p Some terminal emulators such as [[https://​github.com/​kovidgoyal/​kitty|kitty]] support custom ''​TERM''​ values such as **xterm-kitty** but most shells won't have any idea how to particularize the output for it. Stick to **xterm** :p
 ---- ----
-If the VM doesn'​t accept your root login password even after specifically setting it from **chroot** via **passwd**, make sure you're running the script with **sudo**. When debootstrapping the rootfs, the file owner was set to //root//, meaning that your unprivileged user won't have read access to ''/​etc/​shadow''​ that has ''​rw----''​ permissions. As a result, ''​systemd-login''​ won't be able to validate your password against its stored cryptographic hash. Though I agree, it could be a bit more verbose about that fact :/+If the VM doesn'​t accept your root login password even after specifically setting it from **chroot** via **passwd**, make sure you're running the script with **sudo**. When debootstrapping the rootfs, the file owner was set to //root//, meaning that your unprivileged user won't have read access to ''/​etc/​shadow''​ that has ''​rw%%----%%''​ permissions. As a result, ''​systemd-login''​ won't be able to validate your password against its stored cryptographic hash. Though I agree, it could be a bit more verbose about that fact :/
 </​note>​ </​note>​
ass/cursuri/04/theory/00.1723208895.txt.gz · Last modified: 2024/08/09 16:08 by radu.mantu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0