title: My OS Kernel in D: Some embedded strings don't work
body: <p>I'm aware that is a rather difficult question to answer, mainly because there's so many things that could be wrong that it's hard to pin things down. But I'll give as much info as I can; hopefully that'll help.</p>
  
  <p>I started writing my own kernel using the D language and the Digital Mars D compiler, and after a lot of trouble with figuring out how to generate flat binaries that can be relocated, I finally came up with the idea of generating an ordinary PE file for the address <code>0xC0000000</code>, and replacing all of its headers with the byte <code>0x90</code> (the NOP opcode). This worked perfectly fine, and I was able to write things on the screen, set up paging, enter protected mode, etc. perfectly well, with--of course--the help of a 16-bit assembly-based boot loader.</p>
  
  <p>Everything was well, that is, I decided to port the D run-time library for use in my kernel. I managed to extract a subset of the library and modify it to get it to compile into my app. Then I ran my program. (Note: I did <strong>not</strong> <em>use</em> the library at all; my code was the first code executing after the boot--the first thing that happened was printing <code>"Kernel"</code> to the screen, and no run-time code was called before that.)</p>
  
  <p>A D array (and hence a string, since a string is just a <code>char[]</code>) is no more than a structure with a pointer and a size member, so on a 32-bit system it would be 8 bytes big. The funny thing was, when I ran my program, the structure's members showed up to be <em>zero</em> -- that is, both the pointer and the size were zero. (I verified this by printing the pointer's value to the screen, as well as the length member -- both were zero.) As soon as I removed the source code for the run-time (which was never executed anyway), they worked fine.</p>
  
  <p>I narrowed this down to two possibilities:</p>
  
  <ol>
  <li><p>The stack was somehow not set up correctly: I ruled this out, because everything worked fine without the runtime library, and I confirmed that no other code was executed before my code by disassembling the file.</p></li>
  <li><p>Something is funny with the PE file sections: I checked, and figured out that there were two TLS (thread-local) variables in the version with the run-time. Sure enough, when I made them shared (rather than thread-local), my code worked! <em>However</em>, my code still exhibited the <em>same</em> problem when I called code I'd written in a different file--only <code>kernel.d</code>, which is the startup file, behaved correctly with strings; in the other files, the arrays were zero again.</p></li>
  </ol>
  
  <p>Now, does anyone have any guess as to why this might be happening?</p>
  
  <p>If any more information is needed, I'll be happy to post it.</p>
  
  <p>Thank you!</p>