{"id":52,"date":"2016-06-24T14:04:56","date_gmt":"2016-06-24T14:04:56","guid":{"rendered":"http:\/\/dlang.org\/blog\/?p=52"},"modified":"2021-10-08T10:59:58","modified_gmt":"2021-10-08T10:59:58","slug":"project-highlight-the-powernex-kernel","status":"publish","type":"post","link":"https:\/\/dlang.org\/blog\/2016\/06\/24\/project-highlight-the-powernex-kernel\/","title":{"rendered":"Project Highlight: The PowerNex Kernel"},"content":{"rendered":"<p>Hang around the D community long enough and you&#8217;ll discover that people are using the language\u00a0in a variety of fields for a variety of projects, both professionally and personally. Computer games, scientific software, web apps,\u00a0economic modelling, even scripted utilities. There have even been a\u00a0few\u00a0open source kernel projects using D, the most recent\u00a0of which is <a href=\"https:\/\/github.com\/Vild\/PowerNex\">PowerNex by Dan Printzell<\/a>.<\/p>\n<p>As hobby projects go, an OS kernel is one of the more complex projects a programmer could tackle. It requires a certain level of motivation and dedication that isn&#8217;t needed for other types of projects. Dan insists that\u00a0it&#8217;s &#8220;fun, rewarding and hard, like big projects should be.&#8221;<\/p>\n<blockquote><p>I have always been interested in OS development and have been trying to write my own OS for years now. Each attempt was written in C, but none of them worked well because I mostly just copy-pasted code with no real knowledge of how it worked. Back in November 2015, I decided to start writing\u00a0yet another kernel, but this time in D. I also challenged myself to make it 64-bit.\u00a0The reason I chose D is simple. I love the language. I love that you can\u00a0write nice looking code with the help of string mixins and templates and that the code can interface easily with C.<\/p><\/blockquote>\n<p>The D programming language ships with a runtime, appropriately named <a href=\"https:\/\/github.com\/dlang\/druntime\">DRuntime<\/a>, which manages the garbage collector, ensures static constructors and destructors are called, and more. Some language features depend on the runtime being present. When developing an OS kernel, making use of the full runtime is not an option. Dan took the\u00a0minimal D runtime for bare metal D development that Adam Ruppe described in his book, the <a href=\"http:\/\/amzn.to\/1ZTE47m\">D Cookbook<\/a>, and used that as the basis for his kernel.<\/p>\n<blockquote><p>It is still pretty much the same thing Adam provided, with some patches to fix deprecated stuff and to connect it to the rest of the kernel.<\/p><\/blockquote>\n<p>It hasn&#8217;t all been a walk through the roses, though. By default, variables in D are in Thread Local Storage (TLS). In order to force variables to become globally shared across threads, they must be marked as either <code>shared<\/code> or <code>__gshared<\/code>. The former is intended to tell the compiler to restrict certain operations on the variable (you can read about it in <a href=\"http:\/\/www.informit.com\/articles\/article.aspx?p=1609144\">the freely available concurrency chapter<\/a> from Andrei Alexandrescu&#8217;s book, <a href=\"http:\/\/amzn.to\/1ZTDmqH\">The D Programming Language<\/a>). The latter essentially causes the compiler to treat it as a global C variable, with no guarantees and no protection. Normally, TLS variables are a good thing for D programs, but not when starting out in the early stages of kernel development.<\/p>\n<blockquote><p>The biggest problem I&#8217;ve encountered is that the compiler expects that TLS is enabled, which I haven&#8217;t done yet, so I need to append __gshared to all the global variables. If I don&#8217;t write __gshared, the kernel will try and access random memory addresses and do undefined stuff. Sometimes it crashes, sometimes it doesn&#8217;t. This is the thing that is most often behind PowerNex bugs.<\/p><\/blockquote>\n<p>Did I mention that Dan loves D&#8217;s <a href=\"https:\/\/dlang.org\/spec\/function.html#string-mixins\">string mixins<\/a> and <a href=\"https:\/\/dlang.org\/spec\/template.html\">templates<\/a>?<\/p>\n<blockquote><p>String mixins and templates are the best thing in the language. Without these I would probably write the kernel in C instead. One place where they are used is in the Interrupt Service Routines (ISR) handler. The problem with the\u00a0ISRs is that they don&#8217;t provide their\u00a0ID to the handler. So I need to make 256 different functions just to know which\u00a0ISR was triggered. This could be really error prone, but with some help from templates and string mixins, <a href=\"https:\/\/github.com\/Vild\/PowerNex\/blob\/master\/Kernel\/src\/CPU\/IDT.d\">I can generate those<\/a> and be sure that the content for each function is correct.<\/p><\/blockquote>\n<p>To compile PowerNex, Dan uses a cross-compiled GNU Binutils, a patched version of DMD, and his own build system, called <a href=\"https:\/\/github.com\/Vild\/Wild\">Wild<\/a>.<\/p>\n<blockquote><p>The GNU Binutils is for compiling the assembly files and for linking the final executable. <a href=\"https:\/\/github.com\/PowerNex\/dmd\/commits\/PowerNexCompiler\">The patch for DMD<\/a> that I currently use basically just adds PowerNex as a target and as a <a href=\"https:\/\/dlang.org\/spec\/version.html#predefined-versions\">predefined\u00a0version<\/a> (which is active when compiling). It is really hackily implemented because I&#8217;m not too familiar with\u00a0the DMD source code. I want to implement these better and get it upstream in the future when I will be able to compile userspace programs.<\/p>\n<p>The build system is not that much to look at currently. It is written in D and uses a JSON file as a frontend to define a set of file processors, rules and targets. With the help of these, Wild can compile PowerNex. I&#8217;m currently working on\u00a0conversion from JSON to a custom format to be able to provide the features needed for the compilation of the kernel and all its userspace programs.<\/p><\/blockquote>\n<p>He has a few specific goals in mind before he&#8217;s ready to brand a PowerNex 1.0 release.<\/p>\n<blockquote><p>One of my first short term goals is to be able to run a simple ELF executable. Next, I want to port druntime and phobos; once I have that done I will be able to run almost any D program natively. Finally, I will port either DMD or SDC (the <a href=\"https:\/\/github.com\/SDC-Developers\/SDC\">Stupid D Compiler<\/a>), depending on what state SDC is in when I get there.<\/p><\/blockquote>\n<p>You can see a couple of screenshots of\u00a0PowerNex\u00a0in action via <a href=\"http:\/\/forum.dlang.org\/post\/cgtvuamxqgcwxeucjbjb@forum.dlang.org\">a post from one D community member<\/a> in Dan&#8217;s forum announcement thread.\u00a0If the idea of\u00a0kernel development with D gives you goosebumps, <a href=\"https:\/\/github.com\/Vild\/PowerNex\">go have some fun<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hang around the D community long enough and you&#8217;ll discover that people are using the language\u00a0in a variety of fields for a variety of projects, both professionally and personally. Computer games, scientific software, web apps,\u00a0economic modelling, even scripted utilities. There have even been a\u00a0few\u00a0open source kernel projects using D, the most recent\u00a0of which is PowerNex [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[13],"tags":[],"_links":{"self":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/52"}],"collection":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/comments?post=52"}],"version-history":[{"count":15,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/52\/revisions"}],"predecessor-version":[{"id":312,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/52\/revisions\/312"}],"wp:attachment":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/media?parent=52"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/categories?post=52"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/tags?post=52"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}