{"id":369,"date":"2024-04-29T15:32:30","date_gmt":"2024-04-29T13:32:30","guid":{"rendered":"https:\/\/bowfinger.de\/blog\/?p=369"},"modified":"2024-04-29T15:44:37","modified_gmt":"2024-04-29T13:44:37","slug":"working-on-ldd3s-tiny-tty-example","status":"publish","type":"post","link":"https:\/\/bowfinger.de\/blog\/2024\/04\/working-on-ldd3s-tiny-tty-example\/","title":{"rendered":"Working on LDD3&#8217;s tiny tty example"},"content":{"rendered":"\n<p>A while back I started tipping my toes into Linux Kernel module development. Mainly, to understand a driver for a data capture card I got to work with (or for, I believe).<\/p>\n\n\n\n<p>Well, there is a go-to reference: the book <em>Linux Device Drivers<\/em>, 3rd Edition by Corbet, Rubini and Kroah-Hartman (from now on LDD3).<\/p>\n\n\n\n<p>It&#8217;s great, it explains a lot and <a href=\"https:\/\/resources.oreilly.com\/examples\/9780596005900\/\">contains lots of hands-on example code<\/a>, too. But, unfortunately it refers to the 2.6 Linux kernel. We&#8217;re at 6.8 at the time of writing this. So it&#8217;s a bit outdated.<\/p>\n\n\n\n<p>No worries though, FOSS is a beautiful beast, and <a href=\"https:\/\/github.com\/martinezjavier\/ldd3\">people have taken the example modules and updated them<\/a>. Around version 5.15 that is. And things have changed again &#8211; at least for <code>tty<\/code> it seems.<\/p>\n\n\n\n<p>There is a <a href=\"https:\/\/github.com\/martinezjavier\/ldd3\/pull\/86\">pull request to make it 6.x compatible<\/a>, but &#8230; it&#8217;s almost a year old by now, and it seems incomplete. Yet, it was a really great thing to come across at the start of this journey, because it restored my sanity.<\/p>\n\n\n\n<p>So, here&#8217;s my go at the tiny tty example driver and I hope I can finish it up into something that works with a 6.x Linux kernel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Things have changed<\/h2>\n\n\n\n<p>Using static major\/minor numbers is discouraged, or at least, made easier to avoid in more recent kernel versions (feels like since 4.x or so). So, some functions used in LDD3&#8217;s examples simply don&#8217;t exist anymore.<\/p>\n\n\n\n<p><code>alloc_tty_driver<\/code> is now superseeded by <code>tty_alloc_driver<\/code> (okay, that re-naming is kind of evil). And while the former only bothered about the number of supported ports, the latter wants flags, too. So, it looks like the returned struct of type <code>tty_driver<\/code> already contains a lot of entries when <code>tty_alloc_driver<\/code> is done with it.<\/p>\n\n\n\n<p>I&#8217;ve refrained from using the <code>TTY_DRIVER_NO_DEVFS<\/code> flag, because I think dynamic stuff is always nice, so <code>TTY_DRIVER_DYNAMIC_DEV<\/code> it is.<\/p>\n\n\n\n<p><code>tty_driver-&gt;owner<\/code> is not supposed to be set anymore, according to <a href=\"https:\/\/lkml.org\/lkml\/2009\/1\/26\/342\">this old&#8217;ish LKLM post<\/a>. Same goes for <code>-&gt;major<\/code> (see <code>tty_alloc_driver<\/code>).<\/p>\n\n\n\n<p>The module is not put down anymore by <code>put_tty_driver<\/code> but by <code>tty_driver_kref_put<\/code> which seemingly also handles references in <code>proc<\/code> (I&#8217;ve run into issues that the <code>proc<\/code> entry was not removed after <code>rmmod<\/code>ing the module and hence, on the next try <code>insmod<\/code> was complaining).<\/p>\n\n\n\n<p>I mention this, because LDD3&#8217;s <code>static void __exit tiny_exit(void)<\/code> spends two thirds of its code to close ports and <code>kfree<\/code> associated memory. This code is still present in the pull request with the updated example from 2023.<\/p>\n\n\n\n<p>Still, I have to investigate if <code>tty_driver_kref_put<\/code> also removes timers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Things have gotten easier<\/h2>\n\n\n\n<p>Compared to the example for a 2.6 kernel in LDD3, the current version (at least for module <code>__init<\/code> and <code>__exit<\/code>) is way easier and frankly cleaner, i.e. easier to read.<\/p>\n\n\n\n<p>Still, or maybe exactly <em>because of that<\/em>, I think it&#8217;s time for a fourth edition of <em>Linux Device Drivers<\/em>.<\/p>\n\n\n\n<p><em>I try to go through with the rest of the module and understand and ideally fix it. Then I&#8217;ll upload it too, for later generations at kernel 8.x to despair of it. Link soon.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A while back I started tipping my toes into Linux Kernel module development. Mainly, to understand a driver for a data capture card I got to work with (or for, I believe). Well, there is a go-to reference: the book Linux Device Drivers, 3rd Edition by Corbet, Rubini and Kroah-Hartman (from now on LDD3). It&#8217;s&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[17,16],"tags":[94,97,95,18,96,98],"class_list":["post-369","post","type-post","status-publish","format-standard","hentry","category-hardware","category-linux","tag-driver","tag-example","tag-kernel","tag-linux","tag-tty","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/posts\/369","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/comments?post=369"}],"version-history":[{"count":2,"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/posts\/369\/revisions"}],"predecessor-version":[{"id":372,"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/posts\/369\/revisions\/372"}],"wp:attachment":[{"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/media?parent=369"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/categories?post=369"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bowfinger.de\/blog\/wp-json\/wp\/v2\/tags?post=369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}