<?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"
	>

<channel>
	<title>Gustavo Duarte</title>
	<atom:link href="http://duartes.org/gustavo/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://duartes.org/gustavo/blog</link>
	<description>Software, computers, and business.</description>
	<pubDate>Sat, 18 Oct 2008 10:21:09 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Most Programming Is Not Core</title>
		<link>http://duartes.org/gustavo/blog/post/most-programming-is-not-core</link>
		<comments>http://duartes.org/gustavo/blog/post/most-programming-is-not-core#comments</comments>
		<pubDate>Fri, 17 Oct 2008 22:54:16 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Business]]></category>

		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=69</guid>
		<description><![CDATA[ Coding Horror started a discussion on the relative merits of  	writing your own code versus using 3rd-party libraries. The main argument for writing your own is borrowed from Joel&#8217;s In Defense of the Not-Invented-Here Syndrome: 
 If it&#8217;s a core business function &#8212; do it yourself, no matter what.
 Pick your core business [...]]]></description>
			<content:encoded><![CDATA[<p> Coding Horror started a discussion on the relative merits of <a href="http://www.codinghorror.com/blog/archives/001172.html"> 	writing your own</a> code versus using 3rd-party libraries. The main argument for writing your own is borrowed from Joel&#8217;s <a href="http://www.joelonsoftware.com/articles/fog0000000007.html">In Defense of the Not-Invented-Here Syndrome</a>: </p>
<blockquote><p> <b>If it&#8217;s a core business function &#8212; do it yourself, no matter what.</b>
<p> Pick your core business competencies and goals, and do those in house. If you&#8217;re a software company, writing excellent code is how you&#8217;re going to succeed. Go ahead and outsource the company cafeteria and the CD-ROM duplication. If you&#8217;re a pharmaceutical company, write software for drug research, but don&#8217;t write your own accounting package. If you&#8217;re a web accounting service, write your own accounting package, but don&#8217;t try to create your own magazine ads. If you have customers, never outsource customer service. </p>
</blockquote>
<p> Righty. But then why did Fog Creek, Joel&#8217;s company, build their Copilot product <a href="https://www.copilot.com/tech/">based on the open source Tight VNC</a>? I mean, that is the very core of their product, and they decided to use third party code. It&#8217;s hard to think of a bigger counter-example to his claim (there are plenty of others, like Flickr using ImageMagick and MacOS using BSD code). So why the contradiction? </p>
<p> It turns out the quote above is naive and simplistic. Writing excellent code is <b>not</b> how you&#8217;re going to succeed. You&#8217;ll succeed by delivering value and making users happy, hopefully fast. Given that you have limited resources, you need to <b>prioritize</b> your precious programmer firepower and funnel it into those areas that will help you differentiate and build really useful stuff. Rebuilding compilers and libraries is not how you do that. Which is why Joel, who is anything but naive, borrowed the core engine of his product from VNC and concentrated on delivering smooth usability. </p>
<p> Thinking of &#8220;programming&#8221; as your core business function is too broad. Only a subset of your programming is truly core.  You won&#8217;t do better than Prototype, jQuery, or extjs. Rails really is great, and so are CakePHP, lex/yacc, and HTML Tidy. The instinct to use third-party libraries is absolutely right. Only when the choices are truly unsuitable or inexistent should you roll your own. This is especially true now that we have so many high-quality open source libraries. Or at least you do when you&#8217;re developing in the open source ecosystem, which is something that needs to be taken into account when deciding on the right platform. </p>
<p> People often forget to factor in opportunity cost when thinking of tradeoffs.  When you re-write stuff, not only you spent the time and money, but you also did <b>not</b> build something else that might have been valuable. So pick the right libraries and concentrate on giving us the goodness only you can build.  </p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/most-programming-is-not-core/feed</wfw:commentRss>
		</item>
		<item>
		<title>The Divided House of GPL</title>
		<link>http://duartes.org/gustavo/blog/post/the-divided-house-of-gpl</link>
		<comments>http://duartes.org/gustavo/blog/post/the-divided-house-of-gpl#comments</comments>
		<pubDate>Thu, 16 Oct 2008 07:40:30 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Culture]]></category>

		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=63</guid>
		<description><![CDATA[ Back in 2000 The Onion made fun of Libertarians and published this nugget: 
 	 
 Joking aside, a powerful idea attracts a wide range of people. Copyleft is such an idea.  It turns copyright on its head by using authorship rights to enforce the public&#8217;s ability to distribute, modify and use  [...]]]></description>
			<content:encoded><![CDATA[<p> Back in 2000 The Onion <a href="http://www.theonion.com/content/news/l_a_efficiency_chosen_as_site_of">made fun</a> of Libertarians and published this nugget: </p>
<p align="center"> 	<img alt="Libertarian National Convention" src="http://static.duartes.org/img/blogPosts/onion-libertarians.jpg" /> </p>
<p> Joking aside, a powerful idea attracts a wide range of people. <a href="http://en.wikipedia.org/wiki/Copyleft">Copyleft</a> is such an idea.  It turns copyright on its head by using authorship rights to <i>enforce</i> the public&#8217;s ability to distribute, modify and use  the copyrighted work, rather than to <i>curb</i> it as is normally the case. Several copyleft licenses exist, the most prominent in software being the <a href="http://en.wikipedia.org/wiki/Gpl">GPL</a>, first released by Richard Stallman in 1989. </p>
<p> There are two main factions supporting the GPL: the pragmatic camp of Linus Torvalds and the ideological camp of  Richard Stallman. The Linus camp sees copyleft as the enabler of a superior way to produce software, in which  distributed and open development takes place because people are encouraged and protected by the license.  The individual programmer is assured that their contributions must always remain a public good and cannot be coopted for private gain. Others may profit from the software, sell it, or support it, but the source code must be available, modifiable and distributable.  This is a powerful motivator, the same force that makes people help the Wikipedia but not for-profit outfits. </p>
<p> For large-scale development involving multiple corporations, copyleft solves a type of <a href="http://en.wikipedia.org/wiki/Free_rider_problem">free rider problem</a> by ensuring that all participants must give back to the common pool of development. This protects investments and tends to boost returns,  and a brief look at the Linux Kernel Mailing List shows that major tech companies are happy to play along. I bet you can do some game theory and prove some results for cooperation under GPL. </p>
<p> To the Linus camp the GPL is a means to foster this ecosystem, the end being better software. There are no moral imperatives or political reasons behind the whole thing, which surprises some people. Proprietary software is &#8220;alchemy&#8221; while open source is science. Here&#8217;s <a href="http://www.realworldtech.com/forums/index.cfm?action=detail&amp;id=49312&amp;threadid=49309&amp;roomid=2">Linus</a>: </p>
<blockquote><p> In my book, what matters is what you do - whether you want to sell things is your personal choice, but even more importantly it is not a moral negative or positive. I&#8217;m a big believer in open source as creating good stuff, but I don&#8217;t think it&#8217;s a moral issue. It&#8217;s engineering. </p>
<p> So I think open source tends to become technically better over time (but it does take time), but I don&#8217;t think it&#8217;s a moral imperative. I do open source because it&#8217;s fun, and because I think it makes sense in the long run. 	</p>
</blockquote>
<p>And here&#8217;s <a href="http://www.forbes.com/technology/2006/03/09/torvalds-linux-licensing-cz_dl_0309torvalds1.html">more</a>:</p>
<blockquote><p> Just to explain the fundamental issue: To me, the GPL really boils down to &#8220;I give out code, I want you to do the same.&#8221; The thing that makes me not want to use the GPLv3 in its current form is that it really tries to move more toward the &#8220;software freedom&#8221; goals. For example, the GPLv2 in no way limits your use of the software. If you&#8217;re a mad scientist, you can use GPLv2&#8242;d software for your evil plans to take over the world (&#8221;Sharks with lasers on their heads!!&#8221;), and the GPLv2 just says that you have to give source code back. And that&#8217;s OK by me. I like sharks with lasers. I just want the mad scientists of the world to pay me back in kind. I made source code available to them, they have to make their changes to it available to me. After that, they can fry me with their shark-mounted lasers all they want.  This is where the GPLv3 diverges. It limits how you can use the software.  	</p>
</blockquote>
<p> The Stallman camp, however, sees GPL-licensed software as the <i>end</i> itself. They claim that  software <a href="http://www.gnu.org/philosophy/shouldbefree.html">should be free</a> on moral grounds, citing <a href="http://www.gnu.org/philosophy/why-free.html">several reasons</a>. Hence it matters not whether the software or the process are superior. One must use free software regardless because it is the right thing to do, while proprietary software is inherently immoral. Here&#8217;s <a href="http://www.pcworld.idg.com.au/index.php/id;211669437">Stallman</a>: </p>
<blockquote><p> Supporters of open source (which I am not) promote a &#8220;development model&#8221; in which users participate in development, claiming that this typically makes software &#8220;better&#8221; &#8212; and when they say &#8220;better&#8221;, they mean that only in a technical sense. By using the term that way, implicitly, they say that only practical convenience matters &#8212; not your freedom. 	</p>
<p> I don&#8217;t say they are wrong, but they are missing the point. If you neglect the values of freedom and social solidarity, and appreciate only powerful reliable software, you are making a terrible mistake.  </p>
<p> The fact that Torvalds says &#8220;open source&#8221; instead of &#8220;free software&#8221; shows where he is coming from. I wrote the GNU GPL to defend freedom for all users of all versions of a program. I developed version 3 to do that job better and protect against new threats.  Torvalds says he rejects this goal; that&#8217;s probably why he doesn&#8217;t appreciate GPL version 3. I respect his right to express his views, even though I think they are foolish. However, if you don&#8217;t want to lose your freedom, you had better not follow him.  </p>
</blockquote>
<p> Discussions of copyleft often blur these two camps. For much development this is irrelevant - the license stands on its  own irrespective of people&#8217;s motivations. But this schism explains periodical battles like the  <a href="http://lwn.net/Articles/200422/">GPLv3 controversy</a>, the <a href="http://kerneltrap.org/?q=node/4966">endless flames</a> when a proprietary source control tool was used for the kernel, and the GNU/Linux <a href="http://en.wikipedia.org/wiki/GNU/Linux_naming_controversy"> 	naming controversy</a>. The distinction is also important when thinking about free/open source software and what to make of it. </p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/the-divided-house-of-gpl/feed</wfw:commentRss>
		</item>
		<item>
		<title>First Recorded Usage of &#34;Hacker&#34;</title>
		<link>http://duartes.org/gustavo/blog/post/first-recorded-usage-of-hacker</link>
		<comments>http://duartes.org/gustavo/blog/post/first-recorded-usage-of-hacker#comments</comments>
		<pubDate>Thu, 28 Aug 2008 00:28:31 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Culture]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=50</guid>
		<description><![CDATA[Here&#8217;s the first known recorded usage of the word &#8220;hacker&#8221; in the tech sense, published in 1963 in MIT&#8217;s The Tech newspaper:

It was tracked down by Fred Shapiro, editor of The Yale Dictionary Of Quotations and author of a paper with a most hilarious and offensive name. The MIT article dispels the common notion that [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s the first known recorded usage of the word &#8220;hacker&#8221; in the tech sense, published in 1963 in MIT&#8217;s The Tech newspaper:</p>
<p align="center"><img src="http://static.duartes.org/img/blogPosts/firstRecordedUsageOfHacker.png" alt="First recorded usage of hacker" /></p>
<p>It was <a href="http://listserv.linguistlist.org/cgi-bin/wa?A2=ind0306B&amp;L=ads-l&amp;P=R5831&amp;m=24290">tracked down</a> by Fred Shapiro, editor of The Yale Dictionary Of Quotations and author of a paper with a most hilarious and offensive <a href="http://findarticles.com/p/articles/mi_go2573/is_200209/ai_n7467296">name</a>. The MIT article dispels the common notion that &#8220;hacker&#8221; was a purely white-hat term later corrupted by the media. The black-hat connotation was there early on; Richard Stallman was 10 years old when this was printed.</p>
<p>Most of what the article describes is now known as phone phreaking, though some sounds like <a href="http://en.wikipedia.org/wiki/War_dialing">war dialing</a>. It is fascinating this was taking place in 63, over four decades ago! The international phreaking scene was still strong through the late 90s, abusing <a href="http://en.wikipedia.org/wiki/Home_country_direct">home country direct</a> lines with software like BlueBEEP (&#8221;when freedom is outlawed, only outlaws will be free&#8221;), plus cell phone cloning and whatnot. That&#8217;s nearly 40 years of phreaking, though phone companies have since managed to stop widespread fraud.</p>
<p align="center"><img src="http://static.duartes.org/img/blogPosts/hacker.jpg" alt="A hacker" /> <span><br />
Hacking</span></p>
<p>This of course doesn&#8217;t &#8220;prove&#8221; that the black-hat meaning is the &#8220;true&#8221; meaning of hacker, just as &#8220;one who is employed doing mathematical calculations&#8221; is not the &#8220;true&#8221; meaning of computer. Language is fluid. The New Hacker&#8217;s Dictionary has this to say in the word&#8217;s <a href="http://www.ccil.org/jargon/jargon_23.html#TAG833">definition</a>:</p>
<blockquote><p>1. A person who enjoys exploring the details of programmable systems and how to stretch their capabilities, as opposed to most users, who prefer to learn only the minimum necessary.</p>
<p>2. One who programs enthusiastically (even obsessively) or who enjoys programming rather than just theorizing about programming. (&#8230;)</p>
<p>8. [deprecated] A malicious meddler who tries to discover sensitive information by poking around. Hence `password hacker&#8217;, `network hacker&#8217;. The correct term for this sense is cracker.</p></blockquote>
<p>The white-hat definitions are popular among geeks, but I&#8217;m not so sure about the deprecation. For one thing, cracker has a precise and also popular meaning: one who removes copyright protection from software. Meanwhile, blackhats aren&#8217;t exactly rolling over to surrender their language either. From the latest Phrack issue:</p>
<blockquote><p>So no, I wasn&#8217;t that kid that used to hang out at Radio Shack pulling apart electronic equipment and reassembling it to &#8220;see how it works.&#8221; (&#8230;) that doesn&#8217;t make you a &#8220;hacker&#8221; - it makes you a wannabe EE undergrad. (&#8230;) Hacking boxes makes you a &#8220;hacker&#8221; ! That&#8217;s right! Write your local representatives at Wikipedia / urbandictionary / OED and let them know that hackers are people that gain unauthorized access/privileges to computerized systems!</p></blockquote>
<p>The whole thing would offend most people, so no link. It&#8217;s readily googable but be careful about browser exploits, you never know. As a neutral party, Wikipedia has sensible guidelines when it comes to <a href="http://en.wikipedia.org/wiki/Wikipedia:Naming_conflict#How_to_make_a_choice_among_controversial_names">controversial names</a>:</p>
<blockquote><p>A city, country, people or person, by contrast, is a self-identifying entity: it has a preferred name for itself. The city formerly called Danzig now calls itself Gdansk; the man formerly known as Cassius Clay now calls himself Muhammad Ali. These names are not simply arbitrary terms but are key statements of an entity&#8217;s own identity. This should always be borne in mind when dealing with controversies involving self-identifying names. (&#8230;)</p>
<p>A number of objective criteria can be used to determine common or self-identifying usage:</p>
<ul>
<li>Is the name in common usage in English? (&#8230;)</li>
<li>Is it the name used by the subject to describe itself or themselves?</li>
</ul>
</blockquote>
<p>These criteria apply squarely to both types of &#8220;hackers.&#8221; Common usage? <a href="http://dictionary.reference.com/search?q=hacker">Check</a>. Used to describe themselves? Definitely. The word is now hopelessly ambiguous, as it seems to have been from the start, puzzling outsiders. But it&#8217;s always clear to hackers.</p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/first-recorded-usage-of-hacker/feed</wfw:commentRss>
		</item>
		<item>
		<title>Richard Feynman&#8217;s Modest Science</title>
		<link>http://duartes.org/gustavo/blog/post/richard-feynmans-modest-science</link>
		<comments>http://duartes.org/gustavo/blog/post/richard-feynmans-modest-science#comments</comments>
		<pubDate>Mon, 25 Aug 2008 05:28:35 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Culture]]></category>

		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=46</guid>
		<description><![CDATA[ When I was 18 and newly arrived in the US, I used to wonder around enjoying new features like the rule of law and great libraries everywhere.  Once while bumming out in North Denver I went into the Regis University library determined to read about physics. I had tried that once before, back [...]]]></description>
			<content:encoded><![CDATA[<p> When I was 18 and newly arrived in the US, I used to wonder around enjoying new features like the rule of law and great libraries everywhere.  Once while bumming out in North Denver I went into the Regis University library determined to read about physics. I had tried that once before, back in my high school, with poor results. As a teenager I had been obsessed with &#8220;understanding&#8221; physics and chemistry, especially atomic and quantum theory.  I didn&#8217;t know enough math to study the subjects deeply, but I wanted a conceptual grasp, however incomplete, that was at least half-way consistent and clear. </p>
<p> My high school books and classes left me with the strong feeling that I simply did not <i>get</i> physics. Try as I might, I could not accept the bizarre results of quantum mechanics, <a href="http://en.wikipedia.org/wiki/Wave_particle_duality">wave-particle duality</a>, or how Heisenberg&#8217;s uncertainty principle <i>could even be science</i>. I was baffled. When I brought it up with teachers, they had ready-made analogies to &#8220;teach&#8221; what happened in this sub-atomic world.  &#8220;Think of the solar system,&#8221; &#8220;think of springs connected to each other,&#8221; &#8220;well, it&#8217;s like this, suppose you have&#8230;&#8221; These analogies didn&#8217;t help at all. &#8220;You think too concretely, that&#8217;s why you can&#8217;t visualize it,&#8221; told me a teacher.  </p>
<p> So I&#8217;d sit there and try things, think nonverbally, think in wild shapes, somehow think differently to see if I could  imagine a sub-atomic particle and &#8220;get it.&#8221; No go. I wondered whether programming had perhaps damaged my mind by making it inflexible. I went to the school library and found a more advanced physics book, a bit tattered but no matter. I quit reading when I  realized the book still assumed the existence of the <a href="http://en.wikipedia.org/wiki/Luminiferous_aether">ether</a>. &#8220;Screw this,&#8221; I thought. So I flipped off the science bit, kept to my computers, and carried on. </p>
<p align="center"> 	<img alt="Feynman Lectures on Physics" src="http://static.duartes.org/img/blogPosts/feynmanLecturesOnPhysics.jpg"> </p>
<p> But here I was in the USA, land of opportunity and well-stocked libraries. Looking in the physics section I saw &#8220;The Feynman Lectures on Physics&#8221; sitting there, three volumes. I had a vague idea of who Feynman was, so I picked up the books and went straight to Volume 3, Chapter 1, Quantum Behavior. In the <b>very first page</b> he comes right out and says: </p>
<blockquote><p> 	Things on a very small scale behave like nothing that you have any direct experience about. They do not behave like waves, they do not behave like particles, 	they do not behave like clouds, or billiard balls, or weights on springs, or like anything that you have ever seen. (&#8230;) 	</p>
<p>Because atomic behavior is so unlike ordinary experience, it is very difficult to get used to, and it appears peculiar and mysterious to everyone&#8211;both to the novice and the experienced physicist. Even the experts do not understand it the way they would like to, and it is perfectly reasonable that they should not, because all of direct human experience and human intuition applies to large objects. We know how large objects will act, but things on a small scale just do not act that way.</p>
</blockquote>
<p> I felt a rush of enthusiasm reading this. It was so humble and visceral and honest. This was science in a way I had never seen before, simultaneously more rigorous and <i>human</i>. That first page alone drove a sledgehammer to my worldview and started rebuilding it. Perhaps childishly, I thought of the <a href="http://www.mithral.com/~beberg/manifesto.html">Hacker&#8217;s Manifesto</a>: &#8220;we&#8217;ve been spoon-fed baby food at school when we hungered for steak.&#8221;  I had just found one hell of a juicy stake. At one point Feynman asks students to imagine the various electromagnetic fields and waves in the classroom: coming from the earth&#8217;s interior, carrying radio and TV signals, traveling from warm foreheads to the blackboard, and so on. Then he says: </p>
<blockquote><p> 	I have asked you to imagine these electric and magnetic fields. What do you do? Do you know how? How do <i>I</i> imagine the electric 	and magnetic field? What do <i>I</i> actually see? What are the demands of the scientific imagination? Is it any different from 	trying to imagine that the room is full of invisible angels? No, it is not like imagining invisible angels. It requires a much higher 	degree of imagination (&#8230;). Why? Because invisible angels are <b>understandable</b>. (&#8230;) So you say, &#8220;Professor, please give me 	an approximate description of the electromagnetic waves, even though it may be slightly innacurate, so that I too can see them as well as I 	can see almost-invisible angels. Then I will modify the picture to the necessary abstraction.&#8221; 	</p>
<p> 	<b>I&#8217;m sorry I can&#8217;t do that for you. I don&#8217;t know how. I have no picture of this electromagnetic field that is in any sense accurate.</b> (&#8230;) 	So if you have some difficulty in making such a picture, you should not be worried that your difficulty is unusual. 	</p>
</blockquote>
<p>  Volume 2, pages 20-9 and 20-10
<p> Surely you&#8217;re joking - <i>you</i> don&#8217;t know?? I could hardly believe what I was reading. I had been hoping for a better explanation - a masterful analogy of weights on springs that would allow me to <i>really understand</i> physics. Instead, here was a Nobel laureate telling me that <i>he didn&#8217;t really understand it either</i> - not in the definite, make-believe fashion of high school science. Feynman lifted the veil for me - all my sanitized textbooks and uninspired teachers presented  science with <i>finality</i> and devoid of context, as if the gods had handed down a few scientific models to us. Analogies that were meant to &#8220;help understand&#8221; reality had in fact supplanted it; it was not simplification, but a gross distortion of what science really is.  This fake teaching would never say that atomic behavior is &#8220;peculiar and mysterious&#8221; because &#8220;human intuition applies to large objects.&#8221; No, its <i>entire aim</i> was to <b>pretend that science is not mysterious</b>. </p>
<p> Feynman embraces the whole of science: its beauty, its methods, the history and relationships of its ideas, how our minds react to it, and above all how it stands before the ultimate judge, nature. He&#8217;s at once fiercely empirical yet mindful of the crucial human context surrounding scientific ideas. The lectures are not only great technical writing but also a deep look into how we think about the world, into reason and the nature of knowledge. Of course, much of the work is to be done with paper, pencil, and math. Back then I didn&#8217;t even know calculus, so I couldn&#8217;t  really follow all the equations. But the books still gave me what I was looking for, and then some. </p>
<p> Now I have an undergrad in math, which puts me roughly in the 18th century, but better equipped to learn on my own. Some day I hope to take time off and hit physics again. If you want to read more of his stuff, Feynman wrote an insightful <a href="http://duartes.org/gustavo/blog/post/richard-feynman-challenger-disaster-software-engineering">essay on engineering</a> and there&#8217;s the classic <a href="http://www.lhup.edu/~dsimanek/cargocul.htm">Cargo Cult Science</a>, both online. Amazon has the <a href="http://www.amazon.com/Feynman-Lectures-Physics-including-Feynmans/dp/0805390456/gustduar-20">lectures</a> along with other books, and so might your local library. <img src='http://duartes.org/gustavo/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/richard-feynmans-modest-science/feed</wfw:commentRss>
		</item>
		<item>
		<title>CPU Rings, Privilege, and Protection</title>
		<link>http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection</link>
		<comments>http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection#comments</comments>
		<pubDate>Wed, 20 Aug 2008 06:38:41 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Internals]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Software Illustrated]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=38</guid>
		<description><![CDATA[ You probably know intuitively that applications have limited powers in Intel x86 computers and that only operating system code can perform certain tasks, but do you know how this really works? This post takes a look at  x86 privilege levels, the mechanism whereby the OS and CPU conspire to restrict what user-mode programs [...]]]></description>
			<content:encoded><![CDATA[<p> You probably know intuitively that applications have limited powers in Intel x86 computers and that only operating system code can perform certain tasks, but do you know how this really works? This post takes a look at  x86 <b>privilege levels</b>, the mechanism whereby the OS and CPU conspire to restrict what user-mode programs can do. There are four privilege levels, numbered 0 (most privileged) to 3 (least privileged), and three main resources being protected: memory, I/O ports, and the ability to execute certain machine instructions.  At any given time, an x86 CPU is running in a specific privilege level, which determines what code can and cannot do. These privilege levels are often described as protection rings, with the innermost ring corresponding to highest privilege. Most modern x86 kernels use only two privilege levels, 0 and 3: </p>
<p align="center"> 	<img alt="x86 Protectiong Rings" src="http://static.duartes.org/img/blogPosts/x86rings.png" /> 	<font size="-1"><br />x86 Protection Rings</font> </p>
<p> About 15 machine instructions, out of dozens, are restricted by the CPU to ring zero. Many others have limitations on their operands. These instructions can  subvert the protection mechanism or otherwise foment chaos if allowed in user mode, so they are reserved to the kernel. An attempt to run them outside of ring zero causes a general-protection exception, like when a program uses invalid memory addresses. Likewise, access to memory and I/O ports is restricted based on privilege level. But before we look at protection mechanisms, let&#8217;s see <i>exactly</i> how the CPU keeps track of the current privilege level, which involves the <a href="http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation">segment selectors</a> from the previous post. Here they are: </p>
<p align="center"> 	<img alt="x86 Segment Selectors" src="http://static.duartes.org/img/blogPosts/segmentSelectorDataAndCode.png" /> 	<font size="-1"><br />Segment Selectors - Data and Code</font> </p>
<p> The full contents of data segment selectors are loaded directly by code into various segment registers such as  ss (stack segment register) and ds (data segment register). This includes the contents of the Requested Privilege Level (RPL) field, whose meaning we tackle in a bit.   The code segment register (cs) is, however, magical.   First, its contents cannot be set directly by load instructions such as mov, but rather only by instructions that alter the flow of program execution, like call. Second, and importantly for us, instead of an RPL field that can be set by code, cs  has a <b>Current Privilege Level</b> (CPL) field maintained by the CPU itself. This 2-bit CPL field in the code segment register <b>is always equal to</b> the CPU&#8217;s current privilege level.  The Intel docs wobble a little on this fact, and sometimes online documents confuse the issue, but that&#8217;s the hard and fast rule. At any time, no matter what&#8217;s going on in the CPU, a look at the CPL in cs will tell you the privilege level code is running with. </p>
<p> Keep in mind that the <b>CPU privilege level has nothing to do with operating system users</b>. Whether you&#8217;re root, Administrator, guest, or a regular user, <i>it does not matter</i>. <b>All user code runs in ring 3</b> and <b>all kernel 	code runs in ring 0</b>, regardless of the OS user on whose behalf the code operates. Sometimes certain kernel tasks can be pushed to user mode, for example user-mode device drivers in Windows Vista, but these are just special processes  doing a job for the kernel and can usually be killed without major consequences.  </p>
<p> Due to restricted access to memory and I/O ports, user mode can do almost <i>nothing</i> to the outside world without calling on the kernel. It can&#8217;t open files, send network packets, print to the screen, or allocate memory. User processes run in a severely limited sandbox set up by the gods of ring zero. That&#8217;s why it&#8217;s <i>impossible</i>, by design, for a process to leak memory beyond its existence or leave open files after it exits. All of the data structures that control such things - memory, open files, etc - cannot be touched directly by user code; once a process finishes, the sandbox is torn down by the kernel. That&#8217;s why our servers can have 600 days of uptime - as long as the hardware and the kernel don&#8217;t crap out, stuff can run for ever. This is also why Windows 95 / 98 crashed so much: it&#8217;s not because &#8220;M$ sucks&#8221;  but because important data structures were left accessible to user mode for compatibility reasons. It was  probably a good trade-off at the time, albeit at high cost. </p>
<p> The CPU protects memory at two crucial points: when a segment selector is loaded and when a page of memory is accessed with a linear address. Protection thus mirrors <a href="http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation">memory address translation</a> where both segmentation and paging are involved. When a data segment selector is being loaded, the check below takes place: </p>
<p align="center"> 	<img alt="x86 Segment Protection" src="http://static.duartes.org/img/blogPosts/segmentProtection.png" /> 	<font size="-1"><br />x86 Segment Protection</font> </p>
<p> Since a higher number means less privilege, MAX() above picks the least privileged of CPL and RPL, and compares it to the descriptor privilege level (DPL). If the DPL is higher or equal, then access is allowed.  The idea behind RPL is to allow kernel code to load a segment using lowered privilege. For example, you could use an RPL of 3 to ensure that a given operation uses segments accessible to user-mode. The exception is for the stack segment register ss, for which the three of CPL, RPL, and DPL must match exactly. </p>
<p> In truth, segment protection scarcely matters because modern kernels use a flat address space where the user-mode segments can reach the entire linear address space.  Useful memory protection is done in the paging unit when a linear address is converted into a physical address. Each memory page is a block of bytes described by a <b>page table entry</b> containing two fields related to protection: a supervisor flag and a read/write flag.  The supervisor flag is the primary x86 memory protection mechanism used by kernels. When it is on, the page cannot be accessed from ring 3.  While the read/write flag isn&#8217;t as important for enforcing privilege, it&#8217;s still useful. When a process is loaded, pages storing binary images (code) are marked as read only, thereby catching some pointer errors if a program attempts to write to these pages. This flag is also used to implement <a href="http://todo">copy on write</a> when a process is forked in Unix. Upon forking, the parent&#8217;s pages are marked read only and shared with the forked child. If either process attempts to write to the page, the processor triggers a fault and the kernel knows to duplicate the page and mark it read/write for the writing process.  </p>
<p> Finally, we need a way for the CPU to switch between privilege levels.  If ring 3 code could transfer control to arbitrary spots in the kernel, it would be easy to subvert the operating system by jumping into the wrong (right?) places. A controlled transfer is necessary. This is accomplished via <b>gate descriptors</b> and  via the <b>sysenter</b> instruction. A gate descriptor is a segment descriptor of type system, and comes in four sub-types: call-gate descriptor, interrupt-gate descriptor, trap-gate descriptor, and task-gate descriptor. Call gates provide a kernel entry point that can be used with ordinary call and jmp instructions, but they aren&#8217;t used much so I&#8217;ll ignore them. Task gates aren&#8217;t so hot either (in Linux, they are only used in double faults, which are caused by either kernel or hardware problems). </p>
<p> That leaves two juicier ones: interrupt and trap gates, which are used to handle hardware interrupts (<i>e.g.</i>, keyboard, timer, disks) and  exceptions (<i>e.g.</i>, page faults, divide by zero). I&#8217;ll refer to both as an &#8220;interrupt&#8221;.  These gate descriptors are stored in the <b>Interrupt Descriptor Table</b> (IDT).  Each interrupt is assigned a number between 0 and 255 called a <b>vector</b>, which the processor uses as an index into the IDT when figuring out which gate descriptor to use when handling the interrupt. Interrupt and trap gates are nearly identical. Their format is shown below along with the privilege checks enforced when an interrupt happens. I filled in some values for the Linux kernel to make things concrete. </p>
<p align="center"> 	<img alt="Interrupt Descriptor with Privilege Check" src="http://static.duartes.org/img/blogPosts/interruptDescriptorWithPrivilegeCheck.png" /> 	<font size="-1"><br />Interrupt Descriptor with Privilege Check</font> </p>
<p> Both the DPL and the segment selector in the gate regulate access, while segment selector plus offset together nail down an entry point for the interrupt handler code. Kernels normally use the segment selector for the kernel code segment in these gate descriptors. An interrupt can <b>never</b> transfer control from a more-privileged to a less-privileged ring. Privilege must either stay the same (when the kernel itself is interrupted) or be elevated (when user-mode code is interrupted). In either case, the resulting CPL will be equal to to the DPL of the destination code segment; if the CPL changes, a stack switch also occurs. If an interrupt is triggered by code via an instruction like <b>int n</b>, one more check takes place: the gate DPL must be at the same or lower privilege as the CPL. This prevents user code from triggering random interrupts. If these checks fail - you guessed it - a general-protection exception happens. All Linux interrupt handlers end up running in ring zero. </p>
<p> During initialization, the Linux kernel first sets up an IDT in <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/kernel/head_32.S#L475">setup_idt()</a> that ignores all interrupts. It then uses functions in <a href="http://lxr.linux.no/linux+v2.6.25.6/include/asm-x86/desc.h#L322">include/asm-x86/desc.h</a> to flesh out common IDT entries in <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/kernel/traps_32.c#L1140">arch/x86/kernel/traps_32.c</a>. In Linux, a gate descriptor with &#8220;system&#8221; in its name is accessible from user mode and its set function uses a DPL of 3. A &#8220;system gate&#8221; is an Intel trap gate accessible to user mode. Otherwise, the terminology matches up. Hardware interrupt gates are not set here however, but instead in the appropriate drivers. </p>
<p> Three gates are accessible to user mode: vectors 3 and 4 are used for debugging and checking for numeric overflows, respectively. Then a system gate is set up for the <a href="http://lxr.linux.no/linux+v2.6.25.6/include/asm-x86/mach-default/irq_vectors.h#L31">SYSCALL_VECTOR</a>, which is 0&#215;80 for the x86 architecture. This was <i>the mechanism</i> for a process to transfer control to the kernel, to make a <i>system call</i>, and back in the day I applied for an  &#8220;int 0&#215;80&#8243; vanity license plate :).  Starting with the Pentium Pro, the <b>sysenter</b> instruction was introduced as a faster way to make system calls. It relies on special-purpose CPU registers that store the code segment, entry point, and other tidbits for the kernel system call handler. When sysenter is executed the CPU does no privilege checking, going immediately into CPL 0 and loading new values into the registers for code and stack (cs, eip, ss, and esp). Only ring zero can load the sysenter setup registers, which is done in <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/vdso/vdso32-setup.c#L235">enable_sep_cpu()</a>. </p>
<p> Finally, when it&#8217;s time to return to ring 3, the kernel issues an <b>iret</b> or <b>sysexit</b> instruction to return from interrupts and system calls, respectively, thus leaving ring 0 and resuming execution of user code with a CPL of 3. Vim tells me I&#8217;m approaching 1,900 words, so I/O port protection is for another day. This concludes our tour of x86 rings and protection. Thanks for reading! </p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/cpu-rings-privilege-and-protection/feed</wfw:commentRss>
		</item>
		<item>
		<title>Memory Translation and Segmentation</title>
		<link>http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation</link>
		<comments>http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation#comments</comments>
		<pubDate>Tue, 12 Aug 2008 08:30:08 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Internals]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Software Illustrated]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=28</guid>
		<description><![CDATA[ This post is the first in a series about memory and protection in Intel-compatible (x86) computers, going further down the path of how kernels work. As in the boot series,  I&#8217;ll link to Linux kernel sources but give Windows examples as well (sorry, I&#8217;m ignorant about the BSDs and the Mac, but most [...]]]></description>
			<content:encoded><![CDATA[<p> This post is the first in a series about memory and protection in Intel-compatible (x86) computers, going further down the path of how kernels work. As in the <a href="http://duartes.org/gustavo/blog/post/kernel-boot-process">boot series</a>,  I&#8217;ll link to Linux kernel sources but give Windows examples as well (sorry, I&#8217;m ignorant about the BSDs and the Mac, but most of the discussion applies). Let me know what I screw up. </p>
<p> In the <a href="http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map">chipsets</a> that power Intel motherboards, memory is accessed by the CPU via the front side bus, which connects it to the northbridge chip. The memory addresses exchanged in the front side bus are <b>physical memory addresses</b>, raw numbers from zero to the top of the available physical memory.  These numbers are mapped to physical RAM sticks by the northbridge. Physical addresses are concrete and final - no translation, no paging, no privilege checks - you put them on the bus and that&#8217;s that. Within the CPU, however, programs use <b>logical memory addresses</b>, which must be translated into physical addresses before memory access can take place. Conceptually address translation looks like this: </p>
<p align="center"> 	<img alt="Memory address translation" src="http://static.duartes.org/img/blogPosts/memoryTranslation.png" /> 	<font size="-1"><br />Memory address translation in x86 CPUs with paging enabled</font> </p>
<p> This is <b>not</b> a physical diagram, only a depiction of the address translation process, specifically for when the CPU has paging enabled. If you turn off paging, the output from the segmentation unit is already a physical address; in 16-bit real mode that is always the case.  Translation starts when the CPU executes an instruction that refers to a memory address. The first step is translating that logic address into a <b>linear address</b>. But why go through this step instead of having software use linear (or physical) addresses directly? For roughly the same reason humans have an appendix whose primary function is getting infected. It&#8217;s a wrinkle of evolution. To really make sense of x86 segmentation we need to go back to 1978. </p>
<p> The original <a href="http://en.wikipedia.org/wiki/8086">8086</a> had 16-bit registers and its instructions used mostly 8-bit or 16-bit operands. This allowed code to work with 2<sup>16</sup> bytes, or 64K of memory, yet Intel engineers were keen on letting the CPU use more memory without expanding the size of registers and instructions.  So they introduced <i>segment registers</i> as a means to tell the CPU <i>which</i> 64K chunk of memory a program&#8217;s instructions were going to work on. It was a reasonable solution: first you load a segment register, effectively saying &#8220;here, I want to work on the memory chunk starting at X&#8221;;  afterwards, 16-bit memory addresses used by your code are interpreted as offsets into your chunk, or segment. There were four segment registers: one for the stack (ss), one for program code (cs), and two for data (ds, es).  Most programs were small enough back then to fit their whole stack, code, and data each in a 64K segment, so segmentation was often transparent. </p>
</p>
<p> Nowadays segmentation is still present and is always enabled in x86 processors. Each instruction that touches memory implicitly uses a segment register. For example, a jump instruction uses the code segment register (cs) whereas a stack push instruction uses the stack segment register (ss). In most cases you can explicitly override the segment register used by an instruction. Segment registers store 16-bit <b>segment selectors</b>; they can be loaded directly with instructions like MOV. The sole exception is cs, which can only be changed by instructions that affect the flow of execution, like CALL or JMP. Though segmentation is always on, it works differently in real mode versus protected mode. </p>
<p> In real mode, such as during  <a href="http://duartes.org/gustavo/blog/post/how-computers-boot-up">early boot</a>, the segment selector is a 16-bit number specifying the physical memory address for the start of a segment. This number must somehow be scaled, otherwise it would also  be limited to 64K, defeating the purpose of segmentation.  For example, the CPU could use the segment selector as the 16 most significant bits of the physical memory address (by shifting it 16 bits to the left, which is equivalent to multiplying by 2<sup>16</sup>). This simple rule would enable segments to address 4 gigs of memory in 64K chunks.  Sadly Intel made a bizarre decision to multiply the segment selector by only 2<sup>4</sup> (or 16), which in a single stroke  confined memory to about 1MB and unduly complicated translation.  Here&#8217;s an example showing a jump instruction where cs contains 0&#215;1000: </p>
<p align="center"> 	<img alt="Real mode segmentation" src="http://static.duartes.org/img/blogPosts/realModeSegmentation.png" /> 	<font size="-1"><br />Real mode segmentation</font> </p>
<p> Real mode segment starts range from 0 all the way to 0xFFFF0 (16 bytes short of 1 MB) in 16-byte increments.  To these values you add a 16-bit offset (the logical address) between 0 and 0xFFFF. It <a href="http://mirror.href.com/thestarman/asm/debug/Segments.html">follows</a> that there are multiple segment/offset combinations  pointing to the same memory location, and physical addresses fall above 1MB if your segment is high enough (see the infamous <a href="http://en.wikipedia.org/wiki/A20_line">A20 line</a>).  Also, when writing C code in real mode a <a href="http://en.wikipedia.org/wiki/C_memory_model">far pointer</a> is a pointer that contains both the  segment selector <i>and</i> the logical address, which allows it to address 1MB of memory. Far indeed. As programs started getting bigger and outgrowing 64K segments, segmentation and its strange ways complicated development for the x86 platform. This may all sound quaintly odd now but it has driven programmers into the wretched depths of madness. </p>
<p> In 32-bit protected mode, a segment selector is no longer a raw number, but instead it contains  an index into a table of <b>segment descriptors</b>. The table is simply an array containing 8-byte records, where each record describes one segment and looks thus: </p>
<p align="center"> 	<img alt="Segment descriptor" src="http://static.duartes.org/img/blogPosts/segmentDescriptor.png" /> 	<font size="-1"><br />Segment descriptor</font> </p>
<p> There are three types of segments: code, data, and system. For brevity, only the common features in the descriptor are shown here. The <b>base address</b> is a 32-bit linear address pointing to the beginning of the segment, while the  <b>limit</b> specifies how big the segment is. Adding the base address to a logical memory address yields a linear address. DPL is the descriptor privilege level; it is a number from 0 (most privileged, kernel mode) to 3 (least privileged, user mode) that controls access to the segment. </p>
<p> These segment descriptors are stored in two tables: the <b>Global Descriptor Table</b> (GDT) and the  <b>Local Descriptor Table</b> (LDT).   Each CPU (or core) in a computer contains a register called <b>gdtr</b> which stores the linear memory address of the first byte in the GDT.  To choose a segment, you must load a segment register with a <b>segment selector</b> in the following format: </p>
<p align="center"> 	<img alt="Segment Selector" src="http://static.duartes.org/img/blogPosts/segmentSelector.png" /> 	<font size="-1"><br />Segment Selector</font> </p>
<p> 	The TI bit is 0 for the GDT and 1 for the LDT, while the index specifies the desired segment selector within the table.   	We&#8217;ll deal with RPL, Requested Privilege Level, later on. Now, come to think of it, when the CPU is in 32-bit mode registers and instructions 	can address the entire linear address space <i>anyway</i>, so there&#8217;s really no need to give them a push with a base 	address or other shenanigan. So why not set the base address to zero and let logical addresses coincide with 	linear addresses? Intel docs call this &#8220;flat model&#8221; and it&#8217;s exactly what modern x86 kernels do (they use the basic 	flat model, specifically). Basic flat model is equivalent to disabling segmentation when it comes to translating memory addresses. 	So in all its glory, here&#8217;s the jump example running in 32-bit protected mode, with real-world values 	for a Linux user-mode app: </p>
<p align="center"> 	<img alt="Protected Mode Segmentation" src="http://static.duartes.org/img/blogPosts/protectedModeSegmentation.png" /> 	<font size="-1"><br />Protected Mode Segmentation</font> </p>
<p> The contents of a segment descriptor are cached once they are accessed, so there&#8217;s no need to actually read the GDT in subsequent accesses, which would kill performance. Each segment register has a hidden part to store the cached descriptor that corresponds to its segment selector. For more details, including more info on the LDT, see chapter 3 of the Intel System Programming Guide Volume 3a. Volumes 2a and 2b, which cover every x86 instruction, also shed light on the various types of x86 addressing operands - 16-bit, 16-bit with segment selector (which can be used by far pointers), 32-bit, etc. </p>
<p> In Linux, only 3 segment descriptors are used during boot. They are defined with the <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/pm.c#L103">GDT_ENTRY</a> macro and stored in the <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/pm.c#L119">boot_gdt</a> array. Two of the segments are flat, addressing the entire 32-bit space: a code segment loaded into cs and a data segment loaded into the other segment registers. The third segment is a system segment called the Task State Segment. After boot, each CPU has its own copy of the GDT. They are all nearly identical, but a few entries change depending on the running process. You can see the layout of the Linux GDT in <a href="http://lxr.linux.no/linux+v2.6.25.6/include/asm-x86/segment.h#L15">segment.h</a> and its instantiation is <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/kernel/cpu/common.c#L24">here</a>.  There are four primary GDT entries: two flat ones for code and data in kernel mode, and another two for user mode. When looking at the Linux GDT, notice the holes inserted on purpose to align data with CPU cache lines - an artifact of the  <a href="http://en.wikipedia.org/wiki/Von_Neumann_bottleneck#Von_Neumann_bottleneck">von Neumann bottleneck</a> that has become a plague. Finally, the classic &#8220;Segmentation fault&#8221; Unix error message is <i>not</i> due to x86-style segments, but rather invalid memory addresses normally detected by the paging unit - alas, topic for an upcoming post. </p>
<p> Intel deftly worked around their original segmentation kludge, offering a flexible way for us to choose whether to segment or go flat.  Since coinciding logical and linear addresses are simpler to handle, they became standard, such that 64-bit mode now enforces a flat linear address space.  But even in flat mode segments are still crucial for x86 protection, the mechanism that defends the kernel from user-mode processes and every process from each other. It&#8217;s a dog eat dog world out there!   In the next post, we&#8217;ll take a peek at protection levels and how segments implement them. </p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/memory-translation-and-segmentation/feed</wfw:commentRss>
		</item>
		<item>
		<title>Certification Demand and Quality</title>
		<link>http://duartes.org/gustavo/blog/post/certification-demand-and-quality</link>
		<comments>http://duartes.org/gustavo/blog/post/certification-demand-and-quality#comments</comments>
		<pubDate>Mon, 28 Jul 2008 07:11:30 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=25</guid>
		<description><![CDATA[ A few years back I got three silly tech certifications: Certified Information Systems Security Professional (CISSP),  Microsoft Certified Database Administrator (MCDBA), and Microsoft Certified Systems Engineer (MCSE). That sounds like an odd mix of certs for a programmer; I have them because I&#8217;m a mercenary  an independent developer and I also do [...]]]></description>
			<content:encoded><![CDATA[<p> A few years back I got three silly tech certifications: Certified Information Systems Security Professional (CISSP),  Microsoft Certified Database Administrator (MCDBA), and Microsoft Certified Systems Engineer (MCSE). That sounds like an odd mix of certs for a programmer; I have them because I&#8217;m <s>a mercenary</s>  an independent developer and I also do architecture work. Many programmers regard certifications with scorn, for good reason. But merit, or lack thereof, is one piece of the puzzle. For me the main questions around a certification are: </p>
<ol>
<li>Is there market demand for the certification?</li>
<li>Does the certification truly verify knowledge or ability?</li>
<li>Should I look for it when hiring?</li>
</ol>
<p> Certification providers make a lot of claims about jobs and improved incomes due to certification. Most skip over the sticky issue of correlation versus causation. Do certifications boost your income, or is motivation behind both? Or, less graciously, is the data simply crap from people seeking your hard-earned cash? We can get an idea of demand from Dice.com: </p>
<p align="center"> 	<img alt="Dice.com - Jobs per certification" src="http://static.duartes.org/img/blogPosts/jobsPerCertification.png"> 	<font size="-1"><br />Is this the MCDBA? Or is this the CCNA? Or is this the IRA? I thought it was the UK!</font> </p>
<p> By looking at total cert numbers, there&#8217;s clearly some demand. Strangely Java certifications seem to be an exception. Please let me know if I made a mistake there.  Absolute numbers tell part of the story, but a better test is comparing the number of jobs that mention a given certification to the total number of relevant jobs. The chart below is my attempt at that: </p>
<p align="center"> 	<img alt="Dice.com - % of relevant jobs mentioning certification" src="http://static.duartes.org/img/blogPosts/jobsMentioningCertification.png"> 	<font size="-1"><br />Dice.com - % of relevant jobs mentioning certification</font> </p>
<p> The data is flawed since it&#8217;s impossible to query &#8220;all relevant jobs&#8221;, but I tried to make sure it was sane for each cert (I posted the actual searches as a comment). I think this reasonably captures market demand for certifications, including the fortunate reality that programmers can safely ignore them.  Outside of programming demand is stronger; in security the CISSP is notably successful.  There are two points worth mentioning. First, certifications still have an effect on customers and jobs that have not explicitly asked for it. Whether that matters depends on your career: people who are starting out or interview frequently for contracts stand to benefit more. Second, the more clueful a company is, the less stock they put in certifications. Some hardcore, academic, or start-up workplaces downright  <a href="http://steve-yegge.blogspot.com/2007/09/ten-tips-for-slightly-less-awful-resume.html">shun certifications</a>, especially programming ones. </p>
<p> Which brings us to the next point: do these certs prove anything? For the ones I have obtained, all in multiple-choice format, I feel safe answering &#8220;hell no!&#8221; Certified people might truly know the subject <i>or</i> they might have studied for a month <i>or</i> they might be good at multiple-choice tests.  Basic answering techniques go a <i>long</i> way toward passing the tests. The ol&#8217; elimination, contradiction, and parsing answers out of the tests themselves gets you almost there. Add a few hours studying targeted prep books and materials and random people could obtain random multiple-choice certifications, provided they test well in general. </p>
<p> When I took the tests my programming work involved security, so I fulfilled the CISSP requirement for three years of experience.  I had decent knowledge of certain areas covered by the Microsoft stuff and the CISSP, but in other areas I was utterly ignorant. If these tests were up to snuff, I would have had to work much harder. The CISSP, given its better reputation, was a let down - I found it <i>looser</i> than the Microsoft stuff, which is dodgy to begin with. As luck would have it, in the week prior to the CISSP test (<i>i.e.</i>, the study week) I started reading Harry Potter, which is like crack in that it takes your mind off everything, only more addictive.  In the evening before the test I thought &#8220;crap, I just lost $400 in test fees.&#8221; I wondered whether to even show up -  &#8220;surely the mighty CISSP is harder than the Microsoft stuff and you can&#8217;t pass with no study, little sleep, and a head full of Hogwarts.&#8221; Not so.  Hence, in a <a href="http://thinkexist.com/quotation/i_refuse_to_join_any_club_that_would_have_me_as_a/207365.html">Groucho Marx</a> sort of way, I lost all respect for multiple-choice certifications. </p>
<p> In fact, the CISSP unites two negative aspects of certification: a faulty testing mechanism coupled with a heavy-handed experience requirement. I oppose criteria like degrees and years of experience, which correlate weakly with talent and job performance. They also strike me as unfair in a certification - let each employer decide how to value such things independently of the knowledge &#8216;verified&#8217; by the testing. </p>
<p> My conclusion is that certifications based solely on multiple-choice tests are at best misguided and at worst shams.  I don&#8217;t see how they could be fixed either. There is a fundamental disconnect between filling in the right blank and getting technology work done. For programming certifications the multiple-choice format is ludicrous. Hence these silly tests will remain a marketing and money-making scheme fueled by naive employers,  who put faith in vacuous credentials, and the professionals who play along for supposed career benefits.  Or maybe they&#8217;re fueled by the naive customers of the employers. </p>
<p> The final question is whether to look for certifications when hiring. In my experience there&#8217;s actually some positive correlation between certifications and the quality of job candidates, but it is too weak to be useful. I can&#8217;t use certifications as a weeding tool, they don&#8217;t guarantee a phone interview is worthwhile, and I would <i>never</i> rely on them for a hiring decision. Multiple-choice certs are silently ignored in my hiring process. The reality might be different for more stringent, hands-on certifications like the Cisco Certified Internetwork Expert (CCIE). </p>
<p> As to whether you should get certified, it&#8217;s obviously too particular a decision, but I hope this information helps. One of the best pro-certification arguments is that if you study the stuff anyway, for fun or profit, then why not go ahead and take the tests? It helps you focus somewhat and you get the warm fuzzy I-passed feeling. Coupled with the potential advantages in the market, maybe that&#8217;s good enough reason to take them. For those  in markets where certifications are strong, it may be necessary. But on principle I&#8217;d sooner avoid them and for most programmers I don&#8217;t think they make sense. </p>
<p> Certifications that actually proved some knowledge and talent would be useful for job seekers and employers. Where possible, we must shun broken certifications and pressure vendors into adopting a valid testing scheme. This necessarily would involve <i>practical</i> tests, like the ones in the Red Hat Certified Engineer test or the CCIE. Both are head and shoulders above the ones I took. For programmers, certification could use on-the-spot, time-capped programming assignments. The results could be  a mixture of the source code produced (the most important piece) and the outcome of an automated test suite. That&#8217;d be pretty useful during the selection process: the ability to see source code produced in standard conditions of temperature and pressure, before you sink hours into a candidate. </p>
<p>What do you say?</p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/certification-demand-and-quality/feed</wfw:commentRss>
		</item>
		<item>
		<title>Lucky to be a Programmer</title>
		<link>http://duartes.org/gustavo/blog/post/lucky-to-be-a-programmer</link>
		<comments>http://duartes.org/gustavo/blog/post/lucky-to-be-a-programmer#comments</comments>
		<pubDate>Mon, 14 Jul 2008 07:46:24 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=27</guid>
		<description><![CDATA[ For the past few weeks I&#8217;ve been working with a fellow developer on a project that required an all-out programming effort. It&#8217;s done now, so we&#8217;re back to a regular schedule, but when people hear about the crazy hours they often say they&#8217;re sorry. They really shouldn&#8217;t be. I would never do this often, [...]]]></description>
			<content:encoded><![CDATA[<p> For the past few weeks I&#8217;ve been working with a fellow developer on a project that required an all-out programming effort. It&#8217;s done now, so we&#8217;re back to a regular schedule, but when people hear about the crazy hours they often say they&#8217;re sorry. They really shouldn&#8217;t be. I would never do this often, or for long periods, or without proper compensation if done for an employer, but the truth is that these programming blitzkriegs are some of my favorite periods in life. Under the right conditions, writing software is so intensely pleasurable it should be illegal. </p>
<p> Many programmers relate to this, but others are taken aback when they hear it.  I think it&#8217;s because institutions are so good at squeezing the fun out of  everything. It&#8217;s appalling for example how schools can take the most vibrant topics and mangle them into formulaic, mediocre slog. And so it is for programming. Many corporations turn an inherently rewarding experience into something people just barely stomach in exchange for a paycheck. </p>
<p> That&#8217;s too bad. Few things are better than spending time in a creative haze, consumed by ideas, watching your work  come to life, going to bed eager to wake up quickly and go try things out.  I am not suggesting that excessive hours are needed or even advisable; a sane schedule is a must except for  occasional binges. The point is that programming is an intense creative pleasure, a perfect mixture of puzzles, writing, and craftsmanship. </p>
<p> Programming offers intriguing challenges and ample room for invention. Some problems are investigative and reductionist: Why is this code running slowly? What on earth is causing that bug? Others are constructive, like devising algorithms and architectures. All of them are a delight if you enjoy analytical work, immersed in a world full of beasts like malware, routers, caches, protocols, databases, graphs, and numbers. </p>
<p> This analytical side is what most people associate with programming. It does make it interesting, like a complex strategy game. But in most software the primary challenge is <i>communication</i>: with fellow programmers via code and with users via interfaces. By and large, writing code is more essay than puzzle. It is shaping  your ideas and schemes into a coherent body; it is seeking clarity, simplicity and conciseness. Both code and interfaces abound with the simple joy of creation. </p>
<p> Another source of pleasure is that under certain conditions, <i>beauty</i> arises in programming. It may sound like bullshit but it&#8217;s real, the kind of thing that makes your day better. Take for example Euclid&#8217;s 2-line proof that  <a href="http://primes.utm.edu/notes/proofs/infinite/euclids.html">prime numbers are infinite</a>. I think many would find it beautiful - so succint and such a fascinating result.  This is the beauty of math, <a href="http://www.quotationspage.com/quote/26185.html">cold and austere</a>, and it pervades software. It is in clever algorithms like <a href="http://en.wikipedia.org/wiki/Quicksort">quicksort</a>, in the sources of kernels and compilers, in <a href="http://www.matasano.com/log/1032/this-new-vulnerability-dowds-inhuman-flash-exploit/">elegant exploits</a> and in the tricks we pull to solve everyday problems. When you see these solutions, be it famous algorithm or mundane trick, you smile and think &#8220;how smart&#8221; and it feels good. How noble in reason! </p>
<p> A non-math sort of beauty also exists in code, analogous to eloquence in discourse.  It&#8217;s present in well-factored software that does a lot with little code, in short and crisp methods, in well-done architectures. Some languages make this hard and not all programmers produce it, but it&#8217;s a joy to read and work on such code. If you&#8217;re working in an expressive language with coworkers whose code you enjoy, it happens often enough to brighten things up. </p>
<p> Now for craftsmanship. In a sense software is abstract - where does program behavior exist but in our minds? Yet we call it <i>building</i> software for a reason. Programs are shaped feature by feature, architectures start out as scaffolds and grow, user interfaces come together, bugs are fixed and hotspots are optimized to make things run fast. Software provides a deeply satisfying sense of craft.   We <i>build</i> stuff out of pure ideas and then get to watch it   <i>working</i> to solve real problems and make people a little better off. Or far better off, as the case may be. </p>
<p> Take Biology.  Despite nearly 400 years of scientific revolution, Biology has been unable to deliver on crucial problems like effective cures for viral infections or cancer. Some of our best progress, like antibiotics, has been due to chance and random experimentation. You start a clinical trial for a hypertension drug and suddenly - whoah - all your subjects have hard-ons! Viagra <a href="http://en.wikipedia.org/wiki/Viagra#History">is born</a>. To be sure, chance plays a role in all endeavours, but  Physics and Chemistry have a comprehensive theoretical basis powering systematic improvements, whereas Biology has been largely confined to kludges. Wanna treat cancer? Here, blast the patient with radiation and poison and hopefully the cancer will die first. They&#8217;re brilliant kludges, and I&#8217;m happy to have them, but it&#8217;s a far cry from the precision we&#8217;ve had elsewhere. </p>
<p> Software is changing that. Just barely 50 years ago the shape of DNA was being discovered, but now anyone can browse and download <a href="http://www.ncbi.nlm.nih.gov/sites/entrez?term=seqstat_complete&amp;cmd=Search&amp;db=genomeprj">hundreds 	of complete genome sequences</a>. Or look up <a href="http://www.ncbi.nlm.nih.gov/sites/entrez?db=genome">thousands of genes</a>  (<a href="http://www.ncbi.nlm.nih.gov/sites/entrez?Db=gene&amp;Cmd=ShowDetailView&amp;TermToSearch=9940&amp;ordinalpos=10&amp;itool=EntrezSystem2.PEntrez.Gene.Gene_ResultsPanel.Gene_RVDocSum">DLEC1</a> for a random example), complete with nucleotide sequence, amino-acid sequence for expressed proteins, literature mentioning the gene, you name it! Or you can <a href="http://blast.ncbi.nlm.nih.gov/Blast.cgi">search</a> vast gene and protein databases for nucleotide or amino-acid sequences, perhaps after sequencing something in ever-cheaper devices, and get a comprehensive report on the match. It doesn&#8217;t matter if they&#8217;re exact, because the algorithm in <a href="http://en.wikipedia.org/wiki/BLAST">BLAST</a>, the standard sequence search tool, delivers partial maches across databases and species, scored by match likelihood. These advances will enable massive breakthroughs in medicine. Biology is entering a new era, like Physics in the 18th century, propelled by software.  </p>
<p> Yea, sure, biologists have a minor role :P, but we in computing increasingly power major developments in science, culture, and business. When a third-world kid looks up a Wikipedia entry, it&#8217;s our work too! We wrote the RFCs and the networking stacks, the browser and MediaWiki, the OSes and the HTTP servers. Not to mention a lot of the Wikipedia entries, but since a few were on company time I&#8217;ll leave them aside. The influence of technologists goes beyond bits and bytes: it was <a href="http://en.wikipedia.org/wiki/Ward_Cunningham">a programmer</a> who invented wikis and <a href="http://en.wikipedia.org/wiki/Blogging#Origins">our community</a> started blogs. <a href="http://en.wikipedia.org/wiki/Henry_Mencken">Henry Mencken</a> pointed out correctly that &#8220;freedom of the press is limited to those who own one&#8221;.  It&#8217;s a pity he&#8217;s not around to watch our  creations break down the stifling conformity and cozy subservience of professional journalism. Less glamorously but to great benefit our applications have delivered steep productivity gains to businesses across the economy. These are a few examples in a long list. </p>
<p> Three years ago, when I finished my undergrad (after being a programmer for many years), I was about to enter med school. At that point, a couple of negative experiences had me somewhat burned out on computer work. I&#8217;m happy I stuck with it. I&#8217;m still interested in biomedical research, but if I were to get involved I&#8217;d rather come in from the software angle, because frankly it&#8217;s too much fun to pass on. My mom thinks I&#8217;m a typist but oh well. </p>
<p> If you find yourself stuck in a place that&#8217;s killing your innate passion for technology, by all means, move the hell on!  Don&#8217;t stay put while your enthusiasm is slowly drained.  It&#8217;s hard to find motivated people to hire so you&#8217;ve got a major asset already; there are plenty of employers - and companies to be started - that will better suit you.  For people who think they might like programming, your mileage may vary, but I highly recommend it as a career. Not only  is the <a href="http://www.bls.gov/oco/ocos267.htm">outlook bullish</a> on the job front, but as the role of software grows in society we&#8217;ll see more exciting and beneficial changes delivered by technology. I&#8217;m delighted to be along for the ride as constantly <a href="http://www.youtube.com/watch?v=1A0BmbiM53Q">my art and craft I try to master</a>. </p>
<p> PS: thanks for putting up with the irregular posting schedule. The plan is to stick to regular posting now that things have calmed down. And if you like the song, download the mp3 because the YouTube audio doesn&#8217;t do it justice. </p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/lucky-to-be-a-programmer/feed</wfw:commentRss>
		</item>
		<item>
		<title>The Kernel Boot Process</title>
		<link>http://duartes.org/gustavo/blog/post/kernel-boot-process</link>
		<comments>http://duartes.org/gustavo/blog/post/kernel-boot-process#comments</comments>
		<pubDate>Mon, 23 Jun 2008 08:20:17 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Internals]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Software Illustrated]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=23</guid>
		<description><![CDATA[ The previous post explained how computers boot up right up to the point where the boot loader, after stuffing the kernel image into memory,  is about to jump into the kernel entry point. This last post about booting takes a look at the guts of the kernel to see how an operating system [...]]]></description>
			<content:encoded><![CDATA[<p> The previous post explained <a href="http://duartes.org/gustavo/blog/post/how-computers-boot-up">how computers boot up</a> right up to the point where the boot loader, after stuffing the kernel image into memory,  is about to jump into the kernel entry point. This last post about booting takes a look at the guts of the kernel to see how an operating system starts life. Since I have an <a href="http://duartes.org/gustavo/blog/post/reality-driven-development">empirical bent</a> I&#8217;ll link heavily to the sources for Linux kernel 2.6.25.6 at the <a href="http://lxr.linux.no">Linux Cross Reference</a>. The sources are very readable if you are familiar with C-like syntax; even if you miss some details you can get the gist of what&#8217;s happening.  The main obstacle is the lack of context around some of the code, such as when or why  it runs or the underlying features of the machine. I hope to provide a bit of that context. Due to brevity (hah!) a lot of fun stuff - like interrupts and memory - gets only a nod for now.  The post ends with the highlights for the Windows boot. </p>
<p> At this point in the Intel x86 boot story the processor is running in real-mode, is able to address 1 MB of memory, and RAM looks like this for a modern Linux system: </p>
<p align="center"> 	<img alt="RAM contents after boot loader runs" src="http://static.duartes.org/img/blogPosts/memoryAfterBootloader.png" /> 	<font size="-1"><br />RAM contents after boot loader is done</font> </p>
<p> The kernel image has been loaded to memory by the boot loader using the BIOS disk I/O services. This image is an exact copy of the file in your hard drive that contains the kernel, e.g. <b>/boot/vmlinuz-2.6.22-14-server</b>. The image is split into two pieces: a small part containing the real-mode kernel code is loaded below the 640K barrier; the bulk of the kernel, which runs in protected mode, is loaded after the first megabyte of memory. </p>
<p> The action starts in the real-mode kernel header pictured above. This region of memory is used to implement the <a href="http://lxr.linux.no/linux+v2.6.25.6/Documentation/i386/boot.txt"> 	Linux boot protocol</a> between the boot loader and the kernel. Some of the values there are read by the boot loader while doing its work. These include amenities such as a human-readable string containing the kernel version, but also crucial information like the size of the real-mode kernel piece. The boot loader also <i>writes</i> values to this region, such as the memory address for the command-line parameters given by the user in the boot menu. Once the boot loader is finished it has filled in all of the parameters required by the kernel header. It&#8217;s then time to jump into the kernel entry point. The diagram below shows the code sequence for the kernel initialization, along with source directories, files, and line numbers: </p>
<p align="center"> 	<img alt="Architecture-specific Linux Kernel Initialization" src="http://static.duartes.org/img/blogPosts/kernelInitPartOne.png" /> 	<font size="-1"><br />Architecture-specific Linux Kernel Initialization</font> </p>
<p> The early kernel start-up for the Intel architecture is in file  <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/header.S">arch/x86/boot/header.S</a>. It&#8217;s in assembly language, which is rare for the kernel at large but common for boot code. The start of this file actually contains boot sector code, a left over from the days when Linux could work without a boot loader. Nowadays this boot sector, if executed, only prints a &#8220;bugger_off_msg&#8221; to the user and reboots. Modern boot loaders ignore this legacy code. After the boot sector code we have the first 15 bytes of the real-mode kernel header; these two pieces together add up to 512 bytes, the size of a typical disk sector on Intel hardware.</p>
<p> After these 512 bytes, at offset  0&#215;200, we find the very first instruction that runs as part of the Linux kernel: the real-mode entry point.  It&#8217;s in <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/header.S#L110">header.S:110</a> and it is a 2-byte jump written directly  in machine code as 0&#215;3aeb. You can verify this by running hexdump on your kernel image and seeing the bytes at that offset - just a sanity check to make sure it&#8217;s not all a dream. The boot loader jumps into this location when it is finished, which in turn jumps to  <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/header.S#L229">header.S:229</a> where we have a regular assembly routine called start_of_setup. This short routine sets up a stack, zeroes the <a href="http://en.wikipedia.org/wiki/.bss">bss</a> segment  (the area that contains static variables, so they start with zero values) for the real-mode kernel and then jumps to  good old C code at <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/main.c#L122">arch/x86/boot/main.c:122</a>. </p>
<p> main() does some house keeping like detecting memory layout, setting a video mode, etc. It then calls  <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/pm.c#L153">go_to_protected_mode()</a>. Before the CPU can be set to protected mode, however, a few tasks must be done. There are two main issues: interrupts and memory. In real-mode the <a href="http://en.wikipedia.org/wiki/Interrupt_vector_table">interrupt vector table</a> for the processor is always at memory address 0, whereas in protected mode the location of the interrupt vector table is  stored in a CPU register called IDTR. Meanwhile, the translation of logical memory addresses (the ones programs manipulate) to linear memory addresses (a raw number from 0 to the top of the memory) is different between real-mode and protected mode. Protected mode requires a register called GDTR to be loaded with the address of a <a href="http://en.wikipedia.org/wiki/Global_descriptor_table">Global Descriptor Table</a> for memory. So go_to_protected_mode() calls  <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/pm.c#L144">setup_idt()</a> and  <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/pm.c#L115">setup_gdt()</a> to install a temporary interrupt descriptor table and global descriptor table.</p>
<p> We&#8217;re now ready for the plunge into protected mode, which is done by <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/pmjump.S#L31">protected_mode_jump</a>, another assembly routine.   This routine enables protected mode by setting the PE bit in the CR0 CPU register. At this point we&#8217;re running with <a href="http://en.wikipedia.org/wiki/Paging">paging</a> <b>disabled</b>; paging is an optional feature of the processor, even in protected mode, and there&#8217;s no need for it yet. What&#8217;s important is that we&#8217;re no longer confined to the 640K barrier and can now address up to 4GB of RAM. The routine then calls the 32-bit kernel entry point, which is   <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/compressed/head_32.S#L35">startup_32</a> for  compressed kernels.   This routine does some basic register initializations and calls  <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/boot/compressed/misc.c#L368">decompress_kernel()</a>, a C function to do the actual decompression.
<p>decompress_kernel() prints the familiar &#8220;Decompressing Linux&#8230;&#8221; message. Decompression happens in-place and once it&#8217;s finished the uncompressed kernel image has overwritten  the compressed one pictured in the first diagram. Hence the uncompressed contents also start at 1MB. decompress_kernel() then prints &#8220;done.&#8221; and the comforting &#8220;Booting the kernel.&#8221;   By &#8220;Booting&#8221; it means a jump to the final entry point in this whole story,  given to Linus by God himself atop <a href="http://en.wikipedia.org/wiki/Halti">Mountain Halti</a>, which is the protected-mode kernel entry point at the start of the second megabyte of RAM (0&#215;100000).  That sacred location contains a routine called, uh, <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/kernel/head_32.S#L86">startup_32</a>. But <i>this</i> one is in a different directory, you see.  </p>
<p> The second incarnation of startup_32 is also an assembly routine, but it contains 32-bit mode initializations. It clears the bss segment for the protected-mode kernel (which is the <i>true</i> kernel that will now run until the machine reboots or shuts down), sets up the final global descriptor table for memory, builds page tables so that paging can be turned on, enables paging, initializes a stack,  creates the final interrupt descriptor table, and finally jumps to  to the architecture-independent kernel start-up,  <a href="http://lxr.linux.no/linux+v2.6.25.6/init/main.c#L507">start_kernel()</a>. The diagram below shows the code flow for the last leg of the boot: </p>
<p align="center"> 	<img alt="Architecture-independent Linux Kernel Initialization" src="http://static.duartes.org/img/blogPosts/kernelInitPartTwo.png" /> 	<font size="-1"><br />Architecture-independent Linux Kernel Initialization</font> </p>
<p> start_kernel() looks more like typical kernel code, which is nearly all C and machine independent. The function is a long list of calls to initializations of the various kernel subsystems and data structures. These include the scheduler, memory zones, time keeping, and so on.  start_kernel() then calls <a href="http://lxr.linux.no/linux+v2.6.25.6/init/main.c#L432">rest_init()</a>, at which point things are almost all working. rest_init() creates a kernel thread passing another function, <a href="http://lxr.linux.no/linux+v2.6.25.6/init/main.c#L808">kernel_init()</a>, as the entry point. rest_init() then calls <a href="http://lxr.linux.no/linux+v2.6.25.6/kernel/sched.c#L3959">schedule()</a> to kickstart  task scheduling and goes to sleep by calling  <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/kernel/process_32.c#L180">cpu_idle()</a>, which is the idle thread for the Linux kernel. cpu_idle() runs forever and so does process zero, which hosts it. Whenever there is work to do - a runnable process - process zero gets booted out of the CPU, only to return when no runnable processes are available. </p>
<p> But here&#8217;s the kicker for us. This idle loop is the end of the long thread we followed since boot, it&#8217;s the final descendent of the very first <i>jump</i> executed by the processor after power up. All of this mess, from reset vector to BIOS to MBR to boot loader to real-mode kernel to protected-mode kernel, all of it leads right here,  jump by jump by jump it ends in the idle loop for the boot processor, cpu_idle(). Which is really kind of cool.  However, this can&#8217;t be the whole story otherwise the computer would do no work. </p>
<p> At this point, the kernel thread started previously is ready to kick in, displacing process 0 and its  idle thread. And so it does, at which point kernel_init() starts running since it was given as the thread entry point.  <a href="http://lxr.linux.no/linux+v2.6.25.6/init/main.c#L808">kernel_init()</a> is responsible for initializing the remaining CPUs in the system, which have been halted since boot. All of the code we&#8217;ve seen so far has been executed in a single CPU, called the boot processor. As the other CPUs, called application processors, are started they come up in real-mode and must run through several initializations as well. Many of the code paths are common, as you can see in the code for <a href="http://lxr.linux.no/linux+v2.6.25.6/arch/x86/kernel/head_32.S#L86">startup_32</a>, but there are slight forks taken by the late-coming application processors.  Finally, kernel_init() calls  <a href="http://lxr.linux.no/linux+v2.6.25.6/init/main.c#L769">init_post()</a>, which  tries to execute a user-mode process in the following order: /sbin/init, /etc/init, /bin/init, and /bin/sh. If all fail, the kernel will panic. Luckily init is usually there,  and starts running as PID 1. It checks its configuration file to figure out which processes to launch, which might include X11 Windows, programs for logging in on the console, network daemons, and so on. Thus ends the boot process as yet another Linux box starts running somewhere. May your uptime be long and untroubled. </p>
<p> The process for Windows is similar in many ways, given the common architecture.  Many of the same problems are faced and similar initializations must be done. When it comes to boot one of the biggest differences is that Windows packs all of the real-mode kernel code, and some of the initial protected mode code, into the boot loader itself (C:\NTLDR). So instead of having two regions in the same kernel image, Windows uses different binary images. Plus Linux completely separates boot loader and kernel; in a way this automatically falls out of the open source process. The diagram below shows the main bits for the Windows kernel:
<p align="center"> 	<img alt="Windows Kernel Initialization" src="http://static.duartes.org/img/blogPosts/windowsKernelInit.png" /> 	<font size="-1"><br />Windows Kernel Initialization</font> </p>
<p> The Windows user-mode start-up is naturally very different. There&#8217;s no /sbin/init, but rather Csrss.exe and Winlogon.exe.  Winlogon spawns <b>Services.exe</b>, which starts all of the Windows Services, and Lsass.exe, the local security authentication subsystem. The classic Windows login dialog runs in the context of Winlogon. </p>
<p> This is the end of this boot series. Thanks everyone for reading and for feedback. I&#8217;m sorry some things got superficial treatment; I&#8217;ve gotta start somewhere and only so much fits into blog-sized bites. But nothing like a day after the next; my plan is to do regular &#8220;Software Illustrated&#8221; posts like this series along with other topics. Meanwhile, here are some resources: </p>
<ul>
<li>The best, most important resource, is source code for real kernels, either Linux or one of the BSDs.</li>
<li>Intel publishes excellent  	<a href="http://www.intel.com/products/processor/manuals/index.htm">Software Developer&#8217;s Manuals</a>, which 	you can download for free.</li>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0596005652/gustduar-20">Understanding the Linux Kernel</a> is a good book and walks through a lot of the Linux Kernel  	sources. It&#8217;s getting outdated and it&#8217;s dry, but I&#8217;d still recommend it to anyone who wants to grok the kernel. 	<a href="http://www.amazon.com/exec/obidos/ASIN/0596005903/gustduar-20">Linux Device Drivers</a> is more fun, teaches well, but is limited in scope. Finally, Patrick Moroney suggested <a href="http://www.amazon.com/exec/obidos/ASIN/0672327201/gustduar-20">Linux Kernel Development</a> by Robert Love in the comments for this post. I&#8217;ve heard other positive reviews for that book, so it sounds worth checking out.	</li>
<li>For Windows, the best reference by far is  	<a href="http://www.amazon.com/exec/obidos/ASIN/0735625301/gustduar-20">Windows Internals</a> by David Solomon and 	<a href="http://blogs.technet.com/markrussinovich/">Mark Russinovich</a>, the latter of Sysinternals fame.  	This is a great book, well-written and thorough. The main downside is the lack of source code. 	</li>
</ul>
<p>[Update: Thanks to <a href="http://www.sirartisan.net/">Marius Barbu</a> for catching a mistake where I wrote "CR3" instead of GDTR]</p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/kernel-boot-process/feed</wfw:commentRss>
		</item>
		<item>
		<title>How Computers Boot Up</title>
		<link>http://duartes.org/gustavo/blog/post/how-computers-boot-up</link>
		<comments>http://duartes.org/gustavo/blog/post/how-computers-boot-up#comments</comments>
		<pubDate>Thu, 05 Jun 2008 17:40:31 +0000</pubDate>
		<dc:creator>Gustavo Duarte</dc:creator>
		
		<category><![CDATA[Internals]]></category>

		<category><![CDATA[Software Illustrated]]></category>

		<guid isPermaLink="false">http://duartes.org/gustavo/blog/?p=21</guid>
		<description><![CDATA[ The previous post described  motherboards and the memory map  in Intel computers to set the scene for the initial phases of boot. Booting is an involved, hacky, multi-stage affair -  fun stuff. Here&#8217;s an outline of the process: 
 	 	An outline of the boot sequence 
 Things start rolling when [...]]]></description>
			<content:encoded><![CDATA[<p> The previous post described  <a href="http://duartes.org/gustavo/blog/post/motherboard-chipset-memory-map">motherboards and the memory map</a>  in Intel computers to set the scene for the initial phases of boot. Booting is an involved, hacky, multi-stage affair -  fun stuff. Here&#8217;s an outline of the process: </p>
<p align="center"> 	<img alt="Boot Sequence Outline" src="http://static.duartes.org/img/blogPosts/bootProcess.png"> 	<font size="-1"><br />An outline of the boot sequence</font> </p>
<p> Things start rolling when you press the power button on the computer (no! do tell!). Once the motherboard is powered up it initializes its own firmware - the chipset and other tidbits - and tries to get the CPU running. If things fail at this point (e.g., the CPU is busted or missing) then you will likely have a system that looks completely dead except for rotating fans.  A few motherboards manage to emit beeps for an absent or faulty CPU, but the zombie-with-fans state is the most common scenario based on my experience. Sometimes USB or other devices can cause this to happen: unplugging <i>all</i> non-essential devices is  a possible cure for a system that was working and suddenly appears dead like this. You can then single out the culprit device by elimination. </p>
<p> If all is well the CPU starts running. In a multi-processor or multi-core system one CPU is dynamically chosen to be the bootstrap processor (BSP) that runs all of the BIOS and kernel initialization code. The remaining processors, called application processors (AP) at this point, remain halted until later on when they are explicitly activated by the kernel.  Intel CPUs have been evolving over the years but they&#8217;re fully backwards compatible, so modern CPUs <i>can</i> behave like the original 1978 <a href="http://en.wikipedia.org/wiki/Intel_8086">Intel 8086</a>, which is exactly what they do after power up. In this primitive power up state the processor is in <a href="http://en.wikipedia.org/wiki/Real_mode">real mode</a>  with memory <a href="http://en.wikipedia.org/wiki/Paging">paging</a> disabled. This is like  ancient MS-DOS where only 1 MB of memory can be addressed and any code can write to any place in memory -  there&#8217;s no notion of protection or privilege.</p>
<p> Most <a href="http://en.wikipedia.org/wiki/Processor_register">registers</a> in the CPU have well-defined values after power up, including the instruction pointer (EIP) which holds the memory address for the instruction being executed by the CPU. Intel CPUs use a hack whereby even though only 1MB of memory can be addressed at power up, a hidden base address (an offset, essentially) is applied to EIP so that the first instruction executed is at address 0xFFFFFFF0 (16 bytes short of the end of 4 gigs of memory and well above one megabyte).  This magical address is called the <a href="http://en.wikipedia.org/wiki/Reset_vector">reset vector</a> and is standard for modern Intel CPUs. </p>
<p> The motherboard ensures that the instruction at the reset vector is a <i>jump</i> to the memory location mapped to the BIOS entry point. This jump implicitly clears the hidden base address present at power up. All of these memory locations have the right contents needed by the CPU thanks to the <a href="http://duartes.org/gustavo/blog/post/motherboard-chipset-memory-map">memory map</a> kept by the chipset. They are all mapped to flash memory containing the BIOS since at this point the RAM modules have random crap in them. An example of the relevant memory regions is shown below: </p>
<p align="center"> 	<img alt="Memory Regions During Boot" src="http://static.duartes.org/img/blogPosts/bootMemoryRegions.png"> 	<font size="-1"><br />Important memory regions during boot</font> </p>
<p> The CPU then starts executing BIOS code, which initializes some of the hardware in the machine. Afterwards the BIOS kicks off the <a href="http://en.wikipedia.org/wiki/Power_on_self_test">Power-on Self Test</a> (POST) which tests various components in the computer.  Lack of a working video card fails the POST and causes the BIOS to halt and emit beeps to let you know what&#8217;s wrong, since messages on the screen aren&#8217;t an option.  A working video card takes us to a stage where the computer looks alive: manufacturer logos are printed, memory starts to be tested, angels blare their horns.   Other POST failures, like a missing keyboard, lead to halts with an error message on the screen. The POST involves a mixture of testing and initialization, including sorting out all the resources - interrupts, memory ranges, I/O ports - for PCI devices.  Modern BIOSes that follow the <a href="http://en.wikipedia.org/wiki/ACPI">Advanced Configuration and Power Interface</a> build a number of data tables that describe the devices in the computer; these tables are later used by the kernel. </p>
<p> After the POST the BIOS wants to boot up an operating system, which must be found somewhere: hard drives, CD-ROM drives,  floppy disks, etc. The actual order in which the BIOS seeks a boot device is user configurable. If there is no suitable boot device the BIOS halts with a complaint like &#8220;Non-System Disk or Disk Error.&#8221; A dead hard drive might present with this symptom. Hopefully this doesn&#8217;t happen and the BIOS finds a working disk allowing the boot to proceed.  </p>
<p> The BIOS now reads the first 512-byte <a href="http://en.wikipedia.org/wiki/Disk_sector">sector</a> (sector zero) of the hard disk. This is called the <a href="http://en.wikipedia.org/wiki/Master_boot_record">Master Boot Record</a> and it normally contains two vital components: a tiny OS-specific bootstrapping program at the start of the MBR followed by a partition table for the disk. The BIOS however does not care about any of this: it simply loads the contents of the MBR into memory location 0&#215;7c00 and jumps to that location to start executing whatever code is in the MBR. </p>
<p align="center"> 	<img alt="Master Boot Record" src="http://static.duartes.org/img/blogPosts/masterBootRecord.png"> 	<font size="-1"><br />Master Boot Record</font> </p>
<p> The specific code in the MBR could be a Windows MBR loader, code from Linux loaders such as LILO or GRUB, or  even a virus. In contrast the partition table is standardized: it is a 64-byte area with four 16-byte entries describing how the disk has been divided up (so you can run multiple operating systems or have separate volumes in the same disk). Traditionally Microsoft MBR code takes a look at the partition table, finds the (only) partition marked as active, loads the boot sector for <i>that</i> partition, and runs that code.  The <b>boot sector</b> is the first sector of a partition, as opposed to the first sector for the whole disk. If something is wrong with the partition table you would get messages like &#8220;Invalid Partition Table&#8221; or &#8220;Missing Operating System.&#8221; This message does <b>not</b> come from the BIOS but rather from the MBR code loaded from disk. Thus the specific message depends on the MBR flavor. </p>
<p> Boot loading has gotten more sophisticated and flexible over time. The Linux boot loaders Lilo and GRUB can handle a wide variety of operating systems, file systems, and boot configurations. Their MBR code  does not necessarily follow the &#8220;boot the active partition&#8221; approach described above. But functionally the process goes like this:	 </p>
<ol>
<li>The MBR itself contains the first stage of the boot loader. GRUB calls this stage 1.</li>
<li>Due to its tiny size, the code in the MBR does just enough to load another sector from disk 	that contains additional boostrap code. This sector might be the boot sector for a partition, but 	could also be a sector that was hard-coded into the MBR code when the MBR was installed.  	</li>
<li> 	The MBR code plus code loaded in step 2 then read a file containing the second stage of the boot loader.  	In GRUB this is GRUB Stage 2, and in Windows Server this is c:\NTLDR. If step 2 fails in Windows you&#8217;d get a message 	like &#8220;NTLDR is missing&#8221;. The stage 2 code then reads a boot 	configuration file (e.g., grub.conf in GRUB, boot.ini in Windows). It then presents boot choices to the 	user or simply goes ahead in a single-boot system.</li>
<li>At this point the boot loader code needs to fire up a kernel. It must know enough about file systems 	to read the kernel from the boot partition. In Linux this means reading a file like &#8220;vmlinuz-2.6.22-14-server&#8221; 	containing the kernel, loading the file into memory and jumping to the kernel bootstrap code.  	In Windows Server 2003 some of the kernel start-up code is separate from the kernel image itself and is 	actually embedded into NTLDR. After performing several initializations, NTDLR loads the kernel image 	from file c:\Windows\System32\ntoskrnl.exe and, just as GRUB does, jumps to the kernel entry point.  	</li>
</ol>
<p> There&#8217;s a complication worth mentioning (aka, I told you this thing is hacky). The image for a current Linux kernel, even compressed, does not fit into the 640K of RAM available in real mode. My vanilla Ubuntu kernel is 1.7 MB compressed. Yet the boot loader must run in real mode in order to call the BIOS routines for reading from the disk, since the kernel is clearly not available at that point. The solution is the venerable <a href="http://en.wikipedia.org/wiki/Unreal_mode">unreal mode</a>. This is not a true processor mode (I wish the engineers at Intel were allowed to have fun like that), but rather a technique where a program switches back and forth between real mode and protected mode in order to access memory above 1MB while still using the BIOS. If you read GRUB source code, you&#8217;ll see these transitions all over the place (look under stage2/ for calls to real_to_prot and prot_to_real). At the end of this sticky process the loader has stuffed the kernel in memory, by hook or by crook, but it leaves the processor in  real mode when it&#8217;s done. </p>
<p> We&#8217;re now at the jump from &#8220;Boot Loader&#8221; to &#8220;Early Kernel Initialization&#8221; as shown in the first diagram. That&#8217;s when things heat up as the kernel starts to unfold and set things in motion.  The next post will be a guided tour through the Linux Kernel initialization with links to sources at the <a href="http://lxr.linux.no/">Linux Cross Reference</a>. I can&#8217;t do the same for Windows <img src='http://duartes.org/gustavo/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> but I&#8217;ll point out the highlights. </p>
<p> [Update: cleared up discussion of NTLDR.] </p>
]]></content:encoded>
			<wfw:commentRss>http://duartes.org/gustavo/blog/post/how-computers-boot-up/feed</wfw:commentRss>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.000 seconds -->
<!-- Cached page served by WP-Cache -->
<!-- Compression = gzip -->