# Kernel Dev Blog 2 -- In Code ## 4/5/2020 I was able to get the Kernel compiled and loaded yesterday following the guide with relatively no problems. I had no idea that you could change your installed Kernely version at boot time after it is comiled and then `make module_install install` The first chapter in the Linux Device Drivers book was also great, even from a development philosphy standpoint of "mechanism" vs "policy". I have not seen that dilineation before and I believe that principle could apply to a lot of things in general software engineering. For example the separation of concerns across layers in an MVC web architecture, where mechanism of models or services should not be concerned with a higher level layers policy around user authorization). Before moving into the rest of the guide for coding I took a look through the Kernel to spelunk for various things, which landed me in the `Documentation/process/` folder where I have been reading a lot. --- ## /Documentation/process/1.Intro.rst Linux is over 8 million lines of code and over 1000 contributors to each release Getting code into mainline is important for more long term reasons that short: - Available to be improved by others - Peer review from others breeds success (isolationism is weakness) - Available on all Linux platforms - If other developers make breaking changes, they must fix them - Influence over direction of Linux - Other third-party may take your spot GPL 2 License -- _I am not a lawyer but I need to understand this_ ## /Documentation/process/2.Process.rst ### Rough Release Cycle - New releases occur every 2-3 months - Linus opens a 2 week period for maintainers to submit patches - He approves them into the mainline and after 2 weeks forms a "version-rc" kernely (5.6-rc1) - Only patches come in to stabilize release candidate at this time for 6 to 9 weeks - After iterations of stability the version is released as "version" stable release (5.6 stable release) - From there it goes to the "stable team" to put in more stability patches into an "update release" (5.6.1) etc ### Patch Lifecycle - Design - requirements laid out - Early Review - mailing list reviews - Wider Review - accepted by subsystem maintainer into subsystem tree and '-next' tree - Merging into Mainline - linus does this during merge window - Stable release - resolving issues when exposed to more users - Long Term maintenance - be responsible and available to support it ### Subsystem Trees and Trust Linus merges all main patches into core, but he has a lieutenant system to make it sane Kernel is logically broken into: networking, specific architector support, memory management, video devices etc Subsystem maintainers are gatekeepers to code and they merge in patches into a large patch ### Next Trees Patches are also merged into the "-next" tree so you can use this to see if your code may conflicts with other unmerged patches `http://www.kernel.org/pub/linux/kernel/next/` ### Staging Trees I enjoyed looking through `drivers/staging/` where drivers that are being worked on for upcoming hardware have been merged and do compile but are not in the core yet. They are required to have a "TODO" file in them with things they need to change. Greg Kroah-Hartman currently maintains the staging tree. I cloned from his repo. ### Tools GIT, Mercerial, Quilt Quilt is a patch management system (not source code management system). It does not track history but tracks a set of changes against evolving codebase ### Mailing Lists http://vger.kernel.org/vger-lists.html Beware of overwhelming email `linux-kernel` is the core list and to survive: - send list to separate folder - dont try and follow all conversations, filter on topics of interest - dont feed the trolls - respond preserving Cc: header for all involved - search the list archives (and internet) before asking questions - do not "top-post" (putting answer above quoted text) - ask on the correct mailing list Best place to look for lists are the MAINTAINERS file packaged in the kernel source code Ones of interest to me could be: - linux-kernel - linux-newbie - kernel-janitors ### Getting Started > Beginning with a large project can be intimidating; one often wants to test the waters with something smaller first > some developers jump into the creation of patches fixing spelling errors or minor coding style issues > Unfortunately, such patches create a level of noise which is distracting for the development community as a whole > increasingly, they are looked down upon and will not get the sort of reception they wish for Andrew Morton gives this advice for aspiring kernel developers > The #1 project for all kernel beginners should surely be "make sure that the kernel runs perfectly at all times on all machines which you can lay your hands on". Usually the way to do this is to work with others on getting things fixed up (this can require persistence!) but that's fine - it's a part of kernel development. > - (http://lwn.net/Articles/283982/) Look at current list of regressions and open bugs to resolve _pausing here to do some coding practice_ Next is /Documentation/process/3.Early-stage.rst --- ## Adding some Code In `drivers/net/ethernet/intel/e1000/e1000_main.c` I placed a `printk` as the guide stated in the `e1000_probe` function that is called with the device is initalized This driver is used on the VM version ```c static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *netdev; struct e1000_adapter *adapter = NULL; struct e1000_hw *hw; printk(KERN_DEBUG "I AM INVINCIBLE!!!\n"); static int cards_found; static int global_quad_port_a; /* global ksp3 port a indication */ ``` When compiling I received the following warning: ```text drivers/net/ethernet/intel/e1000/e1000_main.c:928:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] static int cards_found; ^~~~~~ ``` I learned that a coding `ISO C90 forbids mixed declarations and code` that there is C Standard that is enforced at the compiler level \ ? / so I switched it around to ```c static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct net_device *netdev; struct e1000_adapter *adapter = NULL; struct e1000_hw *hw; static int cards_found; static int global_quad_port_a; /* global ksp3 port a indication */ int i, err, pci_using_dac; u16 eeprom_data = 0; u16 tmp = 0; u16 eeprom_apme_mask = E1000_EEPROM_APME; int bars, need_ioport; bool disable_dev = false; printk(KERN_DEBUG "I AM INVINCIBLE!!!\n"); /* do not allocate ioport bars when not needed */ need_ioport = e1000_is_need_ioport(pdev); if (need_ioport) { ``` And it compiled. I rebooted and searched and found the printed line ```shell $ dmesg | grep -C5 INVINCIBLE [ 7.218840] ahci 0000:00:0d.0: SSS flag set, parallel bus scan disabled [ 7.219245] ahci 0000:00:0d.0: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA mode [ 7.219655] ahci 0000:00:0d.0: flags: 64bit ncq stag only ccc [ 7.220873] e1000: Intel(R) PRO/1000 Network Driver - version 7.3.21-k8-NAPI [ 7.221182] e1000: Copyright (c) 1999-2006 Intel Corporation. [ 7.221454] I AM INVINCIBLE!!! [ 7.229828] scsi host2: ahci [ 7.230075] ata3: SATA max UDMA/133 abar m8192@0xf1806000 port 0xf1806100 irq 21 [ 7.261574] usb 1-1: new full-speed USB device number 2 using ohci-pci [ 7.304187] cryptd: max_cpu_qlen set to 1000 [ 7.316483] AVX2 version of gcm_enc/dec engaged. ``` And also in the kernel log ```shell $ grep -C5 INVINCIBLE /var/log/kern.log Apr 5 14:54:50 doomkern kernel: [ 7.218840] ahci 0000:00:0d.0: SSS flag set, parallel bus scan disabled Apr 5 14:54:50 doomkern kernel: [ 7.219245] ahci 0000:00:0d.0: AHCI 0001.0100 32 slots 1 ports 3 Gbps 0x1 impl SATA mode Apr 5 14:54:50 doomkern kernel: [ 7.219655] ahci 0000:00:0d.0: flags: 64bit ncq stag only ccc Apr 5 14:54:50 doomkern kernel: [ 7.220873] e1000: Intel(R) PRO/1000 Network Driver - version 7.3.21-k8-NAPI Apr 5 14:54:50 doomkern kernel: [ 7.221182] e1000: Copyright (c) 1999-2006 Intel Corporation. Apr 5 14:54:50 doomkern kernel: [ 7.221454] I AM INVINCIBLE!!! Apr 5 14:54:50 doomkern kernel: [ 7.229828] scsi host2: ahci Apr 5 14:54:50 doomkern kernel: [ 7.230075] ata3: SATA max UDMA/133 abar m8192@0xf1806000 port 0xf1806100 irq 21 Apr 5 14:54:50 doomkern kernel: [ 7.261574] usb 1-1: new full-speed USB device number 2 using ohci-pci Apr 5 14:54:50 doomkern kernel: [ 7.304187] cryptd: max_cpu_qlen set to 1000 Apr 5 14:54:50 doomkern kernel: [ 7.316483] AVX2 version of gcm_enc/dec engaged. ``` `printk` is a Linux Kernel API function that lets us print to the kernel log. Apparently `printf` is not available in the Linux Kernel mode `dmesg` is "dmesg - print or control the kernel ring buffer". What is the Kernel Ring Buffer? ### The Kernel Ring Buffer The `syslog` daemon is what writes to log files, but this daemon is not available the beginning boot of the kernel since it iself is booted from the kernel. As a result logs from `printk` are stored in a memory buffer and when the syslog daemon starts up it collects that buffer and writes it to a proper log file. `dmesg` I think is just reading and writing to this buffer.