<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Websofia</title>
	<atom:link href="http://www.websofia.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.websofia.com</link>
	<description>Notes on programming</description>
	<lastBuildDate>Fri, 20 Apr 2012 07:51:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>MySQL error 1067 &#8211; Windows error 87 &#8211; ERROR_INVALID_PARAMETER</title>
		<link>http://www.websofia.com/2012/04/mysql-error-1067-windows-error-87-error_invalid_parameter/</link>
		<comments>http://www.websofia.com/2012/04/mysql-error-1067-windows-error-87-error_invalid_parameter/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 07:51:10 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[error 1067]]></category>
		<category><![CDATA[error 87]]></category>
		<category><![CDATA[file operation]]></category>
		<category><![CDATA[innodb_flush_method]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=334</guid>
		<description><![CDATA[The strangest thing happened to a MySQL server (running Windows Server 2003) I set up today. MySQL would install with no problem, work all day with no problem, then fail after a reboot. The MySQL service simply wouldn&#8217;t start, producing &#8230;<p class="read-more"><a href="http://www.websofia.com/2012/04/mysql-error-1067-windows-error-87-error_invalid_parameter/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>The strangest thing happened to a MySQL server (running Windows Server 2003) I set up today. MySQL would install with no problem, work all day with no problem, then fail after a reboot. The MySQL service simply wouldn&#8217;t start, producing this error message:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">Could not start the MySQL service on Local Computer.
Error 1067: The process terminated unexpectedly.</pre></div></div></div></div></div></div></div>


<p>First I checked the<em> my.ini</em> file and saw no obvious problems (it was also the default <em>my.ini</em> file produced by the installer). Since the service wouldn&#8217;t start, I created a new one that made sure it was reading the right .ini file:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">mysqld --install MySql2 --defaults-file=&quot;c:\my.ini&quot;</pre></div></div></div></div></div></div></div>


<p>&#8230; but to no avail, as the same error occurred. Eventually I gave up and reinstalled MySQL. But it still didn&#8217;t work! I did learn two interesting things:</p>
<ul>
<li>When trying to delete a service from Windows, make sure that the Services Manager is not open. The deleted service only gets truly deleted when the Services Manager is closed, which may leave you wondering why it&#8217;s taking so long (&#8220;This service is marked for deletion&#8221;).</li>
<li>When you need to reinstall MySQL, in order to really start fresh, you need to do three things:
<ol>
<li>Uninstall MySQL (Add/remove programs, etc.)</li>
<li>Delete the MySQL program directory</li>
<li>Delete the MySQL data directory (under Documents and Settings, Application Data, etc.)</li>
</ol>
</li>
</ul>
<p>When I did a truly &#8220;fresh&#8221; install of MySQL, it actually worked again. But only till the next reboot. I found out when there was a power outage later during the day. MySQL wouldn&#8217;t start, and manually starting the service would produce, again, the error 1067.</p>
<p>This time I had a look at the <strong>MySQL log file</strong>, which lives in the data directory (called server001.err in my case). I found this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">120420  8:21:38  InnoDB: Operating system error number 87 in a file operation.
InnoDB: Some operating system error numbers are described at
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/operating-system-error-codes.html
InnoDB: File name .\ib_logfile0
InnoDB: File operation call: 'aio read'.
InnoDB: Cannot continue operation.</pre></div></div></div></div></div></div></div>


<p>Ah, more information on the error. It turns out that <strong>Windows error 87</strong> is <strong>ERROR_INVALID_PARAMETER</strong>; in other words: &#8220;The parameter is incorrect&#8221; (see <a href="http://dev.mysql.com/doc/refman/5.5/en/operating-system-error-codes.html">here</a>). Not particularly helpful, but it gets you something to Google for.</p>
<p>There weren&#8217;t too many Google results, but after I while I found <a href="http://bugs.mysql.com/bug.php?id=28913">this</a>. It seems that the error is related to either the disk driver or the formatting of the disk (neither of which I could easily change on a remote server). But the bug report did include a workaround. Add this to <em>my.ini</em>:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">innodb_flush_method=normal</pre></div></div></div></div></div></div></div>


<p>And it works!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2012/04/mysql-error-1067-windows-error-87-error_invalid_parameter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing your own bootloader for a toy operating system (5)</title>
		<link>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-5/</link>
		<comments>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-5/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 09:13:21 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Operating System Development]]></category>
		<category><![CDATA[assembler]]></category>
		<category><![CDATA[Bochs]]></category>
		<category><![CDATA[Bochs debugger]]></category>
		<category><![CDATA[boot sector]]></category>
		<category><![CDATA[bootloader]]></category>
		<category><![CDATA[FAT]]></category>
		<category><![CDATA[magic breakpoint]]></category>
		<category><![CDATA[makefile]]></category>
		<category><![CDATA[second stage]]></category>
		<category><![CDATA[toy operating system]]></category>
		<category><![CDATA[xchg bx]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=326</guid>
		<description><![CDATA[This article is part of a short series. Here are part 1, part 2, part 3 and part 4. In our endeavor to write a boot loader for a toy operating system, we&#8217;ve come far already. Our boot loader does &#8230;<p class="read-more"><a href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-5/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>This article is part of a short series. Here are <a title="Writing your own boot loader for a toy operating system (1)" href="../2012/04/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/">part 1</a>, <a title="Writing your own bootloader for a toy operating system (2)" href="../2012/04/2011/10/writing-your-own-bootloader-for-a-toy-operating-system-2/">part 2</a>, <a title="Writing your own bootloader for a toy operating system (3)" href="../2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/">part 3</a> and <a title="Writing your own bootloader for a toy operating system (4)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-4/">part 4</a>.</strong></p>
<p>In our endeavor to write a boot loader for a toy operating system, we&#8217;ve come far already. Our boot loader does the following so far:</p>
<ul>
<li>Setup data segments</li>
<li>Reset the drive system</li>
<li>Write a &#8220;loading&#8221; message</li>
<li>Find the kernel file on disk, using parameters found in the boot sector</li>
<li>Read the FAT table into memory</li>
<li>Read the kernel file into memory, using the FAT table</li>
<li>Reboot gracefully if the file could not be found or if reading fails</li>
</ul>
<p>We are now in a position to put all the code fragments together and compile our boot loader. We&#8217;ll also add some initial code to our kernel, so that it can say &#8220;Hello&#8221;.</p>
<h1>Putting the code together</h1>
<p>The bits of code we&#8217;ve written so far actually come in two flavors: code that&#8217;s used only once and code that&#8217;s called various times. The code that&#8217;s called in multiple places should be implemented as functions; the rest will be macros. We use macros (a feature of the GNU assembler) merely to be able to give a name to a body of code so our source does not become unreadable.</p>
<p>The functions and macros will reside in their own files. This is because even with what we&#8217;ve done so far, the boot process isn&#8217;t quite complete yet. We&#8217;ll still have to write code that puts the processor in protected mode, sets up protected mode descriptor tables, and starts the kernel (we&#8217;ll get to all that later). Since we only have a few bytes left in our boot sector (as you&#8217;ll see after compiling), we&#8217;ll have to put this code somewhere else: in a &#8220;second stage boot loader&#8221;. The upshot of this is that while our boot sector code is limited to only one segment of 512 bytes, our second stage boot loader can occupy many sectors.</p>
<p>The second stage boot loader will again need to read the root directory and the FAT table in order to be able to find and read a file. With our functions and macros placed in separate files, we&#8217;ll be able to use all that code again easily.</p>
<p>Therefore, the code will be divided into files like this:</p>
<ul>
<li><strong>boot.s</strong> &#8211; Primary boot loader</li>
<li><strong>2ndstage.s</strong> &#8211; Second stage boot loader</li>
<li><strong>bootsector.s</strong> &#8211; Macro for the actual boot sector data</li>
<li><strong>macros.s</strong> &#8211; Reusable macros</li>
<li><strong>functions.s</strong> &#8211; Reusable functions</li>
</ul>
<p>You can download the source code so far <strong><a href="http://www.websofia.com/wp-content/uploads/2012/04/boot-loader.zip">here</a></strong>.</p>
<p>Since we now have to compile each file separately, we&#8217;ll tie the build process together with a <strong>makefile</strong>.</p>
<h1>Makefiles</h1>
<p>In order to compile our five files, and turn them into a disk image we can test with Bochs, we need quite a few instructions:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">as -o boot.o boot.s
ld -o boot.out boot.o -Ttext 0x7c00
objcopy -O binary -j .text boot.out boot.bin
as -o 2ndstage.o 2ndstage.s
ld -o 2ndstage.out 2ndstage.o -Ttext 0x0
objcopy -O binary -j .text 2ndstage.out 2ndstage.bin
imagefs c test.img 720
imagefs b test.img boot.bin
imagefs a test.img 2ndstage.bin</pre></div></div></div></div></div></div></div>


<p>Instead of typing all this at the command prompt each time you test, you&#8217;d be better off placing the instructions in a batch file. Better yet, the GNU toolchain comes with a solution: <strong>makefiles</strong>. Imagine your code growing, so that you have many subdirectories with many files that need to be compiled. You&#8217;ll write many batchfiles with similar instructions. Also, you have no way of cleaning up intermediary files. And worst of all, you&#8217;ll always compile <em>everything</em>, including files that haven&#8217;t changed, which might get slow if you have a lot of code.</p>
<p>With makefiles, its gets easier. GNU make determines automatically which files have changed, and compiles only those files.</p>
<p>Here is a makefile for our boot loader code:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="make"><pre class="de1">AS  <span class="sy0">:=</span> as
LD  <span class="sy0">:=</span> ld
&nbsp;
all<span class="sy0">:</span> boot<span class="sy0">.</span>bin 2ndstage<span class="sy0">.</span>bin
&nbsp;
boot<span class="sy0">.</span>bin<span class="sy0">:</span> boot<span class="sy0">.</span>out
objcopy <span class="sy0">-</span>O binary <span class="sy0">-</span>j <span class="sy0">.</span>text boot<span class="sy0">.</span>out boot<span class="sy0">.</span>bin
&nbsp;
boot<span class="sy0">.</span>out<span class="sy0">:</span> boot<span class="sy0">.</span>o
<span class="sy0">$</span><span class="br0">&#40;</span><span class="re2">LD</span><span class="br0">&#41;</span> <span class="sy0">-</span>o boot<span class="sy0">.</span>out boot<span class="sy0">.</span>o <span class="sy0">-</span>Ttext 0x7c00
&nbsp;
boot<span class="sy0">.</span>o<span class="sy0">:</span> boot<span class="sy0">.</span>s bootsector<span class="sy0">.</span>s functions<span class="sy0">.</span>s macros<span class="sy0">.</span>s
<span class="sy0">$</span><span class="br0">&#40;</span><span class="re2">AS</span><span class="br0">&#41;</span> <span class="sy0">-</span>o boot<span class="sy0">.</span>o boot<span class="sy0">.</span>s
&nbsp;
2ndstage<span class="sy0">.</span>bin<span class="sy0">:</span> 2ndstage<span class="sy0">.</span>out
objcopy <span class="sy0">-</span>O binary <span class="sy0">-</span>j <span class="sy0">.</span>text 2ndstage<span class="sy0">.</span>out 2ndstage<span class="sy0">.</span>bin
&nbsp;
2ndstage<span class="sy0">.</span>out<span class="sy0">:</span> 2ndstage<span class="sy0">.</span>o
<span class="sy0">$</span><span class="br0">&#40;</span><span class="re2">LD</span><span class="br0">&#41;</span> <span class="sy0">-</span>o 2ndstage<span class="sy0">.</span>out 2ndstage<span class="sy0">.</span>o <span class="sy0">-</span>Ttext 0x0
&nbsp;
2ndstage<span class="sy0">.</span>o<span class="sy0">:</span> 2ndstage<span class="sy0">.</span>s bootsector<span class="sy0">.</span>s functions<span class="sy0">.</span>s macros<span class="sy0">.</span>s
<span class="sy0">$</span><span class="br0">&#40;</span><span class="re2">AS</span><span class="br0">&#41;</span> <span class="sy0">-</span>o 2ndstage<span class="sy0">.</span>o 2ndstage<span class="sy0">.</span>s
&nbsp;
clean<span class="sy0">:</span>
del <span class="sy0">*.</span>o
del <span class="sy0">*.</span>out
del <span class="sy0">*.</span>bin</pre></div></div></div></div></div></div></div>


<p>Note, for instance, the lines:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="make"><pre class="de1">boot<span class="sy0">.</span>o<span class="sy0">:</span> boot<span class="sy0">.</span>s bootsector<span class="sy0">.</span>s functions<span class="sy0">.</span>s macros<span class="sy0">.</span>s
<span class="sy0">$</span><span class="br0">&#40;</span><span class="re2">AS</span><span class="br0">&#41;</span> <span class="sy0">-</span>o boot<span class="sy0">.</span>o boot<span class="sy0">.</span>s</pre></div></div></div></div></div></div></div>


<p>This instructions tells make that the boot.o object file depends on the files boot.s, bootsector.s, functions.s and macros.s. If any of these files change, then boot.o must be recompiled. In short, makefiles allow you to describe <em>dependencies</em>.</p>
<p>In order to build your code, you can now do:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">mingw32-make</pre></div></div></div></div></div></div></div>


<p>And to clean everything up except the source code, do:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">mingw32-make clean</pre></div></div></div></div></div></div></div>


<h1>The second-stage boot loader</h1>
<p>We can now write a first version of our second-stage boot loader, just to prove that our concept works. We&#8217;ll write one that simply writes &#8220;Hello&#8221; to the screen, then hangs.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="kw4">.code16</span>
<span class="kw4">.intel_syntax</span> noprefix
<span class="kw4">.text</span>
<span class="kw4">.org</span> <span class="nu0">0x0</span>
<span class="kw4">.include</span> <span class="st0">&quot;macros.s&quot;</span>
&nbsp;
<span class="kw4">.global</span> main
<span class="re0">main:</span>
  mWriteString msg
<span class="re0">hang:</span>
  <span class="kw1">jmp</span> hang
&nbsp;
<span class="co1"># Booting has failed because of a disk error.</span>
<span class="co1"># Inform the user and reboot.</span>
<span class="re0">bootFailure:</span>
  mWriteString diskerror
  mReboot
&nbsp;
<span class="kw4">.include</span> <span class="st0">&quot;functions.s&quot;</span>
&nbsp;
<span class="re0">msg:</span>          <span class="kw4">.asciz</span> <span class="st0">&quot;Hello!\r\n&quot;</span>
<span class="re0">rebootmsg:</span>    <span class="kw4">.asciz</span> <span class="st0">&quot;Press any key to reboot.\r\n&quot;</span>
<span class="re0">diskerror:</span>    <span class="kw4">.asciz</span> <span class="st0">&quot;Disk error. &quot;</span>
&nbsp;
<span class="kw4">.include</span> <span class="st0">&quot;bootsector.s&quot;</span>
&nbsp;
<span class="kw4">.fill</span> <span class="nu0">1024</span><span class="sy0">,</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">1</span>  <span class="co1"># Pad 1K with 1-bytes to test file larger than 1 sector</span></pre></div></div></div></div></div></div></div>


<p>You&#8217;ll note several things here. We&#8217;ve included the files <em>functions.s</em> and <em>macros.s</em> which were originally written for the primary boot loader. We&#8217;ll need them later when we load our kernel file. Also, we need the <em>mWriteString</em> macro in order to write text to the screen. The <em>bootFailure</em> section is also present, along with the messages it prints. We&#8217;ll also need this later, but right now we must include it since the code in functions.s and macros.s requires it. Since we&#8217;re not actually calling much of the code in macros.s, the resulting binary file for the second stage boot loader will be quite small.</p>
<p>Also, I&#8217;ve added 1024 bytes with a value of 1 to the end of the file, just to give it a size of over two sectors. This will allow us to see that our primary boot loader does in fact use the FAT table correctly to load a 3-sector file into memory.</p>
<h1>Debugging the code</h1>
<p>All right, now that we&#8217;ve put it all together (don&#8217;t forget to download the final code <a href="http://www.websofia.com/wp-content/uploads/2012/04/boot-loader.zip">here</a>) we can compile and run it. If you like, you can use the makefile above to do this, or you can do it manually. Next, create a disk image from it. (You could add the required instructions to the makefile as an exercise.)</p>
<p>The resulting disk image can now be run in Bochs as we&#8217;ve seen before. However, can and will go wrong and this is as good a time as any to get acquainted with Bochs&#8217;s built-in debugger, which will become your friend soon. Bochs actually comes with two main executables: <strong>bochs.exe</strong> and <strong>bochsdbg.exe</strong>, the latter being the debugger. You can start it directly, or you can use configuration files. The latter will be easier for reuse of your configuration.</p>
<p>In order to create a configuration file, load up Bochs (doesn&#8217;t matter which executable you start) and use the configuration window to setup your test system (also see <a title="Writing your own bootloader for a toy operating system (3)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/">part 3</a> of this guide for a refresher). When you&#8217;re all done, do not start the emulator, but save your configuration to file:</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/04/bochs-start-menu.jpg"><img class="alignnone size-full wp-image-328" title="Bochs start menu" src="http://www.websofia.com/wp-content/uploads/2012/04/bochs-start-menu.jpg" alt="" width="429" height="249" /></a></p>
<p>This will create a file called <em>bochsrc.bxrc</em> on your disk which contains your configuration settings. Close the configuration window now with the <em>Quit</em> button. In order to start the emulator, you can now right-click on the <em>bochsrc.bxrc</em> file and select <strong>Debugger</strong>:</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/04/boch-start-debugger.jpg"><img class="alignnone size-full wp-image-329" title="Starting Bochs in debug mode" src="http://www.websofia.com/wp-content/uploads/2012/04/boch-start-debugger.jpg" alt="" width="416" height="131" /></a></p>
<p>Of course, you can also select <strong>Run</strong> to run in normal, non-debug mode. When debugging, Bochs stops execution of the emulator at the very beginning: inside the POST (Power-On Self Test) code. You can use the debugger to step through this code, if you like, and follow exactly what is does. Eventually your boot sector will be loaded and you can step through that code, as well:</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/04/bochs-debugger.jpg"><img class="alignnone size-full wp-image-330" title="The Bochs built-in debugger" src="http://www.websofia.com/wp-content/uploads/2012/04/bochs-debugger.jpg" alt="" width="540" height="370" /></a></p>
<p>With every step, you can study the value of the processor&#8217;s registers and the contents of the physical memory, which will be solid gold when you run into trouble. Of course, it&#8217;s pain in the neck so have to step through all the BIOS code every time you run the emulator. What we really need are breakpoints. You can either use the debugger itself to place breakpoints by double-clicking an assembly instruction, but that would require scrolling through lots of code, and some of your code hasn&#8217;t even been loaded yet! It&#8217;s easier to actually add a breakpoint instruction to your source code.</p>
<h2>Magic Breakpoints</h2>
<p>Bochs supports a concept called <strong>magic breakpoints</strong>. The Intel IA-32 processor has an instruction that no-one uses since it does nothing (no, it&#8217;s not NOP). The instruction is:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="kw1">xchg</span> <span class="kw3">bx</span><span class="sy0">,</span> <span class="kw3">bx</span></pre></div></div></div></div></div></div></div>


<p>This simply exchanges with contents of the bx register with itself. Bochs assumes you&#8217;ll never use this instruction in your code, so when the debugger encounters it, it stops execution: a <em>breakpoint</em>. Sprinkle some of these instructions through your code and you can just use the &#8220;Continue&#8221; option in the Bochs debugger to move from one breakpoint to the next. Finally, you can debug properly!</p>
<p>Note that you may need to <strong>enable magic breakpoints</strong> in the Bochs configuration.</p>
<h1>Summary</h1>
<p>In this section, we&#8217;ve put all our code together and compiled it (<a href="http://www.websofia.com/wp-content/uploads/2012/04/boot-loader.zip">here</a> is the source for download). We&#8217;ve seen how to use makefiles to make the compilation process easy and repeatable. We&#8217;ve also seen how we can use Bochs&#8217;s internal debugger to step through our code as it executes, and how to set magic breakpoints. Finally, we&#8217;ve added a tentative second-stage boot loader to our toy OS that, for the time being, says &#8220;Hello&#8221;.</p>
<p>In the next part, we&#8217;ll talk about fleshing out our second-stage boot loader with switching the processor to protected mode, and launching our kernel. Stay tuned!</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-5/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Writing your own bootloader for a toy operating system (4)</title>
		<link>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-4/</link>
		<comments>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-4/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 14:21:37 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Operating System Development]]></category>
		<category><![CDATA[boot sector]]></category>
		<category><![CDATA[CHS]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[cylinder]]></category>
		<category><![CDATA[FAT]]></category>
		<category><![CDATA[FAT12]]></category>
		<category><![CDATA[head]]></category>
		<category><![CDATA[int 0x13]]></category>
		<category><![CDATA[LBA]]></category>
		<category><![CDATA[read sector]]></category>
		<category><![CDATA[root directory]]></category>
		<category><![CDATA[sector]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=299</guid>
		<description><![CDATA[This article is part of a short series. Here are part 1, part 2 and part 3. In the previous parts of this guide, we wrote assembly code for a simple boot sector and set up the GNU toolchain we &#8230;<p class="read-more"><a href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-4/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>This article is part of a short series. Here are <a title="Writing your own boot loader for a toy operating system (1)" href="../2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/">part 1</a>, <a title="Writing your own bootloader for a toy operating system (2)" href="../2011/10/writing-your-own-bootloader-for-a-toy-operating-system-2/">part 2</a> and <a title="Writing your own bootloader for a toy operating system (3)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/">part 3</a>.</strong></p>
<p>In the previous parts of this guide, we wrote assembly code for a simple boot sector and set up the GNU toolchain we use for compiling it and writing it to a floppy disk image. We then used the Bochs IA-32 emulator to boot from that image and see it run.</p>
<p>Our current boot loader resets the drive system, writes a &#8220;loading&#8221; messages to the screen, waits for a keypress and reboots. It&#8217;s now time to make it do what it&#8217;s supposed to do: find our kernel file on the disk, so it can be loaded into memory and run.</p>
<h2>Reading from disk</h2>
<p>Before we get into how to find a file, we need to get some basics sorted first: we need some way to actually read data from our disk. Reading from a disk is done through calling BIOS interrupts (built-in functions that come with the BIOS of any computer). We&#8217;ll require interrupt 0&#215;13, subfunction 2. Its arguments are these:</p>
<h3>Interrupt 0&#215;13 &#8211; 2: Read sectors</h3>

<table id="wp-table-reloaded-id-4-no-1" class="wp-table-reloaded wp-table-reloaded-id-4">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Register</th><th class="column-2">Value</th>
	</tr>
</thead>
<tbody class="row-hover">
	<tr class="row-2 even">
		<td class="column-1">al</td><td class="column-2">Number of sectors to read</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">ah</td><td class="column-2">Subfunction 2</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">ch</td><td class="column-2">Low 8 bits of cylinder</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">cl</td><td class="column-2">High 2 bits of cylinder, 6 bits for sector</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">dh</td><td class="column-2">Head number</td>
	</tr>
	<tr class="row-7 odd">
		<td class="column-1">dl</td><td class="column-2">Drive number</td>
	</tr>
	<tr class="row-8 even">
		<td class="column-1">es:bx</td><td class="column-2">Data buffer</td>
	</tr>
</tbody>
</table>

<p>The interrupt tries to read one or more sectors from disk, and sets the carry flag if it fails. Failures are common, and read operations should always be tried several times before giving up.</p>
<h3>Logical Block Addressing (LBA)</h3>
<p>Did you notice the <strong>track</strong> and <strong>head</strong> parameters? So far we&#8217;ve been talking about sectors only. In facts, we&#8217;ve assumed that a disk is simply a long sequential list of sectors. That would be nice, but reality is not nice in this case. We&#8217;ve been thinking in terms of what is known as <strong>Logical Block Addressing</strong> (LBA), while actual disks work differently. Disks can actually have multiple sides that are read by multiple reading heads. Also, sectors are grouped in tracks or cylinders (like on a vinyl record) which further complicates matters. However, the math required to convert an LBA number to a head, cylinder and sector combination is this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">Sector   = (LBA mod SectorsPerTrack) + 1
Cylinder = (LBA / SectorsPerTrack) / NumHeads
Head     = (LBA / SectorsPerTrack) mod NumHeads</pre></div></div></div></div></div></div></div>


<p>What we need to do, then, is write a function that converts an LBA number into these low-level values, reads a sector, and gives it back. That way, the rest of our code can focus on thinking in terms of logical block addresses which avoids headaches.</p>
<h3>Read sector code</h3>
<p>Here is the code that reads a logical sector from disk:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="co1"># Read sector with logical address (LBA) AX into data</span>
<span class="co1"># buffer at ES:BX. This function uses interrupt 13h, subfunction ah=2.</span>
<span class="kw4">.func</span> ReadSector
<span class="re0">ReadSector:</span>
  <span class="kw1">xor</span>     <span class="kw3">cx</span><span class="sy0">,</span> <span class="kw3">cx</span>                      <span class="co1"># Set try count = 0</span>
&nbsp;
 <span class="re0">readsect:</span>
  <span class="kw1">push</span>    <span class="kw3">ax</span>                          <span class="co1"># Store logical block</span>
  <span class="kw1">push</span>    <span class="kw3">cx</span>                          <span class="co1"># Store try number</span>
  <span class="kw1">push</span>    <span class="kw3">bx</span>                          <span class="co1"># Store data buffer offset</span>
&nbsp;
  <span class="co1"># Calculate cylinder, head and sector:</span>
  <span class="co1"># Cylinder = (LBA / SectorsPerTrack) / NumHeads</span>
  <span class="co1"># Sector   = (LBA mod SectorsPerTrack) + 1</span>
  <span class="co1"># Head     = (LBA / SectorsPerTrack) mod NumHeads</span>
&nbsp;
  <span class="kw1">mov</span>     <span class="kw3">bx</span><span class="sy0">,</span> iTrackSect              <span class="co1"># Get sectors per track</span>
  <span class="kw1">xor</span>     <span class="kw3">dx</span><span class="sy0">,</span> <span class="kw3">dx</span>
  <span class="kw1">div</span>     <span class="kw3">bx</span>                          <span class="co1"># Divide (dx:ax/bx to ax,dx)</span>
                                      <span class="co1"># Quotient (ax) =  LBA / SectorsPerTrack</span>
                                      <span class="co1"># Remainder (dx) = LBA mod SectorsPerTrack</span>
  <span class="kw1">inc</span>     <span class="kw3">dx</span>                          <span class="co1"># Add 1 to remainder, since sector</span>
  <span class="kw1">mov</span>     <span class="kw3">cl</span><span class="sy0">,</span> <span class="kw3">dl</span>                      <span class="co1"># Store result in cl for int 13h call.</span>
&nbsp;
  <span class="kw1">mov</span>     <span class="kw3">bx</span><span class="sy0">,</span> iHeadCnt                <span class="co1"># Get number of heads</span>
  <span class="kw1">xor</span>     <span class="kw3">dx</span><span class="sy0">,</span> <span class="kw3">dx</span>
  <span class="kw1">div</span>     <span class="kw3">bx</span>                          <span class="co1"># Divide (dx:ax/bx to ax,dx)</span>
                                      <span class="co1"># Quotient (ax) = Cylinder</span>
                                      <span class="co1"># Remainder (dx) = head</span>
  <span class="kw1">mov</span>     <span class="kw3">ch</span><span class="sy0">,</span> <span class="kw3">al</span>                      <span class="co1"># ch = cylinder                      </span>
  <span class="kw1">xchg</span>    <span class="kw3">dl</span><span class="sy0">,</span> <span class="kw3">dh</span>                      <span class="co1"># dh = head number</span>
&nbsp;
  <span class="co1"># Call interrupt 0x13, subfunction 2 to actually</span>
  <span class="co1"># read the sector.</span>
  <span class="co1"># al = number of sectors</span>
  <span class="co1"># ah = subfunction 2</span>
  <span class="co1"># cx = sector number</span>
  <span class="co1"># dh = head number</span>
  <span class="co1"># dl = drive number</span>
  <span class="co1"># es:bx = data buffer</span>
  <span class="co1"># If it fails, the carry flag will be set.</span>
  <span class="kw1">mov</span>     <span class="kw3">ax</span><span class="sy0">,</span> <span class="nu0">0x0201</span>                  <span class="co1"># Subfunction 2, read 1 sector</span>
  <span class="kw1">mov</span>     <span class="kw3">dl</span><span class="sy0">,</span> iBootDrive              <span class="co1"># from this drive</span>
  <span class="kw1">pop</span>     <span class="kw3">bx</span>                          <span class="co1"># Restore data buffer offset.</span>
  <span class="kw1">int</span>     <span class="nu0">0x13</span>
  <span class="kw1">jc</span>      readfail
&nbsp;
  <span class="co1"># On success, return to caller.</span>
  <span class="kw1">pop</span>     <span class="kw3">cx</span>                          <span class="co1"># Discard try number</span>
  <span class="kw1">pop</span>     <span class="kw3">ax</span>                          <span class="co1"># Get logical block from stack</span>
  <span class="kw1">ret</span>
&nbsp;
  <span class="co1"># The read has failed.</span>
  <span class="co1"># We will retry four times total, then jump to boot failure.</span>
 <span class="re0">readfail:</span>   
  <span class="kw1">pop</span>     <span class="kw3">cx</span>                          <span class="co1"># Get try number             </span>
  <span class="kw1">inc</span>     <span class="kw3">cx</span>                          <span class="co1"># Next try</span>
  <span class="kw1">cmp</span>     <span class="kw3">cx</span><span class="sy0">,</span> <span class="kw5">word</span> ptr <span class="nu0">4</span>              <span class="co1"># Stop at 4 tries</span>
  <span class="kw1">je</span>      bootFailure
&nbsp;
  <span class="co1"># Reset the disk system:</span>
  <span class="kw1">xor</span>     <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">ax</span>
  <span class="kw1">int</span>     <span class="nu0">0x13</span>
&nbsp;
  <span class="co1"># Get logical block from stack and retry.</span>
  <span class="kw1">pop</span>     <span class="kw3">ax</span>
  <span class="kw1">jmp</span>     readsect
<span class="kw4">.endfunc</span></pre></div></div></div></div></div></div></div>


<p>This code will attempt to read the sector with LBA specified in AX up to four times before giving up and jumping to <em>bootFailure</em>. After each failed read attempt, the disk system is reset. Most of the code focuses on doing the divisions required to get the values needed by the interrupt call. If all goes well, the sector&#8217;s 512 bytes are placed in ES:BX.</p>
<p>As a side note, we&#8217;re actually lucky to have interrupt 0&#215;13 at this stage. Once we&#8217;ve put our processor in protected mode, we won&#8217;t have access to the BIOS anymore (all its code only runs in 16-bit real mode) and we&#8217;ll have to access the disk drive ourselves which is <em>very</em> tricky.</p>
<h2>Introduction to FAT</h2>
<p>There are <a href="http://en.wikipedia.org/wiki/List_of_file_systems">many file systems</a> in use these days (NTFS, ext, BFS, UFS, etc.) and we need to pick one to use for our bootable disk. <strong>FAT</strong> (&#8220;File Allocation Table&#8221;) is not the most advanced system available, but it&#8217;s simple, and on Windows we have the tools for format a disk with it. Plus, rawrite and ImageFS understand it. At a later stage in the development of a toy OS, you can implement support for bags of other file systems if you want.</p>
<p>There is no actual requirement to use any file system. A (floppy) disk is just a bag of bytes, grouped in sectors, clusters and tracks (we&#8217;ll get to that), that you can read from and write to. The BIOS expects the first sector of a bootable to disk to be a boot sector, but that&#8217;s the only requirement. However, at some point we&#8217;ll want to store files and it&#8217;s a good idea to pick a file system now, so FAT it is.</p>
<p>FAT comes in different flavors. There&#8217;s FAT12, FAT16 and FAT32. The difference is in the size of the disk supported. For FAT12, references to sectors on disk can be up to 12 bits (a maximum value of 4,096 sectors), while with FAT32 we can point to 4,294,967,296 sectors. Since we&#8217;re working with floppy disks, FAT12 is enough. The discussion below applies to all FAT versions.</p>
<p>The basic structure of a 720 KB floppy disk formatted with FAT is this:</p>

<table id="wp-table-reloaded-id-2-no-1" class="wp-table-reloaded wp-table-reloaded-id-2">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Region</th><th class="column-2">Size</th>
	</tr>
</thead>
<tbody class="row-hover">
	<tr class="row-2 even">
		<td class="column-1">Boot sector</td><td class="column-2">1</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">File allocation table (FAT)</td><td class="column-2">18</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">Root directory</td><td class="column-2">14</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">Data area</td><td class="column-2">1407</td>
	</tr>
</tbody>
</table>

<p>A 720 KB floppy disk contains 1440 512-byte sectors, some of which are reserved as shown. The remaining 1,407 sectors contain the data of our files.</p>
<h3>The boot sector</h3>
<p>Here is a quick refresher of the layout of the boot sector (see also <a title="Writing your own boot loader for a toy operating system (1)" href="http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/">part 1</a> of this guide).</p>

<table id="wp-table-reloaded-id-1-no-1" class="wp-table-reloaded wp-table-reloaded-id-1">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Offset</th><th class="column-2">Size</th><th class="column-3"></th><th class="column-4">Contents</th><th class="column-5">Typical value</th>
	</tr>
</thead>
<tbody class="row-hover">
	<tr class="row-2 even">
		<td class="column-1">0000</td><td class="column-2">3</td><td class="column-3">Code</td><td class="column-4">Jump to rest of code</td><td class="column-5"></td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">0003</td><td class="column-2">8</td><td rowspan="12" class="column-3 rowspan-12">BPB</td><td class="column-4">OEM name</td><td class="column-5">Great-OS</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">0011</td><td class="column-2">2</td><td class="column-4">Bytes per sector</td><td class="column-5">512</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">0013</td><td class="column-2">1</td><td class="column-4">Number of sectors per cluster</td><td class="column-5">1</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">0014</td><td class="column-2">2</td><td class="column-4">Number of reserved sectors</td><td class="column-5">1</td>
	</tr>
	<tr class="row-7 odd">
		<td class="column-1">0016</td><td class="column-2">1</td><td class="column-4">Number of FAT tables</td><td class="column-5">2</td>
	</tr>
	<tr class="row-8 even">
		<td class="column-1">0017</td><td class="column-2">2</td><td class="column-4">Number of root directory entries (usually 224)</td><td class="column-5">224</td>
	</tr>
	<tr class="row-9 odd">
		<td class="column-1">0019</td><td class="column-2">2</td><td class="column-4">Total number of sectors</td><td class="column-5">2880</td>
	</tr>
	<tr class="row-10 even">
		<td class="column-1">0021</td><td class="column-2">1</td><td class="column-4">Media descriptor</td><td class="column-5">0xf0</td>
	</tr>
	<tr class="row-11 odd">
		<td class="column-1">0022</td><td class="column-2">2</td><td class="column-4">Number of sectors per FAT</td><td class="column-5">9</td>
	</tr>
	<tr class="row-12 even">
		<td class="column-1">0024</td><td class="column-2">2</td><td class="column-4">Number of sectors/track</td><td class="column-5">9</td>
	</tr>
	<tr class="row-13 odd">
		<td class="column-1">0026</td><td class="column-2">2</td><td class="column-4">Number of heads</td><td class="column-5">2</td>
	</tr>
	<tr class="row-14 even">
		<td class="column-1">0028</td><td class="column-2">2</td><td class="column-4">Number of hidden sectors</td><td class="column-5">0</td>
	</tr>
	<tr class="row-15 odd">
		<td class="column-1">0030</td><td class="column-2">2</td><td rowspan="8" class="column-3 rowspan-8">EBPB</td><td class="column-4">Number of hidden sectors (high word)</td><td class="column-5">0</td>
	</tr>
	<tr class="row-16 even">
		<td class="column-1">0032</td><td class="column-2">4</td><td class="column-4">Total number of sectors in filesystem</td><td class="column-5"></td>
	</tr>
	<tr class="row-17 odd">
		<td class="column-1">0036</td><td class="column-2">1</td><td class="column-4">Logical drive number</td><td class="column-5">0</td>
	</tr>
	<tr class="row-18 even">
		<td class="column-1">0037</td><td class="column-2">1</td><td class="column-4">Reserved</td><td class="column-5"></td>
	</tr>
	<tr class="row-19 odd">
		<td class="column-1">0038</td><td class="column-2">1</td><td class="column-4">Extended signature</td><td class="column-5">0x29</td>
	</tr>
	<tr class="row-20 even">
		<td class="column-1">0039</td><td class="column-2">4</td><td class="column-4">Serial number</td><td class="column-5"></td>
	</tr>
	<tr class="row-21 odd">
		<td class="column-1">0043</td><td class="column-2">8</td><td class="column-4">Volume label</td><td class="column-5">MYVOLUME</td>
	</tr>
	<tr class="row-22 even">
		<td class="column-1">0054</td><td class="column-2">8</td><td class="column-4">Filesystem type</td><td class="column-5">FAT16   </td>
	</tr>
	<tr class="row-23 odd">
		<td class="column-1">0062</td><td class="column-2">448</td><td class="column-3">Code</td><td class="column-4">Boot code</td><td class="column-5"></td>
	</tr>
	<tr class="row-24 even">
		<td class="column-1">0510</td><td class="column-2">2</td><td class="column-3">Required</td><td class="column-4">Boot signature</td><td class="column-5">0xaa55</td>
	</tr>
</tbody>
</table>

<p>I&#8217;ve filled this table with the values you would typically get for a 720 KB floppy disk formatted with FAT. The values in the boot sector are used to determine where exactly on the disk the FAT tables and the root directory live.</p>
<h3>The root directory</h3>
<p>In order to find a file on the disk, we need to start by looking at the root directory. This is a list of up to 224 entries (according to the boot sector) of 32 bytes each. Each entry contains data about a file:</p>

<table id="wp-table-reloaded-id-3-no-1" class="wp-table-reloaded wp-table-reloaded-id-3">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Offset</th><th class="column-2">Size</th><th class="column-3">Description</th>
	</tr>
</thead>
<tbody class="row-hover">
	<tr class="row-2 even">
		<td class="column-1">0x00</td><td class="column-2">8</td><td class="column-3">File name</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">0x08</td><td class="column-2">3</td><td class="column-3">File extension</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">0x0b</td><td class="column-2">1</td><td class="column-3">Attribute</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">0x0c</td><td class="column-2">1</td><td class="column-3">Reserved</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">0x0d</td><td class="column-2">1</td><td class="column-3">Creation timestamp</td>
	</tr>
	<tr class="row-7 odd">
		<td class="column-1">0x0e</td><td class="column-2">2</td><td class="column-3">Creation time</td>
	</tr>
	<tr class="row-8 even">
		<td class="column-1">0x10</td><td class="column-2">2</td><td class="column-3">Creation date</td>
	</tr>
	<tr class="row-9 odd">
		<td class="column-1">0x12</td><td class="column-2">2</td><td class="column-3">Last access date</td>
	</tr>
	<tr class="row-10 even">
		<td class="column-1">0x14</td><td class="column-2">2</td><td class="column-3">Reserved</td>
	</tr>
	<tr class="row-11 odd">
		<td class="column-1">0x16</td><td class="column-2">2</td><td class="column-3">Last modified time</td>
	</tr>
	<tr class="row-12 even">
		<td class="column-1">0x18</td><td class="column-2">2</td><td class="column-3">Last modified date</td>
	</tr>
	<tr class="row-13 odd">
		<td class="column-1">0x1a</td><td class="column-2">2</td><td class="column-3">Cluster</td>
	</tr>
	<tr class="row-14 even">
		<td class="column-1">0x1c</td><td class="column-2">4</td><td class="column-3">File size (bytes)</td>
	</tr>
</tbody>
</table>

<p>So the root directory is a list of files on disk. In order to find our kernel file, all we need to do is read it and look for the kernel filename (&#8220;KERNEL.BIN&#8221; would be good). The directory entry then tells us in which cluster the file resides.</p>
<h2>Finding a file on disk</h2>
<p>The original boot sector code for DOS and Windows 95 required that the OS kernel file (IO.SYS) be the first file in the root directory of the boot disk. This allowed the programmer to write less code: he did not have to scan the disk&#8217;s root directory looking for the file but could simply assume that the file would reside at a fixed position. We can do better, though, by actually scanning the root directory to find our file &#8211; and you will see that it&#8217;s still possible to squeeze all required code in the 448 bytes that we&#8217;re allowed to use.</p>
<ul>
<li>In order to find a file, we need to take the following steps:</li>
<li>Prepare a memory area to load sectors of the root directory into (one sector at a time will do)</li>
<li>Calculate the size of the root directory in sectors</li>
<li>Figure out where the root directory starts on disk (see above)</li>
<li>For each sector:
<ul>
<li>Read the sector into memory</li>
<li>Scan it to see if it contains the filename we&#8217;re looking for</li>
<li>If found, calculate its starting sector and file size</li>
</ul>
</li>
<li>If not found, the boot process fails</li>
</ul>
<h3>Root directory size</h3>
<p>The size of the root directory in sectors is the number of entries it contains, times 32 bytes:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="co1"># The number of sectors that the root directory occupies</span>
<span class="co1"># is equal to its max number of entries, times 32 bytes per</span>
<span class="co1"># entry, divided by sector size.</span>
<span class="co1"># E.g. (32 * rootsize) / 512</span>
<span class="co1"># This normally yields 14 sectors on a FAT12 disk.</span>
<span class="co1"># We calculate this total, then store it in cx for later use in a loop.</span>
<span class="kw1">mov</span>     <span class="kw3">ax</span><span class="sy0">,</span> <span class="nu0">32</span>
<span class="kw1">xor</span>     <span class="kw3">dx</span><span class="sy0">,</span> <span class="kw3">dx</span>
<span class="kw1">mul</span>     <span class="kw5">word</span> ptr iRootSize
<span class="kw1">div</span>     <span class="kw5">word</span> ptr iSectSize          <span class="co1"># Divide (dx:ax,sectsize) to (ax,dx)</span>
<span class="kw1">mov</span>     <span class="kw3">cx</span><span class="sy0">,</span> <span class="kw3">ax</span>
<span class="kw1">mov</span>     root_scts<span class="sy0">,</span> <span class="kw3">cx</span>
<span class="co1"># root_scts is now the number of sectors in the root directory.</span></pre></div></div></div></div></div></div></div>


<h3>Root directory start</h3>
<p>To get started, we&#8217;ll first need to know where the root directory begins. The information we need is in the boot sector, where the following values are important:</p>
<ul>
<li>Number of FAT tables (2)</li>
<li>Number of sectors per FAT (9)</li>
<li>Number of reserved sectors (1)</li>
<li>Number of hidden sectors (0)</li>
</ul>
<p>The root directory comes after and reserved or hidden sectors and the file allocation table (FAT). The starting cluster of the root directory is therefore:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">root_sector = (FAT tables) * (#sectors per FAT)
            + (reserved sectors)
            + (hidden sectors)</pre></div></div></div></div></div></div></div>


<p>The one reserved sector is of, course, the boot sector. There are no hidden sectors on our disk.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="co1"># Calculate start sector root directory:</span>
<span class="co1"># root_strt = number of FAT tables * sectors per FAT</span>
<span class="co1">#           + number of hidden sectors</span>
<span class="co1">#           + number of reserved sectors</span>
<span class="kw1">xor</span>   <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">ax</span>                      <span class="co1"># find the root directory</span>
<span class="kw1">mov</span>   <span class="kw3">al</span><span class="sy0">,</span> <span class="kw5">byte</span> ptr iFatCnt        <span class="co1"># ax = number of FAT tables</span>
<span class="kw1">mov</span>   <span class="kw3">bx</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iFatSize       <span class="co1"># bx = sectors per FAT</span>
<span class="kw1">mul</span>   <span class="kw3">bx</span>                          <span class="co1"># ax = #FATS * sectors per FAT</span>
<span class="kw1">add</span>   <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iHiddenSect    <span class="co1"># Add hidden sectors to ax</span>
<span class="kw1">adc</span>   <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iHiddenSect<span class="sy0">+</span><span class="nu0">2</span>
<span class="kw1">add</span>   <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iResSect       <span class="co1"># Add reserved sectors to ax</span>
<span class="kw1">mov</span>   root_strt<span class="sy0">,</span> <span class="kw3">ax</span>
<span class="co1"># root_strt is now the number of the first root sector</span></pre></div></div></div></div></div></div></div>


<h3>Reading and scanning each sector</h3>
<p>We can now use the ReadSector function we developed earlier to read the sectors into memory, one by one. For each sector, we then loop through the entries and check each filename (the first 11 bytes of the directory entry) for a match:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="co1"># Load a sector from the root directory.</span>
<span class="co1"># If sector reading fails, a reboot will occur.</span>
<span class="re0">read_next_sector:</span>
<span class="kw1">push</span>   <span class="kw3">cx</span>
<span class="kw1">push</span>   <span class="kw3">ax</span>
<span class="kw1">xor</span>    <span class="kw3">bx</span><span class="sy0">,</span> <span class="kw3">bx</span>
<span class="kw1">call</span>   ReadSector
&nbsp;
<span class="re0">check_entry:</span>
<span class="kw1">mov</span>    <span class="kw3">cx</span><span class="sy0">,</span> <span class="nu0">11</span>                      <span class="co1"># Directory entries filenames are 11 bytes.</span>
<span class="kw1">mov</span>    <span class="kw3">di</span><span class="sy0">,</span> <span class="kw3">bx</span>                      <span class="co1"># es:di = Directory entry address</span>
<span class="kw1">lea</span>    <span class="kw3">si</span><span class="sy0">,</span> \filename               <span class="co1"># ds:si = Address of filename we are looking for.</span>
<span class="kw1">repz</span>   <span class="kw1">cmpsb</span>                       <span class="co1"># Compare filename to memory.</span>
<span class="kw1">je</span>     found_file                  <span class="co1"># If found, jump away.</span>
<span class="kw1">add</span>    <span class="kw3">bx</span><span class="sy0">,</span> <span class="kw5">word</span> ptr <span class="nu0">32</span>             <span class="co1"># Move to next entry. Entries are 32 bytes.</span>
<span class="kw1">cmp</span>    <span class="kw3">bx</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iSectSize      <span class="co1"># Have we moved out of the sector yet?</span>
<span class="kw1">jne</span>    check_entry                 <span class="co1"># If not, try next directory entry.</span>
&nbsp;
<span class="kw1">pop</span>    <span class="kw3">ax</span>
<span class="kw1">inc</span>    <span class="kw3">ax</span>                          <span class="co1"># check next sector when we loop again</span>
<span class="kw1">pop</span>    <span class="kw3">cx</span>
<span class="kw1">loopnz</span> read_next_sector            <span class="co1"># loop until either found or not</span>
<span class="kw1">jmp</span>    bootFailure                 <span class="co1"># could not find file: abort</span></pre></div></div></div></div></div></div></div>


<h3>Getting the file start position</h3>
<p>Now that we have found the root directory entry for the kernel file, we need to get from it the position of the file (the cluster number) :</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1">  <span class="re0">found_file:</span>
    <span class="co1"># The directory entry stores the first cluster number of the file</span>
    <span class="co1"># at byte 26 (0x1a). BX is still pointing to the address of the start</span>
    <span class="co1"># of the directory entry, so we will go from there.</span>
    <span class="co1"># Read cluster number from memory:</span>
    <span class="kw1">mov</span>    <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">es</span><span class="sy0">:</span><span class="br0">&#91;</span><span class="kw3">bx</span><span class="sy0">+</span><span class="nu0">0x1a</span><span class="br0">&#93;</span>
    <span class="kw1">mov</span>    file_strt<span class="sy0">,</span> <span class="kw3">ax</span></pre></div></div></div></div></div></div></div>


<p>The end result is that <strong>file_strt</strong> contains the file&#8217;s starting cluster number.</p>
<h2>FAT Clusters</h2>
<p>All right, after all this digging through the disk&#8217;s root directory, we&#8217;ve found our file and we&#8217;ve got a <strong>cluster number</strong> in hand. However, so far we&#8217;ve only talked about sectors, not <strong>clusters</strong> (you can safely ignore the cylinder, track and head story from here on &#8211; they have nothing to do with it). A cluster is another logical structure introduced by FAT.</p>
<p>The idea is that in FAT, a file may occupy a number of sectors. And most files certainly will, because one sector is only 512 bytes. Files on disk will often be much larger than that! So imagine that we have a disk with two of files on it. They&#8217;re both 3 sectors in size, and they were physically written to the disk so as to occupy precisely the first 6 sectors of the data area. Now, the first file is deleted. That means we now have 3 empty sectors at the start of the data area. Next, a new file, 4 sectors in size, is copied onto the disk. Where does it go? There&#8217;s no space to put new file before the remaining existing file, since there&#8217;s only space for 3 sectors. We can only place the new file after the existing file. Maybe at some point a user will want to write a 3-sector file that can fill the gap!</p>
<p>Naturally, if you consider writing and deleting lots of files on a disk, this will leave the file system fragmented and with lots of gaps that we can&#8217;t use. And this is where FAT comes in. With FAT, a file that occupies multiple sectors on disk may be broken up into non-contiguous sectors. So a 3-sector file could occupy physical sectors 40, 21 and 304. The bits and pieces can go wherever there is space and all available space is used to the fullest.</p>
<p>The problem then is administration. How does FAT know where the loose pieces of each file are? For this, the FAT system uses its namesake, the <strong>File Allocation Table</strong>. This table lives right before the root directory and contains an index of all the sectors on the disk. There are actually two copies of the FAT on every disk: one is a backup, for safety. You&#8217;ll see that the bootsector actually contains a field with the number of FAT tables on the disk.</p>
<p>The FAT table is actually an index of linked lists of sectors (hello?). An example illustrates how this works. Imagine we have a disk with 10 data sectors on it (we&#8217;re ignoring the sectors occupied by boot sector, root directory, FAT etc., and the fact that 10 sectors is a really small disk):</p>

<table id="wp-table-reloaded-id-5-no-1" class="wp-table-reloaded wp-table-reloaded-id-5">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Sector</th><th class="column-2">FAT-Value</th>
	</tr>
</thead>
<tbody class="row-hover">
	<tr class="row-2 even">
		<td class="column-1">0</td><td class="column-2">0x001</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">1</td><td class="column-2">0x004</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">2</td><td class="column-2">0xFF8</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">3</td><td class="column-2">0x007</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">4</td><td class="column-2">0x006</td>
	</tr>
	<tr class="row-7 odd">
		<td class="column-1">5</td><td class="column-2">0x000</td>
	</tr>
	<tr class="row-8 even">
		<td class="column-1">6</td><td class="column-2">0xFF8</td>
	</tr>
	<tr class="row-9 odd">
		<td class="column-1">7</td><td class="column-2">0xFF8</td>
	</tr>
	<tr class="row-10 even">
		<td class="column-1">8</td><td class="column-2">0x000</td>
	</tr>
	<tr class="row-11 odd">
		<td class="column-1">9</td><td class="column-2">0xFF7</td>
	</tr>
</tbody>
</table>

<p>There are actually three files on this disk. From the root directory we get:</p>
<ul>
<li>File 1 &#8211; cluster index = 0</li>
<li>File 2 &#8211; cluster index = 2</li>
<li>File 3 &#8211; cluster index = 3</li>
</ul>
<p>The directory entry for file 1 points to cluster index 0. In the FAT table, the value for this index is 0&#215;001: it points to index 1. Index 1&#8242;s value is 0&#215;004: it points to index 4. Index 4&#8242;s value is 0&#215;006: is points to index 6. Index 6&#8242;s value, finally, is 0xff8, a special value which means that it is the last index of the file.</p>
<p>What this all means is that file 1 occupies sectors 0, 1, 4 and 6. Actually, sector 0 is actually the sector <em>after</em> the root directory on the disk, but that&#8217;s a detail.</p>
<p>For file 2 we can now determine that it occupies only one sector (sector 2). The FAT-value for this index is 0xFf8, so there are no more sectors.</p>
<p>For file 3, we see that it occupies sectors 3 and 7. You&#8217;ll get the idea by now.</p>
<ul>
<li>Some of the FAT indices have the value 0. That means that the sector is free.</li>
<li>Any value of 0xff8 or higher means end-of-file</li>
<li>A value of 0xff7 means the sector is bad and should not be used.</li>
</ul>
<p>A cluster, therefore, is a linked list where each entry points to the next, until the end of the cluster. Each entry relates to an actual physical sector on disk. When reading a file, we&#8217;ll have to follow its FAT cluster and read each corresponding sector into memory.</p>
<p>It sounds simple enough, after all, but there&#8217;s a catch: the FAT entries occupy 12 bits each (a byte and a half), which will make reading and using the data bit tricky later. You will now see that since each the FAT consists of 9 sectors, it can address 9*512/1.5 = 3072 sectors, which is more than enough, since our disk has 1440 sectors.</p>
<h3>Reading the FAT</h3>
<p>The FAT lives on the disk, and in order to access it, we&#8217;ll have to get it in memory first. The following code does just that: it loads the FAT into a memory segment (I use segment 0x0ee0, so as to place it just under where I&#8217;ll be loading the next file):</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="co1"># The FAT will be loaded in a special segment.</span>
<span class="co1"># Set ES to this segment.</span>
<span class="kw1">mov</span>   <span class="kw3">ax</span><span class="sy0">,</span> \fatsegment
<span class="kw1">mov</span>   <span class="kw3">es</span><span class="sy0">,</span> <span class="kw3">ax</span>
&nbsp;
<span class="co1"># Calculate offset of FAT:</span>
<span class="kw1">mov</span>   <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iResSect       <span class="co1"># Add reserved sectors to ax</span>
<span class="kw1">add</span>   <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iHiddenSect    <span class="co1"># Add hidden sectors to ax</span>
<span class="kw1">adc</span>   <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iHiddenSect<span class="sy0">+</span><span class="nu0">2</span>
&nbsp;
<span class="co1"># Read all FAT sectors into memory:</span>
<span class="kw1">mov</span>   <span class="kw3">cx</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iFatSize       <span class="co1"># Number of sectors in FAT</span>
<span class="kw1">xor</span>   <span class="kw3">bx</span><span class="sy0">,</span> <span class="kw3">bx</span>                      <span class="co1"># Memory offset to read into (es:bx)</span>
<span class="re0">read_next_fat_sector:</span>
<span class="kw1">push</span>  <span class="kw3">cx</span>
<span class="kw1">push</span>  <span class="kw3">ax</span>
<span class="kw1">call</span>  ReadSector
<span class="kw1">pop</span>   <span class="kw3">ax</span>
<span class="kw1">pop</span>   <span class="kw3">cx</span>
<span class="kw1">inc</span>   <span class="kw3">ax</span>
<span class="kw1">add</span>   <span class="kw3">bx</span><span class="sy0">,</span> <span class="kw5">word</span> ptr iSectSize
<span class="kw1">loopnz</span> read_next_fat_sector       <span class="co1"># continue with next sector</span></pre></div></div></div></div></div></div></div>


<p>After this code has executed, all 9 sectors of the FAT now live in memory at 0ee0:0000.</p>
<h2>Reading a file</h2>
<p>With out FAT in memory, we are not ready to read a file from disk. By scanning the root directory we had earlier determined the starting index in the FAT table, so we&#8217;re good to go:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="co1"># Set memory segment that will receive the file:</span>
<span class="kw1">mov</span>     <span class="kw3">ax</span><span class="sy0">,</span> \loadsegment
<span class="kw1">mov</span>     <span class="kw3">es</span><span class="sy0">,</span> <span class="kw3">ax</span>
<span class="co1"># Set memory offset for loading to 0.</span>
<span class="kw1">xor</span>     <span class="kw3">bx</span><span class="sy0">,</span> <span class="kw3">bx</span>
&nbsp;
<span class="co1"># Set memory segment for FAT:</span>
<span class="kw1">mov</span>     <span class="kw3">cx</span><span class="sy0">,</span> file_strt             <span class="co1"># CX now points to file's first FAT entry</span>
&nbsp;
<span class="re0">read_file_next_sector:</span>
<span class="co1"># Locate sector:</span>
<span class="kw1">mov</span>     <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">cx</span>                    <span class="co1"># Sector to read is equal to current FAT entry</span>
<span class="kw1">add</span>     <span class="kw3">ax</span><span class="sy0">,</span> root_strt             <span class="co1"># Plus the start of the root directory</span>
<span class="kw1">add</span>     <span class="kw3">ax</span><span class="sy0">,</span> root_scts             <span class="co1"># Plus the size of the root directory</span>
<span class="kw1">sub</span>     <span class="kw3">ax</span><span class="sy0">,</span> <span class="nu0">2</span>                     <span class="co1"># ... but minus 2</span>
&nbsp;
<span class="co1"># Read sector:</span>
<span class="kw1">push</span>    <span class="kw3">cx</span>                        <span class="co1"># Read a sector from disk, but save CX</span>
<span class="kw1">call</span>    ReadSector                <span class="co1"># as it contains our FAT entry</span>
<span class="kw1">pop</span>     <span class="kw3">cx</span>
<span class="kw1">add</span>     <span class="kw3">bx</span><span class="sy0">,</span> iSectSize             <span class="co1"># Move memory pointer to next section</span>
&nbsp;
<span class="co1"># Get next sector from FAT:</span>
<span class="kw1">push</span>    <span class="kw3">ds</span>                        <span class="co1"># Make DS:SI point to FAT table</span>
<span class="kw1">mov</span>     <span class="kw3">dx</span><span class="sy0">,</span> \fatsegment           <span class="co1"># in memory.</span>
<span class="kw1">mov</span>     <span class="kw3">ds</span><span class="sy0">,</span> <span class="kw3">dx</span>
&nbsp;
<span class="kw1">mov</span>     <span class="kw3">si</span><span class="sy0">,</span> <span class="kw3">cx</span>                    <span class="co1"># Make SI point to the current FAT entry</span>
<span class="kw1">mov</span>     <span class="kw3">dx</span><span class="sy0">,</span> <span class="kw3">cx</span>                    <span class="co1"># (offset is entry value * 1.5 bytes)</span>
<span class="kw1">shr</span>     <span class="kw3">dx</span>
<span class="kw1">add</span>     <span class="kw3">si</span><span class="sy0">,</span> <span class="kw3">dx</span>
&nbsp;
<span class="kw1">mov</span>     <span class="kw3">dx</span><span class="sy0">,</span> <span class="kw3">ds</span><span class="sy0">:</span><span class="br0">&#91;</span><span class="kw3">si</span><span class="br0">&#93;</span>               <span class="co1"># Read the FAT entry from memory</span>
<span class="kw1">test</span>    <span class="kw3">dx</span><span class="sy0">,</span> <span class="nu0">1</span>                     <span class="co1"># See which way to shift</span>
<span class="kw1">jz</span>      read_next_file_even
<span class="kw1">and</span>     <span class="kw3">dx</span><span class="sy0">,</span> <span class="nu0">0x0fff</span>
<span class="kw1">jmp</span>     read_next_file_cluster_done
<span class="re0">read_next_file_even:</span>
<span class="kw1">shr</span>     <span class="kw3">dx</span><span class="sy0">,</span> <span class="nu0">4</span>
<span class="re0">read_next_file_cluster_done:</span>
<span class="kw1">pop</span>     <span class="kw3">ds</span>                        <span class="co1"># Restore DS to the normal data segment</span>
<span class="kw1">mov</span>     <span class="kw3">cx</span><span class="sy0">,</span> <span class="kw3">dx</span>                    <span class="co1"># Store the new FAT entry in CX</span>
<span class="kw1">cmp</span>     <span class="kw3">cx</span><span class="sy0">,</span> <span class="nu0">0xff8</span>                 <span class="co1"># If the FAT entry is greater or equal</span>
<span class="kw1">jl</span>      read_file_next_sector     <span class="co1"># to 0xff8, then we've reached end-of-file</span></pre></div></div></div></div></div></div></div>


<p>What happens here is that we start with <em>cx</em> = first sector of file (we know this from the root directory after all). We read that sector into memory, then use the cx value to access the corresponding index in the FAT. There&#8217;s a bit of trickiness where we juggle with the 12-bits issue, but then all that remains is whether to continue reading, or stop because end-of-file (FAT-entry 0xff8 or higher) was reached.</p>
<h1>Summary</h1>
<p>From a bare-bones boot loader, we&#8217;ve now come to a point where we can load the kernel (or rather the second-stage boot loader &#8211; this will become clear later on)! We&#8217;ve seen how the root directory and FAT work, and neatly read both to load the required file from disk. Since we squeezed all this functionality in, the file we&#8217;re loading can actually live anywhere in the root of the disk. Gone is the requirement for SYS.COM that DOS and Windows imposed. In our future OS, making a disk bootable should not require a formatting operation. Writing a boot sector and simply coping the OS files onto the disk will suffice.</p>
<p>So far I&#8217;ve shown here some sections of code that still need to be sewn together. In the next part of this guide, we&#8217;ll add a small kernel (something along the lines of &#8220;hello world&#8221;) to be loaded and executed. We&#8217;ll then have a complete source that can be compiled and run on Bochs (or from a floppy disk if you&#8217;re hardcore).</p>
<p>Continue to <a title="Writing your own bootloader for a toy operating system (5)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-5/">part 5</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-4/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Writing your own bootloader for a toy operating system (3)</title>
		<link>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/</link>
		<comments>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/#comments</comments>
		<pubDate>Wed, 11 Apr 2012 14:11:51 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Operating System Development]]></category>
		<category><![CDATA[Bochs]]></category>
		<category><![CDATA[boot sector]]></category>
		<category><![CDATA[bootloader]]></category>
		<category><![CDATA[BPB]]></category>
		<category><![CDATA[disk image]]></category>
		<category><![CDATA[EBPB]]></category>
		<category><![CDATA[GNU as]]></category>
		<category><![CDATA[GNU ld]]></category>
		<category><![CDATA[imagefs]]></category>
		<category><![CDATA[Intel]]></category>
		<category><![CDATA[toy operating system]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=272</guid>
		<description><![CDATA[This article is part of a short series. Here are part 1, part 2 and part 4. In part 2 of this guide to writing your own toy operating system, we set it to write our own (floppy) disk boot &#8230;<p class="read-more"><a href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>This article is part of a short series. Here are <a title="Writing your own boot loader for a toy operating system (1)" href="http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/">part 1</a>, <a title="Writing your own bootloader for a toy operating system (2)" href="http://www.websofia.com/2011/10/writing-your-own-bootloader-for-a-toy-operating-system-2/">part 2</a> and <a title="Writing your own bootloader for a toy operating system (4)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-4/">part 4</a>.<br />
</strong></p>
<p>In part 2 of this guide to writing your own toy operating system, we set it to write our own (floppy) disk boot sector in assembly code. We ended up with a piece of code that writes a message to the screen, initializes the drive system, waits for a key press, and reboots. Before we move in, let&#8217;s create a development environment: a toolset that we can use to compile and test our code repeatedly (and when fiddling with low-level assembly code, you&#8217;ll find that &#8220;repeatedly&#8221; is the operative word here).</p>
<p>Our code so far was written in for the <strong>GNU assembler</strong>, <em><strong>as</strong></em>, although we use the Intel syntax (which GNU supports) as this is easier on the eyes for most people (I like the GNU syntax, but if you&#8217;ve never used it, you&#8217;ll find that it requires looking at everything upside down). The GNU assembler is free, and any other tools we&#8217;ll use will also be free.</p>
<p>We&#8217;ll also use <strong>Windows</strong> as our development platform, which we&#8217;ll require some extra work to set things up.</p>
<h2>Assembling &amp; linking</h2>
<p>Assembling code turns that code into an object file. An object file contains machine code that the processor can execute. But before that, the object file must be linked into an executable. This is because programs in assembly code (or any other language) more often than not consist of many source files, which must be combined into one executable. The tool responsible for putting it all together is called a <strong>linker</strong>. It joins up all the code, and makes sure that all the references in that code (jumps, variables, memory references) actually point to the correct spot. It does all the math required to turn all references into numbers, so you don&#8217;t have to (a very good thing).</p>
<p>So: the next tool we&#8217;ll be using is the GNU linker, <strong>ld</strong>.</p>
<h2>Getting the GNU toolchain: MinGW</h2>
<p>The GNU assembler and the GNU linker are ideal tools for our purposes, but they are not readily available for Windows. You&#8217;ll find as and ld on any UNIX/Linux system, but not on Windows. Of course we could decide to use some Windows-based assembler, but these assembler simply don&#8217;t have enough switches to fiddle with, so it&#8217;s GNU or nothing.</p>
<p>Luckily, we have two options: <strong>Cygwin</strong> and <strong>MinGW</strong>. Both are complete GNU toolsets that were compiled for and run on Windows. Cygwin requires that you work in a special shell, while MinGW (&#8220;Minimalist GNU for Windows&#8221;) can be used directly from the ordinary Windows command line, which is how I like it. (You can still opt for Cygwin, it shouldn&#8217;t make any difference). So go and get a copy of <a title="MinGW" href="http://www.mingw.org/">MinGW</a> here (or <a href="http://sourceforge.net/projects/mingw/files/">here</a> for direct download) and install it. I&#8217;ll wait.</p>
<p>After installing MinGW, don&#8217;t forget to set your <strong>PATH</strong> to include your MinGW&#8217;s /bin directory. That way you&#8217;ll have access to <strong>as</strong>, <strong>ld</strong> and <strong>make</strong> from your shell.</p>
<h2>Compiling the code</h2>
<p>Now that we have MinGW, we can open a shell and find our code file (let&#8217;s call it <em>boot.s</em>). Here&#8217;s how we assemble the code:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">as -o boot.o boot.s</pre></div></div></div></div></div></div></div>


<p>This will turn boot.s into boot.o.</p>
<p>Now to link it:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">ld -o boot.out boot.o -Ttext 0x7c00
objcopy -O binary -j .text boot.out boot.bin</pre></div></div></div></div></div></div></div>


<p>That&#8217;s a mouthful. Here, we use the GNU linker to create a linked intermediary file. Normally, we could tell the linker which output format it should produce, and there are quite a few of those (Windows PE, Linux ELF, flat binary etc.). What we want is for the linker to produce a flat binary: no operating-system specific headers, just the code. And that&#8217;s just what we cannot do.</p>
<p>This is where <strong>objcopy</strong> comes in. It takes the linker output, strips off any headers and leaves us with a flat binary with just the code. It produces, in fact, a file of 532 bytes (on my computer), which is 20 bytes too many. Closer inspection with a hex editor shows that the code is in fact exactly 512 bytes and ld/objcopy added 20 excess bytes that we can ignore. (I have yet to find out why &#8211; when I compiled similar code some years ago this did not happen. Also see <a title="Linking a flat binary from C with MinGW" href="http://www.websofia.com/2011/10/linking-a-flat-binary-from-c-with-mingw/">this post</a>.)</p>
<p>What we have now produced is exactly like a .com file in the olden days of DOS gone by. These files (as opposed to .exe files) also included just the code. You could run one, and DOS would know what to do with it. No such luck now: if you run your file (renaming it to .com or .exe) you&#8217;ll get this:</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/04/boot.jpg"><img class="alignnone size-full wp-image-276" title="Boot problems" src="http://www.websofia.com/wp-content/uploads/2012/04/boot.jpg" alt="" width="394" height="139" /></a></p>
<p>Of course, this is a good thing, because our code would bring Windows down if it were allowed to execute. Also, our code was written for 16-bits real mode, and your Windows computer is in protected mode. Thus, our boot loader can only be tested if we were to actually boot our computer with it, or within some sort of simulator (we can actually do both).</p>
<h1>Bochs</h1>
<p>There actually exists a simulator that we can use for our purposes. The good people of <a href="http://bochs.sourceforge.net/">Bochs</a> (&#8220;The Open Source IA-32 Emulation Project&#8221;) have produced a program that precisely simulates a computer with an Intel processor, loaded with a BIOS ROM and with support for common I/O devices. Bochs can run old DOS versions by running image files of the old DOS floppy disks, and we can do the same. If we can produce an image file of a floppy disk with our boot sector on it, then we&#8217;re good to go!</p>
<p>Now would be a good time to download and install <a href="http://bochs.sourceforge.net/">Bochs</a> if you haven&#8217;t already done so.</p>
<h2>Making a disk image</h2>
<p>The final tool we&#8217;ll need for now is tool that can help us create a disk image with a custom boot sector. <strong>rawrite</strong> is such a tool, but it&#8217;s not available for Windows (although <a href="http://www.chrysocome.net/rawwrite">here</a> is an implementation for Windows, but it doesn&#8217;t take command-line argument so it can&#8217;t be used in an automated build process). I rolled my own at some point and the result was <a href="http://www.websofia.com/wp-content/uploads/2012/04/imagefs.exe">ImageFS</a> (you can download it here). Its usage is:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">Usage:
imagefs [c/create] [image file name] [number of sectors]
imagefs [b/boot]   [image file name] [bootsector file name]
imagefs [a/add]    [image file name] [file] [more files]
imagefs [r/remove] [image file name] [file] [more files]
imagefs [d/dir]    [image file name]</pre></div></div></div></div></div></div></div>


<p>To create a disk image, do this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="bash"><pre class="de1">imagefs c test.img <span class="nu0">720</span>
imagefs b test.img boot.bin</pre></div></div></div></div></div></div></div>


<p>You&#8217;ll get:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="text"><pre class="de1">C:\code\os\boot) imagefs c test.img 720
Create new image file [test.img] with [720] sectors.
Image opened, current size is 0 sectors.
Formatted 720 sectors with fill character ÷.
&nbsp;
C:\code\os\boot) imagefs b test.img boot.bin
Write boot sector [boot.bin] to image file [test.img].
Image opened, current size is 720 sectors.
Warning: boot sector file (532 bytes) is larger than one sector (512 bytes).
- skipping excess bytes.
Boot sector copied successfully.</pre></div></div></div></div></div></div></div>


<p>This creates an empty floppy disk of 720 KB and stores our boot sector on it.</p>
<h2>Running the simulator</h2>
<p>Now run Bochs. You&#8217;ll get the emulator&#8217;s start menu. From it, select &#8220;Disk &amp; Boot&#8221; <em>before</em> you hit Start. Fill out the following:</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/04/bochs-disk-options1.jpg"><img class="alignnone size-full wp-image-312" title="Bochs disk options" src="http://www.websofia.com/wp-content/uploads/2012/04/bochs-disk-options1.jpg" alt="" width="561" height="584" /></a></p>
<p>In particular, don&#8217;t forget to set your boot disk as &#8220;<strong>inserted</strong>&#8220;! Now hit <strong>Start</strong> and watch your code work:</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/04/bochs-bootup.jpg"><img class="alignnone size-full wp-image-296" title="Bochs running our boot loader" src="http://www.websofia.com/wp-content/uploads/2012/04/bochs-bootup.jpg" alt="" width="740" height="509" /></a></p>
<p>Note that you can access Bochs&#8217;s log file to see the boot procedure in more detail, and if it crashes, you can see why.</p>
<p>If you want, you can actually run this code from a real floppy disk on a real computer. For this, you&#8217;ll need <strong>rawrite</strong> to write your boot sector to the disk. After that, you should be able to boot your computer with it (if you actually have a floppy drive).</p>
<h2>Summary</h2>
<p>We now have the tools in place that we need to develop our boot sector further. The Bochs simulator allows us to test our code. In the next section, we&#8217;ll flesh out our boot loader with code that finds and loads our kernel file. Since we&#8217;ll be using multiple source files, we&#8217;ll also begin using <strong>GNU make</strong> to automate our build process.</p>
<h2>Resources</h2>
<ul>
<li>MinGW: <a href="http://www.mingw.org/">home page</a>, <a href="http://sourceforge.net/projects/mingw/files/">download</a></li>
<li>Cygwin: <a href="www.cygwin.com/">home page</a></li>
<li>Bochs: <a href="http://bochs.sourceforge.net/">home page</a></li>
<li>ImageFS: <a href="http://www.websofia.com/wp-content/uploads/2012/04/imagefs.exe">direct download</a></li>
</ul>
<p>Continue to <a title="Writing your own bootloader for a toy operating system (4)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-4/">part 4</a> of this guide!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>My Android app does not scale on a Samsung Galaxy Tab</title>
		<link>http://www.websofia.com/2012/03/my-android-app-does-not-scale-on-a-samsung-galaxy-tab/</link>
		<comments>http://www.websofia.com/2012/03/my-android-app-does-not-scale-on-a-samsung-galaxy-tab/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 09:25:04 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Processing App]]></category>
		<category><![CDATA[Samsung Galaxy Tab]]></category>
		<category><![CDATA[Scale]]></category>
		<category><![CDATA[Strech]]></category>
		<category><![CDATA[Zoom]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=255</guid>
		<description><![CDATA[I had built an Android app requiring a minimum Android SDK of 3 (Android version 1.5), in order to make sure that it would run on as many platforms as possible &#8211; and it does. It even runs on a &#8230;<p class="read-more"><a href="http://www.websofia.com/2012/03/my-android-app-does-not-scale-on-a-samsung-galaxy-tab/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I had built an Android app requiring a minimum Android SDK of 3 (Android version 1.5), in order to make sure that it would run on as many platforms as possible &#8211; and it does. It even runs on a Samsung Galaxy Tab, so I rejoiced. However, on the tablet, the app shows up very tiny, using the resolution it would have on a mobile phone.</p>
<p>Now on an iPad, I know that apps developed for the iPhone can be &#8220;zoomed 2x&#8221;, thus filling the iPad screen nicely. It would naturally be better to produce a HD version of the app, but at least zooming allows the original app to be readable. This doesn&#8217;t happen with Android. Google says it will add a zoom feature in Android 3.2, but since my tablet (and others) uses Android 3.1, it doesn&#8217;t solve my problem.</p>
<p>I did however find a way to stretch (not zoom) the app on a tablet. Apparently stretching is only possible from SDK version 7 onwards. Setting the minimum SDK level in your Android manifest to 7 will do the trick:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="xml"><pre class="de1"><span class="sc3"><span class="re1">&lt;uses-sdk</span> <span class="re0">android:minSdkVersion</span>=<span class="st0">&quot;7&quot;</span> <span class="re2">/&gt;</span></span></pre></div></div></div></div></div></div></div>


<p>Now the app stretches on the tablet, at least using all screen real estate available. It&#8217;s not pretty, since the controls remain small. Apparently the way to go is creating a Processing app, as explained <a href="http://realmike.org/blog/2010/12/21/multiple-screen-sizes-with-processing-for-android/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2012/03/my-android-app-does-not-scale-on-a-samsung-galaxy-tab/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple XML yields ClassNotFoundException on Android</title>
		<link>http://www.websofia.com/2012/03/simple-xml-yields-classnotfoundexception-on-android/</link>
		<comments>http://www.websofia.com/2012/03/simple-xml-yields-classnotfoundexception-on-android/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 09:16:24 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[ClassLoader]]></category>
		<category><![CDATA[ClassNotFoundException]]></category>
		<category><![CDATA[Polymorphism]]></category>
		<category><![CDATA[Simple XML]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=250</guid>
		<description><![CDATA[I&#8217;m writing an Android app that uses Simple XML to parse XML directly into class instances. Simple XML works wonders, but a problem occurs when using polymorphism. My application stores and retrieves surveys. A survey contains a list of questions, &#8230;<p class="read-more"><a href="http://www.websofia.com/2012/03/simple-xml-yields-classnotfoundexception-on-android/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m writing an Android app that uses Simple XML to parse XML directly into class instances. Simple XML works wonders, but a problem occurs when using polymorphism. My application stores and retrieves surveys. A survey contains a list of questions, and questions can be of various types. There are text questions, numeric questions, list questions etc. Polymorphism is used to implement all these question types. The following XML snippet illustrates this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="xml"><pre class="de1"><span class="sc3"><span class="re1">&lt;Survey<span class="re2">&gt;</span></span></span>
  <span class="sc3"><span class="re1">&lt;Questions<span class="re2">&gt;</span></span></span>
    <span class="sc3"><span class="re1">&lt;Question</span> <span class="re0">class</span>=<span class="st0">&quot;SingeLineQuestion&quot;</span><span class="re2">&gt;</span></span>
      <span class="sc3"><span class="re1">&lt;Title<span class="re2">&gt;</span></span></span>What is your name?<span class="sc3"><span class="re1">&lt;/Title<span class="re2">&gt;</span></span></span>
      <span class="sc3"><span class="re1">&lt;MaxLength<span class="re2">&gt;</span></span></span>50<span class="sc3"><span class="re1">&lt;/MaxLength<span class="re2">&gt;</span></span></span>
    <span class="sc3"><span class="re1">&lt;/Question<span class="re2">&gt;</span></span></span>
    <span class="sc3"><span class="re1">&lt;Question</span> <span class="re0">class</span>=<span class="st0">&quot;NumericQuestion&quot;</span><span class="re2">&gt;</span></span>
      <span class="sc3"><span class="re1">&lt;Title<span class="re2">&gt;</span></span></span>How old are you?<span class="sc3"><span class="re1">&lt;/Title<span class="re2">&gt;</span></span></span>
      <span class="sc3"><span class="re1">&lt;Minimum<span class="re2">&gt;</span></span></span>10<span class="sc3"><span class="re1">&lt;/Minimum<span class="re2">&gt;</span></span></span>
      <span class="sc3"><span class="re1">&lt;Maximum<span class="re2">&gt;</span></span></span>80<span class="sc3"><span class="re1">&lt;/Maximum<span class="re2">&gt;</span></span></span>
    <span class="sc3"><span class="re1">&lt;/Question<span class="re2">&gt;</span></span></span>
  <span class="sc3"><span class="re1">&lt;/Questions<span class="re2">&gt;</span></span></span>
<span class="sc3"><span class="re1">&lt;/Survey<span class="re2">&gt;</span></span></span></pre></div></div></div></div></div></div></div>


<p>The survey contains a list of question instances, and upon saving the XML, Simple XML has added an attribute to each question stating what the actual Question class is (e.g. class=&#8221;SingleLineQuestion&#8221;).</p>
<p>The problem is this: loading a survey into memory actually works perfectly on Android 1.5, but fails on Android 2.1 and higher. It produces a ClassNotFound exception:</p>
<pre>java.lang.ClassNotFoundException: SingleLineQuestion
in loader dalvik.system.PathClassLoader@4001b605</pre>
<p>What is happening? Studying the source of Simple XML shows that the required SingleLineQuestion question is instantiated using a ClassLoader. This ClassLoader may run in a different thread context than the main code, and therefore it cannot find the required class to load. This may happen when Simple XML gets called through an synchronous request in order to avoid the application from blocking.</p>
<p>In order to make sure that Simple XML has access to the correct class loader, you can do this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="java"><pre class="de1"><span class="kw3">Thread</span>.<span class="me1">currentThread</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">setContextClassLoader</span><span class="br0">&#40;</span>context.<span class="kw1">class</span>.<span class="me1">getClassLoader</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span>
Serializer serializer <span class="sy0">=</span> <span class="kw1">new</span> Persister<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span>
...</pre></div></div></div></div></div></div></div>


<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2012/03/simple-xml-yields-classnotfoundexception-on-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Engrish in Mozambique</title>
		<link>http://www.websofia.com/2012/01/engrish-in-mozambique/</link>
		<comments>http://www.websofia.com/2012/01/engrish-in-mozambique/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 14:55:07 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=244</guid>
		<description><![CDATA[I&#8217;m an expat in Mozambique, and I&#8217;d like to share a little bit of this wonderful country with you in the form of our local &#8220;Engrish&#8221;, for lack of a better term. Sometimes business try to communicate to people whose &#8230;<p class="read-more"><a href="http://www.websofia.com/2012/01/engrish-in-mozambique/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m an expat in Mozambique, and I&#8217;d like to share a little bit of this wonderful country with you in the form of our local &#8220;Engrish&#8221;, for lack of a better term. Sometimes business try to communicate to people whose first language isn&#8217;t Portuguese, which is the official language here. The result might be called Menglish, maybe, but I&#8217;ll just go with Engrish here. Here is a list of fun stuff:</p>
<h2>Fun at the Water Park</h2>
<p>The local &#8220;Adil&#8221; water park shares some goodness:</p>
<blockquote><p>&#8220;We will not tolerate any offense against public morals, ethics and lack of bad behavior on the grounds of the park.&#8221;</p></blockquote>
<p>That&#8217;s right. ethics are good, but bad behavior is better.</p>
<h2>Resumé gems</h2>
<p>Excerpt from a great cover letter (sent to 100+ organizations &#8211; To, not BCC):</p>
<blockquote><p>Waiting for Your Excellency the greatest consideration and care to nurture more professional experience, hereby express their willingness to join in your workgroup.</p></blockquote>
<p>Naturally closely followed by this, in case there were any lingering doubts:</p>
<blockquote><p>English: Spoken and written fluently.</p></blockquote>
<p>Also lifted from a CV:</p>
<blockquote><p>Curso de Inglês no JEMES INGLiSH SCHOOL ΙΙ nivel;</p></blockquote>
<h2>We&#8217;d like to introduse herbly our company</h2>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/01/dk-1.jpg"><img class="alignnone size-full wp-image-259" title="Dear Sirs" src="http://www.websofia.com/wp-content/uploads/2012/01/dk-1.jpg" alt="Dear Sirs" width="782" height="70" /></a></p>
<p>Oh good. What does your company do then?</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/01/dk-2.jpg"><img class="alignnone size-full wp-image-261" title="Trainnings" src="http://www.websofia.com/wp-content/uploads/2012/01/dk-2.jpg" alt="" width="680" height="26" /></a></p>
<p>(Yes, it&#8217;s hard to read. The email was sent as an image.) It&#8217;s nice to know that the &#8220;trainnings&#8221; will be offered by world-renowned experts. Somehow I do hope that these industry and academia giants did not write this introduction letter. But fear not, we are in good hands:</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/01/dk-3.jpg"><img class="alignnone size-full wp-image-262" title="We care your business" src="http://www.websofia.com/wp-content/uploads/2012/01/dk-3.jpg" alt="" width="313" height="41" /></a></p>
<p>That&#8217;s a relief, whatever it means. Ah, I see now that this message was brought to me not by the world-renowned experts but rather the company&#8217;s sales team:</p>
<p><a href="http://www.websofia.com/wp-content/uploads/2012/01/dk-4.jpg"><img class="alignnone size-full wp-image-263" title="Sales team!" src="http://www.websofia.com/wp-content/uploads/2012/01/dk-4.jpg" alt="" width="167" height="45" /></a></p>
<p>Thank you! Sales Team! It was certainly &#8220;pleasent&#8221; to hear from you!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2012/01/engrish-in-mozambique/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing your own bootloader for a toy operating system (2)</title>
		<link>http://www.websofia.com/2011/10/writing-your-own-bootloader-for-a-toy-operating-system-2/</link>
		<comments>http://www.websofia.com/2011/10/writing-your-own-bootloader-for-a-toy-operating-system-2/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 14:46:12 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Operating System Development]]></category>
		<category><![CDATA[boot sector]]></category>
		<category><![CDATA[bootloader]]></category>
		<category><![CDATA[BPB]]></category>
		<category><![CDATA[EBPB]]></category>
		<category><![CDATA[GNU as]]></category>
		<category><![CDATA[int 0x10]]></category>
		<category><![CDATA[int 0x13]]></category>
		<category><![CDATA[int 0x16]]></category>
		<category><![CDATA[Intel]]></category>
		<category><![CDATA[toy operating system]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=199</guid>
		<description><![CDATA[This article is part of a short series. Find part 1 here, or go straight through to part 3. Now that we know the structure of the boot parameter block (BPB) and extended boot parameter block (EBPB), we can start &#8230;<p class="read-more"><a href="http://www.websofia.com/2011/10/writing-your-own-bootloader-for-a-toy-operating-system-2/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p><strong>This article is part of a short series. Find <a title="Writing your own boot loader for a toy operating system (1)" href="http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/">part 1 here</a>, or go straight through to <a title="Writing your own bootloader for a toy operating system (3)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/">part 3</a>.<br />
</strong></p>
<p>Now that we know the structure of the boot parameter block (BPB) and extended boot parameter block (EBPB), we can start writing our first code. (If you need a refresher, have a look at <a title="Writing your own boot loader for a toy operating system (1)" href="http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/">part 1</a> of this article).</p>
<h2>First code in GNU assembler</h2>
<p>We&#8217;ll be using the GNU assembler, since it&#8217;s free, comes with a boatload of options, supports AT&amp;T and Intel assembly syntax and plays nice with gcc and ld later on. Some of the preprocessor directives used may need some explanation, but all code will be in straightforward Intel syntax.</p>
<p>Here&#8217;s some boilerplate code to get started:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="kw4">.code16</span>
<span class="kw4">.intel_syntax</span> noprefix
<span class="kw4">.text</span>
<span class="kw4">.org</span> <span class="nu0">0x0</span>
&nbsp;
LOAD_SEGMENT = <span class="nu0">0x1000</span>
&nbsp;
<span class="kw4">.global</span> main
<span class="re0">main:</span>
  <span class="kw1">jmp</span> short start
  <span class="kw1">nop</span>
&nbsp;
  <span class="co1"># BPB and EBPB here</span>
&nbsp;
<span class="re0">start:</span>
  <span class="co1"># rest of code</span></pre></div></div></div></div></div></div></div>


<p>The pile of preprocessor instructions at the top tell the assembler to assemble code for real mode. Since all (intel-based) computers start up in real mode with 16-bit instructions, we won&#8217;t be able to write 32-bit code here yet. We also instruct GNU assembler that we&#8217;ll be using Intel syntax (e.g. <em>mov ax, 1</em> instead of <em>movw $1, %ax</em> &#8211; some prefer the latter, but most readers of this text will be familiar with Intel).  The origin of our code will be 0&#215;0, i.e. all absolute addresses start at 0&#215;0, which will be convenient.</p>
<p>Then there&#8217;s the main entry point of our code, which corresponds to the first byte of actual output when assembled. The code under &#8220;main&#8221; simply jumps over the BPB and EBPB located at offset 0&#215;3, resuming execution at the label <em>start</em>. We&#8217;ll flesh out the BPB/EBPB in a bit, since it&#8217;ll have to have a very exact size.</p>
<p>We&#8217;ve also defined a constant LOAD_SEGMENT, which is the segment where we&#8217;ll be loading our second stage boot loader (more about that later).</p>
<h2>The Boot Parameter Block</h2>
<p>The structure of the boot parameter block can be coded like this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="re0">bootsector:</span>
 <span class="re0">iOEM:</span>          <span class="kw4">.ascii</span> <span class="st0">&quot;DevOS   &quot;</span>    <span class="co1"># OEM String</span>
 <span class="re0">iSectSize:</span>     <span class="kw4">.word</span>  <span class="nu0">0x200</span>         <span class="co1"># bytes per sector</span>
 <span class="re0">iClustSize:</span>    <span class="kw4">.byte</span>  <span class="nu0">1</span>             <span class="co1"># sectors per cluster</span>
 <span class="re0">iResSect:</span>      <span class="kw4">.word</span>  <span class="nu0">1</span>             <span class="co1"># #of reserved sectors</span>
 <span class="re0">iFatCnt:</span>       <span class="kw4">.byte</span>  <span class="nu0">2</span>             <span class="co1"># #of FAT copies</span>
 <span class="re0">iRootSize:</span>     <span class="kw4">.word</span>  <span class="nu0">224</span>           <span class="co1"># size of root directory</span>
 <span class="re0">iTotalSect:</span>    <span class="kw4">.word</span>  <span class="nu0">2880</span>          <span class="co1"># total # of sectors if over 32 MB</span>
 <span class="re0">iMedia:</span>        <span class="kw4">.byte</span>  <span class="nu0">0xF0</span>          <span class="co1"># media Descriptor</span>
 <span class="re0">iFatSize:</span>      <span class="kw4">.word</span>  <span class="nu0">9</span>             <span class="co1"># size of each FAT</span>
 <span class="re0">iTrackSect:</span>    <span class="kw4">.word</span>  <span class="nu0">9</span>             <span class="co1"># sectors per track</span>
 <span class="re0">iHeadCnt:</span>      <span class="kw4">.word</span>  <span class="nu0">2</span>             <span class="co1"># number of read-write heads</span>
 <span class="re0">iHiddenSect:</span>   <span class="sy0">.</span><span class="kw1">int</span>   <span class="nu0">0</span>             <span class="co1"># number of hidden sectors</span>
 <span class="re0">iSect32:</span>       <span class="sy0">.</span><span class="kw1">int</span>   <span class="nu0">0</span>             <span class="co1"># # sectors for over 32 MB</span>
 <span class="re0">iBootDrive:</span>    <span class="kw4">.byte</span>  <span class="nu0">0</span>             <span class="co1"># holds drive that the boot sector came from</span>
 <span class="re0">iReserved:</span>     <span class="kw4">.byte</span>  <span class="nu0">0</span>             <span class="co1"># reserved, empty</span>
 <span class="re0">iBootSign:</span>     <span class="kw4">.byte</span>  <span class="nu0">0x29</span>          <span class="co1"># extended boot sector signature</span>
 <span class="re0">iVolID:</span>        <span class="kw4">.ascii</span> <span class="st0">&quot;seri&quot;</span>        <span class="co1"># disk serial</span>
 <span class="re0">acVolumeLabel:</span> <span class="kw4">.ascii</span> <span class="st0">&quot;MYVOLUME   &quot;</span> <span class="co1"># volume label</span>
 <span class="re0">acFSType:</span>      <span class="kw4">.ascii</span> <span class="st0">&quot;FAT16   &quot;</span>    <span class="co1"># file system type</span></pre></div></div></div></div></div></div></div>


<p>The fields in this structure correspond to the specification in <a title="Writing your own boot loader for a toy operating system (1)" href="http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/">part 1</a> of this text, and since they&#8217;re nicely labelled, we&#8217;ll be able to refer to them later on.</p>
<h2>Real-mode Segments</h2>
<p>After the start label, we can write some actual code. Let&#8217;s start by defining our real mode data segments:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1">  <span class="kw1">cli</span>
  <span class="kw1">mov</span>  iBootDrive<span class="sy0">,</span> <span class="kw3">dl</span>  <span class="co1"># save what drive we booted from (should be 0x0)</span>
  <span class="kw1">mov</span>  <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">cs</span>          <span class="co1"># CS = 0x0, since that's where boot sector is (0x07c00)</span>
  <span class="kw1">mov</span>  <span class="kw3">ds</span><span class="sy0">,</span> <span class="kw3">ax</span>          <span class="co1"># DS = CS = 0x0</span>
  <span class="kw1">mov</span>  <span class="kw3">es</span><span class="sy0">,</span> <span class="kw3">ax</span>          <span class="co1"># ES = CS = 0x0</span>
  <span class="kw1">mov</span>  <span class="kw3">ss</span><span class="sy0">,</span> <span class="kw3">ax</span>          <span class="co1"># SS = CS = 0x0</span>
  <span class="kw1">mov</span>  <span class="kw3">sp</span><span class="sy0">,</span> <span class="nu0">0x7C00</span>      <span class="co1"># Stack grows down from offset 0x7C00 toward 0x0000.</span>
  <span class="kw1">sti</span></pre></div></div></div></div></div></div></div>


<p>Here, we mask interrupts so that interrupt calls don&#8217;t mess up our sector declarations. We set ES = DS = SS = CS = 0&#215;0, and make the stack grow down from 0x7C00 (our boot loader was loaded at 0x7C00). When done, we turn the interrupts back on. It&#8217;s important to note that the BIOS places the number of the boot drive in the DL register. We store it in our BPB for later use.</p>
<h2>Resetting the disk system</h2>
<p>Next, we need to prepare the floppy drive for use. This is done through BIOS interrupt 0&#215;13, subfunction 0. We call it with the boot drive in DL:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1">  <span class="kw1">mov</span>  <span class="kw3">dl</span><span class="sy0">,</span> iBootDrive   <span class="co1"># drive to reset</span>
  <span class="kw1">xor</span>  <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">ax</span>           <span class="co1"># subfunction 0</span>
  <span class="kw1">int</span>  <span class="nu0">0x13</span>             <span class="co1"># call interrupt 13h</span>
  <span class="kw1">jc</span>   bootFailure      <span class="co1"># display error message if carry set (error)</span></pre></div></div></div></div></div></div></div>


<p>If the reset fails, the carry flag will be set and we jump to a label where we handle a boot failure by showing a message, waiting for a keypress and rebooting. Come to think of it, we&#8217;ll need a way to print a string to the screen.</p>
<h2>Printing a string</h2>
<p>We&#8217;ll add a short function that uses BIOS interrupt 0&#215;10, sub-function 9 to print characters to the screen. The calling code must point DS:SI to the null-terminated string to be printed.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="kw4">.func</span> WriteString
 <span class="re0">WriteString:</span>
  <span class="kw1">lodsb</span>                   <span class="co1"># load byte at ds:si into al (advancing si)</span>
  <span class="kw1">or</span>     <span class="kw3">al</span><span class="sy0">,</span> <span class="kw3">al</span>           <span class="co1"># test if character is 0 (end)</span>
  <span class="kw1">jz</span>     WriteString_done <span class="co1"># jump to end if 0.</span>
&nbsp;
  <span class="kw1">mov</span>    <span class="kw3">ah</span><span class="sy0">,</span> <span class="nu0">0xe</span>          <span class="co1"># Subfunction 0xe of int 10h (video teletype output).</span>
  <span class="kw1">mov</span>    <span class="kw3">bx</span><span class="sy0">,</span> <span class="nu0">9</span>            <span class="co1"># Set bh (page nr) to 0, and bl (attribute) to white (9).</span>
  <span class="kw1">int</span>    <span class="nu0">0x10</span>             <span class="co1"># call BIOS interrupt.</span>
&nbsp;
  <span class="kw1">jmp</span>    WriteString      <span class="co1"># Repeat for next character.</span>
&nbsp;
 <span class="re0">WriteString_done:</span>
  retw
<span class="kw4">.endfunc</span></pre></div></div></div></div></div></div></div>


<p>We can now define the &#8220;bootFailure&#8221; label:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="re0">diskerror:</span> <span class="kw4">.asciz</span> <span class="st0">&quot;Disk error. &quot;</span>
<span class="re0">bootFailure:</span>
  <span class="kw1">lea</span> <span class="kw3">si</span><span class="sy0">,</span> diskerror
  <span class="kw1">call</span> WriteString
  <span class="kw1">call</span> Reboot</pre></div></div></div></div></div></div></div>


<p>Great. We&#8217;ve got code to reset the floppy drive, and if it fails, there&#8217;s code that prints failure strings and reboots. Although, we still have to write a Reboot function.</p>
<h2>Rebooting</h2>
<p>Here is some code that prints a &#8220;Press any key to reboot&#8221; message, waits for a keystroke, and reboots the machine.</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="re0">rebootmsg:</span> <span class="kw4">.asciz</span> <span class="st0">&quot;Press any key to reboot\r\n&quot;</span>
<span class="kw4">.func</span> Reboot
 <span class="re0">Reboot:</span>
  <span class="kw1">lea</span>    <span class="kw3">si</span><span class="sy0">,</span> rebootmsg    <span class="co1"># Load address of reboot message into si</span>
  <span class="kw1">call</span>   WriteString      <span class="co1"># print the string</span>
  <span class="kw1">xor</span>    <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">ax</span>           <span class="co1"># subfuction 0</span>
  <span class="kw1">int</span>    <span class="nu0">0x16</span>             <span class="co1"># call bios to wait for key</span>
&nbsp;
  <span class="kw4">.byte</span>  <span class="nu0">0xEA</span>             <span class="co1"># machine language to jump to FFFF:0000 (reboot)</span>
  <span class="kw4">.word</span>  <span class="nu0">0x0000</span>
  <span class="kw4">.word</span>  <span class="nu0">0xFFFF</span>
<span class="kw4">.endfunc</span></pre></div></div></div></div></div></div></div>


<p>Here, we use BIOS interrupt 0&#215;16, sub-function 0 to read a key (any key). We then add a far jump to 0xffff:0000 we causes the machine to reboot.</p>
<h2>Putting it all together</h2>
<p>When we combine the functions above into a single source file, we end up with this:</p>


<div class="wp-geshi-highlight-wrap5"><div class="wp-geshi-highlight-wrap4"><div class="wp-geshi-highlight-wrap3"><div class="wp-geshi-highlight-wrap2"><div class="wp-geshi-highlight-wrap"><div class="wp-geshi-highlight"><div class="gnu-asm"><pre class="de1"><span class="kw4">.code16</span>
<span class="kw4">.intel_syntax</span> noprefix
<span class="kw4">.text</span>
<span class="kw4">.org</span> <span class="nu0">0x0</span>                                        
&nbsp;
LOAD_SEGMENT = <span class="nu0">0x1000</span>             <span class="sy0">;</span> load the boot loader to segment <span class="nu0">1000h</span>
&nbsp;
<span class="kw4">.global</span> main
&nbsp;
<span class="re0">main:</span>
  <span class="kw1">jmp</span> short start                 <span class="co1"># jump to beginning of code</span>
  <span class="kw1">nop</span>
&nbsp;
<span class="re0">bootsector:</span>
 <span class="re0">iOEM:</span>          <span class="kw4">.ascii</span> <span class="st0">&quot;DevOS   &quot;</span>    <span class="co1"># OEM String</span>
 <span class="re0">iSectSize:</span>     <span class="kw4">.word</span>  <span class="nu0">0x200</span>         <span class="co1"># bytes per sector</span>
 <span class="re0">iClustSize:</span>    <span class="kw4">.byte</span>  <span class="nu0">1</span>             <span class="co1"># sectors per cluster</span>
 <span class="re0">iResSect:</span>      <span class="kw4">.word</span>  <span class="nu0">1</span>             <span class="co1"># #of reserved sectors</span>
 <span class="re0">iFatCnt:</span>       <span class="kw4">.byte</span>  <span class="nu0">2</span>             <span class="co1"># #of FAT copies</span>
 <span class="re0">iRootSize:</span>     <span class="kw4">.word</span>  <span class="nu0">224</span>           <span class="co1"># size of root directory</span>
 <span class="re0">iTotalSect:</span>    <span class="kw4">.word</span>  <span class="nu0">2880</span>          <span class="co1"># total # of sectors if over 32 MB</span>
 <span class="re0">iMedia:</span>        <span class="kw4">.byte</span>  <span class="nu0">0xF0</span>          <span class="co1"># media Descriptor</span>
 <span class="re0">iFatSize:</span>      <span class="kw4">.word</span>  <span class="nu0">9</span>             <span class="co1"># size of each FAT</span>
 <span class="re0">iTrackSect:</span>    <span class="kw4">.word</span>  <span class="nu0">9</span>             <span class="co1"># sectors per track</span>
 <span class="re0">iHeadCnt:</span>      <span class="kw4">.word</span>  <span class="nu0">2</span>             <span class="co1"># number of read-write heads</span>
 <span class="re0">iHiddenSect:</span>   <span class="sy0">.</span><span class="kw1">int</span>   <span class="nu0">0</span>             <span class="co1"># number of hidden sectors</span>
 <span class="re0">iSect32:</span>       <span class="sy0">.</span><span class="kw1">int</span>   <span class="nu0">0</span>             <span class="co1"># # sectors for over 32 MB</span>
 <span class="re0">iBootDrive:</span>    <span class="kw4">.byte</span>  <span class="nu0">0</span>             <span class="co1"># holds drive that the boot sector came from</span>
 <span class="re0">iReserved:</span>     <span class="kw4">.byte</span>  <span class="nu0">0</span>             <span class="co1"># reserved, empty</span>
 <span class="re0">iBootSign:</span>     <span class="kw4">.byte</span>  <span class="nu0">0x29</span>          <span class="co1"># extended boot sector signature</span>
 <span class="re0">iVolID:</span>        <span class="kw4">.ascii</span> <span class="st0">&quot;seri&quot;</span>        <span class="co1"># disk serial</span>
 <span class="re0">acVolumeLabel:</span> <span class="kw4">.ascii</span> <span class="st0">&quot;MYVOLUME   &quot;</span> <span class="co1"># volume label</span>
 <span class="re0">acFSType:</span>      <span class="kw4">.ascii</span> <span class="st0">&quot;FAT16   &quot;</span>    <span class="co1"># file system type</span>
&nbsp;
<span class="kw4">.func</span> WriteString
<span class="re0">WriteString:</span>
  <span class="kw1">lodsb</span>                   <span class="co1"># load byte at ds:si into al (advancing si)</span>
  <span class="kw1">or</span>     <span class="kw3">al</span><span class="sy0">,</span> <span class="kw3">al</span>           <span class="co1"># test if character is 0 (end)</span>
  <span class="kw1">jz</span>     WriteString_done <span class="co1"># jump to end if 0.</span>
&nbsp;
  <span class="kw1">mov</span>    <span class="kw3">ah</span><span class="sy0">,</span> <span class="nu0">0xe</span>          <span class="co1"># Subfunction 0xe of int 10h (video teletype output)</span>
  <span class="kw1">mov</span>    <span class="kw3">bx</span><span class="sy0">,</span> <span class="nu0">9</span>            <span class="co1"># Set bh (page nr) to 0, and bl (attribute) to white (9)</span>
  <span class="kw1">int</span>    <span class="nu0">0x10</span>             <span class="co1"># call BIOS interrupt.</span>
&nbsp;
  <span class="kw1">jmp</span>    WriteString      <span class="co1"># Repeat for next character.</span>
&nbsp;
<span class="re0">WriteString_done:</span>
  retw
<span class="kw4">.endfunc</span>
&nbsp;
<span class="kw4">.func</span> Reboot
 <span class="re0">Reboot:</span>
  <span class="kw1">lea</span>    <span class="kw3">si</span><span class="sy0">,</span> rebootmsg <span class="co1"># Load address of reboot message into si</span>
  <span class="kw1">call</span>   WriteString   <span class="co1"># print the string</span>
  <span class="kw1">xor</span>    <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">ax</span>        <span class="co1"># subfuction 0</span>
  <span class="kw1">int</span>    <span class="nu0">0x16</span>          <span class="co1"># call bios to wait for key</span>
  <span class="kw4">.byte</span>  <span class="nu0">0xEA</span>          <span class="co1"># machine language to jump to FFFF:0000 (reboot)</span>
  <span class="kw4">.word</span>  <span class="nu0">0x0000</span>
  <span class="kw4">.word</span>  <span class="nu0">0xFFFF</span>
<span class="kw4">.endfunc</span>
&nbsp;
<span class="re0">start:</span>
  <span class="co1"># Setup segments:</span>
  <span class="kw1">cli</span>
  <span class="kw1">mov</span>  iBootDrive<span class="sy0">,</span> <span class="kw3">dl</span>  <span class="co1"># save what drive we booted from (should be 0x0)</span>
  <span class="kw1">mov</span>  <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">cs</span>          <span class="co1"># CS = 0x0, since that's where boot sector is (0x07c00)</span>
  <span class="kw1">mov</span>  <span class="kw3">ds</span><span class="sy0">,</span> <span class="kw3">ax</span>          <span class="co1"># DS = CS = 0x0</span>
  <span class="kw1">mov</span>  <span class="kw3">es</span><span class="sy0">,</span> <span class="kw3">ax</span>          <span class="co1"># ES = CS = 0x0</span>
  <span class="kw1">mov</span>  <span class="kw3">ss</span><span class="sy0">,</span> <span class="kw3">ax</span>          <span class="co1"># SS = CS = 0x0</span>
  <span class="kw1">mov</span>  <span class="kw3">sp</span><span class="sy0">,</span> <span class="nu0">0x7C00</span>      <span class="co1"># Stack grows down from offset 0x7C00 toward 0x0000.</span>
  <span class="kw1">sti</span>  
&nbsp;
  <span class="co1"># Display &quot;loading&quot; message:</span>
  <span class="kw1">lea</span>  <span class="kw3">si</span><span class="sy0">,</span> loadmsg
  <span class="kw1">call</span> WriteString
&nbsp;
  <span class="co1"># Reset disk system.</span>
  <span class="co1"># Jump to bootFailure on error.</span>
  <span class="kw1">mov</span>  <span class="kw3">dl</span><span class="sy0">,</span> iBootDrive  <span class="co1"># drive to reset</span>
  <span class="kw1">xor</span>  <span class="kw3">ax</span><span class="sy0">,</span> <span class="kw3">ax</span>          <span class="co1"># subfunction 0</span>
  <span class="kw1">int</span>  <span class="nu0">0x13</span>            <span class="co1"># call interrupt 13h</span>
  <span class="kw1">jc</span>   bootFailure     <span class="co1"># display error message if carry set (error)  </span>
&nbsp;
  <span class="co1"># End of loader, for now. Reboot.</span>
  <span class="kw1">call</span> Reboot
&nbsp;
<span class="re0">bootFailure:</span>
  <span class="kw1">lea</span>  <span class="kw3">si</span><span class="sy0">,</span> diskerror
  <span class="kw1">call</span> WriteString
  <span class="kw1">call</span> Reboot
&nbsp;
<span class="co1"># PROGRAM DATA</span>
<span class="re0">loadmsg:</span>          <span class="kw4">.asciz</span> <span class="st0">&quot;Loading OS...\r\n&quot;</span>
<span class="re0">diskerror:</span>        <span class="kw4">.asciz</span> <span class="st0">&quot;Disk error. &quot;</span>
<span class="re0">rebootmsg:</span>        <span class="kw4">.asciz</span> <span class="st0">&quot;Press any key to reboot.\r\n&quot;</span>
&nbsp;
<span class="kw4">.fill</span> <span class="br0">&#40;</span><span class="nu0">510</span><span class="sy0">-</span><span class="br0">&#40;</span><span class="sy0">.-</span>main<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">0</span>  <span class="co1"># Pad with nulls up to 510 bytes (excl. boot magic)</span>
<span class="re0">BootMagic:</span>  <span class="sy0">.</span><span class="kw1">int</span> <span class="nu0">0xAA55</span>     <span class="co1"># magic word for BIOS</span></pre></div></div></div></div></div></div></div>


<h3>Points of note</h3>
<ul>
<li>The WriteString and Reboot sections are functions, that we&#8217;ll want to call various times in the other boot code that we&#8217;ll write soon. They are not part of the main body of code. That is why they are placed <em>before </em>the start label, so that execution will jump over them.</li>
<li>The loader will not print a &#8220;Loading OS&#8230;&#8221; message right after it sets the segments.</li>
<li>After having reset the disk system successfully, the loader will reboot. We&#8217;re doing that only because we haven&#8217;t written any more code yet that does interesting things.</li>
<li>The source code ends with a <strong>.fill</strong> preprocessor directive. This causes the assembler to fill up the output file with null bytes all the way to offset 510. The final two bytes contain the magic word required by some BIOSes. Compilation will now yield a file of exactly 512 bytes, which is what we need for our boot sector.</li>
</ul>
<h2>Summary</h2>
<p>We&#8217;ve written assembler code that prepares data and stack segments and resets the floppy drive. We&#8217;ve also added functions for writing text to the screen, waiting for a keypress, and rebooting, which wraps up</p>
<p>I don&#8217;t know about you, but I&#8217;m just about ready to see this code in action! In the <a title="Writing your own bootloader for a toy operating system (3)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/">next section</a>, we&#8217;ll see how we can actually compile and test this code.</p>
<p><a title="Writing your own bootloader for a toy operating system (3)" href="http://www.websofia.com/2012/04/writing-your-own-bootloader-for-a-toy-operating-system-3/">On to section 3</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2011/10/writing-your-own-bootloader-for-a-toy-operating-system-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Writing your own boot loader for a toy operating system (1)</title>
		<link>http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/</link>
		<comments>http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 13:47:12 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Operating System Development]]></category>
		<category><![CDATA[assembler]]></category>
		<category><![CDATA[boot sector]]></category>
		<category><![CDATA[bootloader]]></category>
		<category><![CDATA[BPB]]></category>
		<category><![CDATA[DOS]]></category>
		<category><![CDATA[EBPB]]></category>
		<category><![CDATA[FAT]]></category>
		<category><![CDATA[FAT16]]></category>
		<category><![CDATA[GRUB]]></category>
		<category><![CDATA[IO.SYS]]></category>
		<category><![CDATA[LILO]]></category>
		<category><![CDATA[SYS.COM]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=180</guid>
		<description><![CDATA[If you&#8217;re writing your own toy operating system, the first thing you&#8217;ll need is a boot sector. It&#8217;s a piece of code (the boot loader) that lives in the first sector of a (floppy) disk. This code gets called by &#8230;<p class="read-more"><a href="http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/">Read more &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re writing your own toy operating system, the first thing you&#8217;ll need is a <strong>boot sector</strong>. It&#8217;s a piece of code (the <em>boot loader</em>) that lives in the first sector of a (floppy) disk. This code gets called by the BIOS as soon as the computer starts up.</p>
<p>Note that you can actually start developing other components of your toy operating system before writing boot code, since you can use <a title="GRUB" href="http://www.gnu.org/software/grub/">GRUB</a> (GNU Grand Unified Boot Loader) or <a title="LILO" href="http://freshmeat.net/projects/lilo/">LILO</a> to start your kernel. Using one of these tools brings advantages, since they&#8217;ll switch the processor to <strong>protected mode</strong> for you, and allow you to load kernels that are placed beyond cylinder 1024 of a hard disk.</p>
<p>However, writing your own boot code can be a very interesting exercise in assembly programming, and you&#8217;ll have full control over what your boot loader actually does. Plus, you get to try and do it better than the people who wrote the DOS/Win95 boot loaders (which isn&#8217;t saying a lot as you&#8217;ll see below).</p>
<h2>Boot loader requirements</h2>
<p>The boot code lives in the first sector of a floppy disk, which typically has a size of 512 bytes. However, 61 of those bytes are occupied by data, placed on the disk when it is formatted. This data includes the size of a disk sector, number of FAT tables, number of tracks per sector, volume ID, and more. This yields 451 bytes available for code, which is not a whole lot. That&#8217;s one reason we&#8217;ll use assembler to write our code.</p>
<h2>The DOS/Windows bootloader and its limitations</h2>
<p>Let&#8217;s consider the boot loader that most of us have used many times: the boot loader that comes with DOS or Windows (up to Windows 95). What does it do?</p>
<ul>
<li>Reset the floppy disk system</li>
<li>Read the first sector of the root directory from the disk</li>
<li>Verify that the first file found there is IO.SYS (the kernel)</li>
<li>Load IO.SYS into memory</li>
<li>Transfer control to IO.SYS</li>
</ul>
<p>Since the space available for actual code in the boot sector is limited, the author of the DOS boot loader introduced an important requirement: the file IO.SYS must be the first file in the root directory. The DOS code does not scan the entire root directory looking for the required file. If IO.SYS is not the first file found, then the boot code fails.</p>
<p>This is why DOS/Windows comes with the SYS.COM program, which is used to make a disk bootable. This program actually cleans the root directory of a floppy disk and copies IO.SYS into it as the first entry, effectively removing all the other files. It would have been much nicer if it had been possible to copy IO.SYS to the root directory of a disk, at<em> any</em> position. Then any disk could be make bootable without sacrificing the files on it. This can actually be done, but it requires more assembly code, something the DOS developers apparently did not find any space for &#8211; but we can do better.</p>
<p>At any rate, modern operating systems will switch the processor to protected mode, which allows us to address up to 4 GB of memory in a flat model (not segmented), and switch on paging to protect processes from one another. This wasn&#8217;t part of the DOS/Windows 95 boot loader, but we&#8217;ll need to do it.</p>
<h2>How a boot loader gets called</h2>
<p>When the computer starts up, it executes a <strong>power-on self test</strong> (POST). It then performs the following actions:</p>
<ul>
<li>Determine which device (drive) to use for booting, using preferences stored in the CMOS.</li>
<li>Try to load the first sector (and only the first sector) from the boot drive into memory at address 0:0x7C00.</li>
<li>Verify that the the first sector is in fact bootable by checking for the presence of a magic number (see below).</li>
<li>Store the number of the drive used in register DL.</li>
<li>Point the CPU&#8217;s instruction pointer to 0:0x7C00, and start execution from there.</li>
</ul>
<p>The computer knows how to do these things, and does them automatically, because the code for this is in its BIOS ROM. In other words, these procedures we get for free with any computer.</p>
<h2>What a boot loader should do</h2>
<p>Here&#8217;s a list of things that a modern boot loader should do in order to load and start your operating system&#8217;s kernel (we&#8217;ll cover concepts like the A20-line, IDT and GDT tables later):</p>
<ul>
<li>Reset the floppy disk system</li>
<li>Write a &#8220;loading&#8221; message to the screen</li>
<li>Find the kernel in the root directory of the disk (at any position)</li>
<li>Read the kernel from disk into memory</li>
<li>Enable the A20-line</li>
<li>Setup the IDT and GDT tables</li>
<li>Switch to protected mode</li>
<li>Clear the processor prefetch queue</li>
<li>Run the kernel</li>
</ul>
<h2>Boot Sector Layout</h2>
<p>The boot sector of a floppy disk has a very specific layout, because the BIOS requires access to certain data which it needs to find in the place it expects it to be. Also, an operating system will need to access this data to determine how large the disk is, what file system it uses, what its volume label is and so on. For this article, we&#8217;ll assume a floppy disk formatted with a FAT16 file system. The layout of the boot sector is then:</p>
<p><strong>
<table id="wp-table-reloaded-id-1-no-1" class="wp-table-reloaded wp-table-reloaded-id-1">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Offset</th><th class="column-2">Size</th><th class="column-3"></th><th class="column-4">Contents</th><th class="column-5">Typical value</th>
	</tr>
</thead>
<tbody class="row-hover">
	<tr class="row-2 even">
		<td class="column-1">0000</td><td class="column-2">3</td><td class="column-3">Code</td><td class="column-4">Jump to rest of code</td><td class="column-5"></td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">0003</td><td class="column-2">8</td><td rowspan="12" class="column-3 rowspan-12">BPB</td><td class="column-4">OEM name</td><td class="column-5">Great-OS</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">0011</td><td class="column-2">2</td><td class="column-4">Bytes per sector</td><td class="column-5">512</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">0013</td><td class="column-2">1</td><td class="column-4">Number of sectors per cluster</td><td class="column-5">1</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">0014</td><td class="column-2">2</td><td class="column-4">Number of reserved sectors</td><td class="column-5">1</td>
	</tr>
	<tr class="row-7 odd">
		<td class="column-1">0016</td><td class="column-2">1</td><td class="column-4">Number of FAT tables</td><td class="column-5">2</td>
	</tr>
	<tr class="row-8 even">
		<td class="column-1">0017</td><td class="column-2">2</td><td class="column-4">Number of root directory entries (usually 224)</td><td class="column-5">224</td>
	</tr>
	<tr class="row-9 odd">
		<td class="column-1">0019</td><td class="column-2">2</td><td class="column-4">Total number of sectors</td><td class="column-5">2880</td>
	</tr>
	<tr class="row-10 even">
		<td class="column-1">0021</td><td class="column-2">1</td><td class="column-4">Media descriptor</td><td class="column-5">0xf0</td>
	</tr>
	<tr class="row-11 odd">
		<td class="column-1">0022</td><td class="column-2">2</td><td class="column-4">Number of sectors per FAT</td><td class="column-5">9</td>
	</tr>
	<tr class="row-12 even">
		<td class="column-1">0024</td><td class="column-2">2</td><td class="column-4">Number of sectors/track</td><td class="column-5">9</td>
	</tr>
	<tr class="row-13 odd">
		<td class="column-1">0026</td><td class="column-2">2</td><td class="column-4">Number of heads</td><td class="column-5">2</td>
	</tr>
	<tr class="row-14 even">
		<td class="column-1">0028</td><td class="column-2">2</td><td class="column-4">Number of hidden sectors</td><td class="column-5">0</td>
	</tr>
	<tr class="row-15 odd">
		<td class="column-1">0030</td><td class="column-2">2</td><td rowspan="8" class="column-3 rowspan-8">EBPB</td><td class="column-4">Number of hidden sectors (high word)</td><td class="column-5">0</td>
	</tr>
	<tr class="row-16 even">
		<td class="column-1">0032</td><td class="column-2">4</td><td class="column-4">Total number of sectors in filesystem</td><td class="column-5"></td>
	</tr>
	<tr class="row-17 odd">
		<td class="column-1">0036</td><td class="column-2">1</td><td class="column-4">Logical drive number</td><td class="column-5">0</td>
	</tr>
	<tr class="row-18 even">
		<td class="column-1">0037</td><td class="column-2">1</td><td class="column-4">Reserved</td><td class="column-5"></td>
	</tr>
	<tr class="row-19 odd">
		<td class="column-1">0038</td><td class="column-2">1</td><td class="column-4">Extended signature</td><td class="column-5">0x29</td>
	</tr>
	<tr class="row-20 even">
		<td class="column-1">0039</td><td class="column-2">4</td><td class="column-4">Serial number</td><td class="column-5"></td>
	</tr>
	<tr class="row-21 odd">
		<td class="column-1">0043</td><td class="column-2">8</td><td class="column-4">Volume label</td><td class="column-5">MYVOLUME</td>
	</tr>
	<tr class="row-22 even">
		<td class="column-1">0054</td><td class="column-2">8</td><td class="column-4">Filesystem type</td><td class="column-5">FAT16   </td>
	</tr>
	<tr class="row-23 odd">
		<td class="column-1">0062</td><td class="column-2">448</td><td class="column-3">Code</td><td class="column-4">Boot code</td><td class="column-5"></td>
	</tr>
	<tr class="row-24 even">
		<td class="column-1">0510</td><td class="column-2">2</td><td class="column-3">Required</td><td class="column-4">Boot signature</td><td class="column-5">0xaa55</td>
	</tr>
</tbody>
</table>
</strong></p>
<p>A required element of the boot sector is the <strong>boot parameter block</strong> (BPB) and the <strong>extended boot parameter block</strong> (EBPB, for FAT16). This block <em>must</em> be placed at offset 3, size 59 bytes. Also, the boot sector must end with the magic number 0xaa55: (some) BIOSes will check whether this value is present at offset 510. If not, the BIOS will refuse to boot from the disk. All other bytes are available for us to fill in. We can calculate that that adds in fact up to 451 bytes. Also, the first three bytes are separated from the rest and should only be used to jump to the rest of the code, so that&#8217;s less 3 bytes for interesting code&#8230;</p>
<p>Here is a typical hex dump of a boot sector without any code. Colored in red are the parts in the BPB and EBPB as decribed above, and the magic number at the end. Everything else is available for code:</p>
<pre>0x0000 00 00 00<span style="color: #993300;"> 47 72 65 61 74 2d 4f 53 00 02 01 01 00</span> ...<span style="color: #993300;">Great-OS.....</span>
0x0010 <span style="color: #993300;">02 e0 00 40 0b f0 09 00 09 00 02 00 00 00 00 00 .à.@............</span>
0x0020 <span style="color: #993300;">00 00 00 00 00 00 29 73 65 72 69 00 00 00 00 00 ......)seri.....</span>
0x0030 <span style="color: #993300;">00 00 00 00 00 00 46 41 54 31 36 20 20 20 fa 88 ......FAT16   ú^</span>
0x0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x01a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x01b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x01c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x01d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x01e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x01f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 <span style="color: #993300;">55 aa</span> ..............<span style="color: #993300;">Uª</span></pre>
<h2>Summary</h2>
<p>This article described how a computer bootstraps. The Power-On Self Test (POST) causes the first sector of a (floppy) disk to be read into memory. This boot sector contains information about the disk and (at most) 451 bytes of code. In the next part of this guide, we&#8217;ll see how we can write assembly code to roll our own boot loader.</p>
<p>This article continues in <strong><a title="Writing your own bootloader for a toy operating system (2)" href="http://www.websofia.com/2011/10/writing-your-own-bootloader-for-a-toy-operating-system-2/">part 2</a></strong> of this series.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2011/10/writing-your-own-boot-loader-for-a-toy-operating-system-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Jiskefet Lullo&#8217;s Gezinsverpakking: alle video&#8217;s!</title>
		<link>http://www.websofia.com/2011/10/jiskefet-lullos-gezinsverpakking-alle-videos/</link>
		<comments>http://www.websofia.com/2011/10/jiskefet-lullos-gezinsverpakking-alle-videos/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 12:26:22 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[Jiskefet]]></category>
		<category><![CDATA[dispuut]]></category>
		<category><![CDATA[Jisketfet]]></category>
		<category><![CDATA[kamphuys]]></category>
		<category><![CDATA[kerstens]]></category>
		<category><![CDATA[Lullo's]]></category>
		<category><![CDATA[pizza]]></category>
		<category><![CDATA[skybox]]></category>
		<category><![CDATA[van binsbergen]]></category>

		<guid isPermaLink="false">http://www.websofia.com/?p=173</guid>
		<description><![CDATA[Hier zijn ze dan:]]></description>
			<content:encoded><![CDATA[<p>Hier zijn ze dan:</p>
<p><iframe src="http://www.youtube.com/embed/Jgd8g3oqZus" width="420" frameborder="0" height="315"></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/6tlOPm_RFHI" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/ZbnKqA3rjOU" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/6UQvdN7RkQI" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/kIJO584aX0o" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/fdEFNdyIGwg" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/7Uc6jIruIBM" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/B723xCdnvZs" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/XK0K04VHTrM" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/lh3lsTu7W9A" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/ASqvFdANCJg" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/xv0CivbC3TY" frameborder="0" allowfullscreen></iframe></p>
<p><iframe width="420" height="315" src="http://www.youtube.com/embed/JUijaUl04-Q" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.websofia.com/2011/10/jiskefet-lullos-gezinsverpakking-alle-videos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

