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

<channel>
	<title>Rants, Rambles, and Rhinos</title>
	<atom:link href="http://samuelkerr.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://samuelkerr.com</link>
	<description>Charging into the blog-o-sphere!</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:16:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Reverse Engineering the Master Boot Record</title>
		<link>http://samuelkerr.com/?p=262</link>
		<comments>http://samuelkerr.com/?p=262#comments</comments>
		<pubDate>Mon, 26 Jul 2010 14:40:58 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[General Computing]]></category>
		<category><![CDATA[Reverse Engineering]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=262</guid>
		<description><![CDATA[One day, I was curious about how the computer system goes from booting to actually loading up an operating system. Obviously, it must retrieve the operating system from disk at some point, so I decided to investigate this. The first &#8230; <a href="http://samuelkerr.com/?p=262">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One day, I was curious about how the computer system goes from booting to actually loading up an operating system. Obviously, it must retrieve the operating system from disk at some point, so I decided to investigate this. The first step in this process is reading the MBR, or <a href="http://en.wikipedia.org/wiki/Master_boot_record">Master Boot Record</a> of the hard drive. The MBR is used to store data about where the OS is stored on the drive. </p>
<p>I figured the MBR would be interesting to learn a little bit more about, so I decided to load it up into <a href="http://www.hex-rays.com/idapro/">IDA Pro</a>, a tool for disassembling programs, and see what I could find out.<br />
<div id="attachment_274" class="wp-caption alignleft" style="width: 272px"><a href="http://samuelkerr.com/wp-content/uploads/2010/07/Baby-rhino-6078359.jpg"><img src="http://samuelkerr.com/wp-content/uploads/2010/07/Baby-rhino-6078359-262x300.jpg" alt="" title="Baby-rhino-6078359" width="262" height="300" class="size-medium wp-image-274" /></a><p class="wp-caption-text">This baby rhino was also curious about MBRs.</p></div><br />
I learned a lot and had a lot of fun, so I&#8217;m presenting it here to share my results.</p>
<p><span id="more-262"></span></p>
<p>For this analysis, I assume that you are familiar with the x86 architecture and assembly. If not, WikiBooks has some great information about it <a href="http://en.wikibooks.org/wiki/X86_Assembly">here</a>. I am also using IDA Pro to do this. I have tried to provide comments and labeling in my IDA work, but I also explain each block of code separately.</p>
<p>The first step in figuring out the MBR was to actually get a copy of it I could work with. To do this, I used <a href="http://www.hexworkshop.com/">Hex Workshop</a>, which offers a way to do a binary copy of hard disks. The MBR is always located as the first sector of the disk, so I used Hex Workshop and extracted this file. It is only 1 sector long, so it is a mere 512 bytes.</p>
<p>After looking at <a href="http://en.wikipedia.org/wiki/Master_boot_record">Wikipedia</a>, I figured out the MBR structure was:</p>
<pre>
0000h - 01B7h       Code Area (440 bytes)
01B8h - 01BBh       Disk Signature (4 bytes)
01BCh - 01BDh       Generally Zeroed out (2 bytes)
01BEh - 01FDh       List of Partition Records (4 16-byte structures)
01FEh - 01FFh       MBR Signature (2 bytes - Must be AA55h)
</pre>
<p>The above structure is what gets loaded into memory and executed. The code area is going to do a few different things, which I look at below. The disk signature can be used to uniquely identify a hard disk. The partition records define different operating systems and partitions on the hard disk. Have you ever noticed how you have to jump through some hoops if you want to have more than 4 operating systems or partitions on your computer? Well, that&#8217;s because you only have 4 partition records available. The MBR signature helps illustrate that this is in fact an MBR structure.</p>
<p>The partition records are a pretty important part of the MBR, so I also examined their structure. It is:</p>
<pre>
0000h - 0000h    Status byte (80h for bootable, 00h for non-bootable, others are invalid) (1 byte)
0001h - 0003h    CHS address of first absolute sector (3 bytes)
0004h - 0004h    Partition type (1 byte)
0005h - 0007h    CHS address of last absolute sector (3 bytes)
0008h - 000Bh    LBA of first absolute sector (4 bytes)
000Ch - 000Fh    Number of sectors in partition (4 bytes)
</pre>
<p>That is a pretty simple structure; just a start and stop address, length, and a few informational bytes. The CHS format is a little confusing though. CHS stands for Cylinder-Head-Sector and defines an address inside of a physical hard drive. You can read more about CHS here. The LBA address stands for Logical Block Address. LBA is a format to linearly address space on the hard drive, rather than defining 3 separate numbers for Cylinder-Head-Sector format. More information about LBA is here.</p>
<p>After examining the file MBR structure, I loaded the binary file into IDA Pro. Since it is a binary file, IDA doesn&#8217;t know where the correct segments or entry points are, or even if it is 16 or 32 bit code. Since we don&#8217;t have an OS yet, we know that this code is 16 bit. Looking at the MBR structure, the code starts at the very first byte of the file. Knowing this, I configured IDA and converted the first few bytes to code. I got the following:</p>
<pre>
s0:0000 ; ---------------------------------------------------------------------------
s0:0000
s0:0000 ; Segment type: Pure code
s0:0000 seg000          segment byte public 'CODE' use16
s0:0000                 assume cs:seg000
s0:0000                 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
s0:0000                 xor     ax, ax          ; Zero out AX
s0:0002                 mov     ss, ax          ; Set SS to 0
s0:0004                 mov     sp, 7C00h       ; Set SP to 7C00h
s0:0007                 mov     es, ax          ; Set ES to 0
s0:0009                 mov     ds, ax          ; Set DS to 0
s0:000B                 mov     si, 7C00h       ; Source for the copy
s0:000E                 mov     di, 600h        ; This is the destination for the copy
s0:0011                 mov     cx, 200h        ; We want to copy 200h bytes, which is the length
s0:0011                                         ;    of one sector, i.e. the whole MBR.
s0:0014                 cld                     ; Clear Direction Flag
s0:0015                 rep movsb               ; Copies CX bytes from [SI] to [DI]
s0:0015                                         ;    i.e. from [7C00h] to [600h]
s0:0017                 push    ax              ; New value for CS
s0:0018
s0:0018 loc_18:                                 ; New value for IP
s0:0018                 push    61Ch
s0:001B                 retf                    ; Pops the top of the stack into IP then pops CS
s0:001B	                                        ;    off next.
s0:001B                                         ;    i.e. we will run from 0000h:61Ch,
s0:001B                                         ;    which is where we just copied ourselves to.
s0:001B                                         ;
s0:001B                                         ; Execution continues at the next instruction.
</pre>
<p>I have tried to add a lot of comments to show what is going on. Essentially though, what this is doing is copying the MBR from 0000h:7C00h to 0000:600h. This is necessary, because it will later load the OS to 0000h:7C00h, so it needs to get itself out of the way. It does this using the &#8216;rep movsb&#8217; which does a binary copy of 200 bytes from SI (7C00h) to DI (600h).</p>
<p>An interesting part about the code above is the way that the &#8216;retf&#8217; instruction is used. This does what is known as a &#8216;far jump&#8217;. This means it not only jumps to a different instruction address, but also a different code segment. Both of these values are popped off of the stack, with the offset being on top and the new segment being second. Before the retf instruction, the program pushes 0 and then &#8217;61Ch&#8217; onto the stack to setup for this far jump. This may seem strange, but since it just copied all the program data to 0000h:0600h, 61Ch is actually the offset to the instruction directly after the retf in the binary.</p>
<p>The next few instructions are:</p>
<pre>
s0:001C                 sti                     ; Enable interrupts
s0:001D                 mov     cx, 4           ; This will be used for the loop.
s0:001D                                         ;    We only want to examine 4 partition records.
s0:0020                 mov     bp, 7BEh        ; This is the offset to the first partition
s0:0020                                         ;   record.
s0:0020                                         ; In the MBR structure, the first partition
s0:0020                                         ;    record is at base+1BEh,
s0:0023                                              so it is 600h + 1BEh = 7BEh
s0:0023
</pre>
<p>First thing this code does is to enable <a href="http://en.wikipedia.org/wiki/Interrupt">interrupts</a> so that it can be interrupted if necessary. Next, it sets the CX register to 4 and BP to 7BEh. BP is the offset to the partition records (there is a description of these records <a href="http://en.wikipedia.org/wiki/Master_boot_record">here</a>). CX is indicating that we will only examine 4 records (since there are only 4 in the MBR). So this is setting up to iterate over the 4 partition records to find the bootable one that we want.</p>
<p>After this is a loop that tries to find a bootable partition entry. The code is:</p>
<pre>
s0:0023 loc_23:                                 ; CODE XREF: seg000:0030j
s0:0023                 cmp     byte ptr [bp+0], 0 ; Compares the status byte to 0
s0:0027                 jl      short FoundBootableEntry ; Jumps if the status flag is not 0.
s0:0027                                         ;    This will happen if the MSB of [bp+0]
s0:0027                                         ;    is 1, essentially saying that if it
s0:0027                                         ;    is 0x80, it will jump.
s0:0027                                         ;
s0:0027                                         ; This jump indicates that we have found the
s0:0027                                         ;    bootable partition.
s0:0029                 jnz     PrintInvalidPartitionTable ; It's not 0x80 and it's not 0x0, so
s0:0029                                         ;    it's invalid. Jump to an error state.
s0:002D                 add     bp, 10h         ; Go to the next partition record.
s0:0030                 loop    loc_23          ; Loop while CX != 0
s0:0032                 int     18h             ; TRANSFER TO ROM BASIC
s0:0032                                         ; causes transfer to ROM-based BASIC (IBM-PC)
s0:0032                                         ; often reboots a compatible; often has no effect
s0:0034                                         ; at all
</pre>
<p>Remember how above we moved the offset of 7BEh into BP? That is so this loop can then examine the partition records. The comparison is checking the status byte of the partition record and comparing it to 0. If it is 0, the first jump will not be taken, nor will the second jump, so 10h is added to BP and the loop is restarted. Advancing the BP register means that we will examine a different partition record. If, after 4 iterations, we have still not found a bootable partition entry, an &#8216;int 18h&#8217; call will be made. On old IBM PCs, this would run a BASIC interpreter from ROM, but few computers have this. So essentially, an int 18h call will just stop the system. Imagine that, if you have no bootable entries, you&#8217;re computer won&#8217;t boot!</p>
<p>If the status byte of the parition record was in fact 80h, the first jump would have been taken. The JL instruction does a jump if the status flag is set to 1. This flag will get set by the previous CMP instruction if the high order bit is set in the status byte, i.e. the status byte is 80h. If the entries status byte is neither 80h or 00h, a jump is made to the PrintInvalidPartitionTable location. I&#8217;ll talk about that a little bit, but it&#8217;s pretty boring (it just prints an error message); when a bootable entry is found, things are much more fun.</p>
<p>The next block of code is run when a bootable entry is found. Here it is:</p>
<pre>
s0:0034 FoundBootableEntry:                     ; CODE XREF: seg000:0027j
s0:0034                                         ; seg000:00AEj
s0:0034                 mov     [bp+0], dl      ; Save the drive number for later
s0:0034                                         ;    Note that since this will most likely be the
s0:0034                                         ;    first hard drive, DL will probably be 0x80
s0:0037                 push    bp
s0:0038                 mov     byte ptr [bp+11h], 5
s0:003C                 mov     byte ptr [bp+10h], 0 ; This is a sentinel value for later
s0:0040
s0:0040 loc_40:                                 ; DATA XREF: seg000:014Fr
s0:0040                 mov     ah, 41h ; 'A'
s0:0042                 mov     bx, 55AAh
s0:0045                 int     13h             ; DISK - Installation Check
s0:0045                                         ;   CF set on error
s0:0045                                         ;   CF cleared on success
s0:0045                                         ;   BX = AA55 if installed
s0:0045                                         ;   AH = major version of extensions
s0:0045                                         ;   CX = API subset
s0:0045                                         ;   DH = Extension version
s0:0047                 pop     bp
s0:0048                 jb      short AttemptLoadFromDisk ; Jump if Below (CF=1)
s0:004A                 cmp     bx, 0AA55h      ; DATA XREF: seg000:0045r
s0:004A                                         ; seg000:007Er ...
s0:004A                                         ; Compare Two Operands
s0:004E                 jnz     short AttemptLoadFromDisk ; Jump if Not Zero (ZF=0)
s0:0050                 test    cx, 1           ; Logical Compare
s0:0054                 jz      short AttemptLoadFromDisk ; Jump if Zero (ZF=1)
s0:0056                 inc     byte ptr [bp+10h] ; This acts like a sentinel value
s0:0056                                         ;    for whether or not the INT 13
s0:0056                                         ;    extended read is installed
s0:0059
</pre>
<p>First part of this block does is moves the DL register into where the entry&#8217;s status byte used to be. I wasn&#8217;t really too sure what was going on here for a long time, since if it overwrites the partition record, won&#8217;t it not boot correctly next time? Well, it turns out that the first hard drive is represented by 80h, so most of the time, things will be fine. I don&#8217;t have 2 hard drives, so I&#8217;m not sure what would happen if you had two hard drives and had your bootable entry on the second hard drive. I suspect that the 2nd hard drive would just have its own MBR and would run that instead. Running code on 1 hard drive and loading data from another hard drive seems a little bit silly anyways, so I&#8217;m pretty sure that&#8217;s whats going on. If you know more, please leave a comment!</p>
<p>Next, the code saves the partition record to the stack and moves the values 5 and 0 into the status byte. The 5 indicates the number of attempts that will be made to read from disk later. Multiple attempts will be made because the disk read might fail while the disk spins up. The 0 value is a sentinel value for whether or not the BIOS supports the extended interrupt 13h feature. This is an advanced, easier way to load lots of data from disk into memory, but not all BIOSs support it. The code above runs several different checks and if they all succeed, it stores a 1 where it had just stored a 0, indicating the extended read feature is supported. If any of those checks fails, it just jumps down a few lines and continues executing and will use the older method.</p>
<p>The next section of code loads the first sector of the OS into memory, using a different method depending on whether or not the extended read is supported. Here it is:</p>
<pre>
s0:0059 AttemptLoadFromDisk:                    ; CODE XREF: seg000:0048j
s0:0059                                         ; seg000:004Ej ...
s0:0059                 pushad                  ; Save all our registers for a little bit
s0:005B                 cmp     byte ptr [bp+10h], 0 ; Did our sentinel value get changed?
s0:005F                 jz      short InstallationFailed ; DATA XREF: seg000:0032r
s0:005F                                         ; Jump if Zero (ZF=1)
s0:0061                 push    large 0         ; LBA of 0
s0:0067                 push    large dword ptr [bp+8] ; DATA XREF: seg000:00E5r
s0:0067                                         ; seg000:0125r
s0:0067                                         ; Transfer buffer
s0:0067                                         ;    This is also the LBA of first absolute sector
s0:0067                                         ;    in the MBR partition record
s0:006B                 push    0               ; Transfer buffer
s0:006E                 push    7C00h           ; Number of blocks
s0:006E                                         ;    Note that only the first byte is relevant,
s0:006E                                         ;    and the second is ignored, so we are only
s0:006E                                         ;    reading 7Ch
s0:0071                 push    1               ; Reserved
s0:0074                 push    10h             ; Packet is size 10h
s0:0077                 mov     ah, 42h ; 'B'
s0:0079                 mov     dl, [bp+0]      ; Drive number
s0:007C                 mov     si, sp          ; Point to the address packet we just made
s0:007E                 int     13h             ; DISK - Extended Read
s0:007E                                         ;
s0:007E                                         ;    Reads DS:SI into a disk appress packet
s0:007E                                         ;      a disk address packet is:
s0:007E                                         ;      00 BYTE: Size of packet (10h or 18h)
s0:007E                                         ;      01 BYTE: Reserved
s0:007E                                         ;      02 WORD: Number of blocks to transfer
s0:007E                                         ;      04 DWORD: Transfer buffer
s0:007E                                         ;      08 QWORD: Starting absolute block number (LBA)
s0:007E                                         ;      10 QWORD: 64-bit flat address of transfer buffer (optional, used if the DWORD at 04 is FFFFh:FFFFh)
s0:007E                                         ;
s0:007E                                         ;    CF cleared if successful
s0:007E                                         ;    AH = 0 on success
s0:0080                 lahf                    ; Preserve the flags for a second
s0:0081                 add     sp, 10h         ; Pop the address packet we were using off the stack
s0:0084                 sahf                    ; Store AH into Flags Register
s0:0085                 jmp     short PostDiskReadState ; Jump
s0:0087 ; ---------------------------------------------------------------------------
s0:0087
s0:0087 InstallationFailed:                     ; CODE XREF: seg000:005Fj
s0:0087                 mov     ax, 201h        ; The extended read interrupt is not installed,
s0:0087                                         ;    so use the legacy version
s0:0087                                         ; AH = 2 (Disk read sectors into memory)
s0:0087                                         ; AL = 1 (Read 1 sector)
s0:008A                 mov     bx, 7C00h       ; This is the destination buffer
s0:008D                 mov     dl, [bp+0]      ; Drive number
s0:0090                 mov     dh, [bp+1]      ; These 3 bytes are a CHS structure
s0:0093                 mov     cl, [bp+2]
s0:0096                 mov     ch, [bp+3]
s0:0099                 int     13h             ; DISK - READ SECTORS INTO MEMORY
s0:0099                                         ; AL = number of sectors to read, CH = track, CL = sector
s0:0099                                         ; DH = head, DL = drive, ES:BX -> buffer to fill
s0:0099                                         ; Return: CF set on error, AH = status, AL = number of sectors read
</pre>
<p>Right away, a comparison is done against the sentinel value. If it is 0 (indicating no extended read), a jump is taken to the InstallationFailed label. If the extended read is supported, an &#8220;address packet&#8221; is set up for the interrupt and then the int 13h call is made, performing the read. This was actually a pretty tricky section to figure out, mostly because I found all the documentation about address packets was pretty confusing. After the extended read is completed, the code jumps to the PostDiskReadState location. I expect there are a few errors in my comments about the address packet, which I might try to figure out more about later.</p>
<p>Both the extended read and the non-extended read code do essentially the same thing though. They load the first sector of the bootable partition into memory at 0000h:7C00h. This will most likely be the operating system&#8217;s loader which will get things started up properly. Before we jump to the OS though, first we have a little bit of maintenance to do, to make sure we are set up and good to go.</p>
<p>After the disk reads are done, we need to make sure that everything succeeded, which is what this block of code does:</p>
<pre>
s0:009B PostDiskReadState:                      ; CODE XREF: seg000:0085j
s0:009B                 popad                   ; Restore all our registers
s0:009D                 jnb     short DiskReadSuccess ; Jump if CF = 0
s0:009D                                         ;    i.e. The interrupt we just executed (either one)
s0:009D                                         ;    just succeeded.
s0:009F                 dec     byte ptr [bp+11h] ; Remember this was set to 5 before?
s0:009F                                         ;    This is looping and trying the disk several times,
s0:009F                                         ;    (it might have failed while the disk spun up)
s0:00A2                 jnz     short ReattemptDiskRead ; Jump if Not Zero (ZF=0)
s0:00A4                 cmp     byte ptr [bp+0], 80h ; 'Ç' ; Is this drive letter 80h, i.e. the
s0:00A4                                                    ; first hard drive?
s0:00A8                 jz      PrintErrorLoadingOperatingSystem ; Jump if Zero (ZF=1)
s0:00AC                 mov     dl, 80h ; 'Ç'   ; Re-try on the first hard drive
s0:00AE                 jmp     short FoundBootableEntry ; Jump
s0:00B0 ; ---------------------------------------------------------------------------
s0:00B0
s0:00B0 ReattemptDiskRead:                      ; CODE XREF: seg000:00A2j
s0:00B0                 push    bp
s0:00B1                 xor     ah, ah          ; Logical Exclusive OR
s0:00B3                 mov     dl, [bp+0]
s0:00B6                 int     13h             ; DISK - RESET DISK SYSTEM
s0:00B6                                         ; DL = drive (if bit 7 is set both hard disks and
s0:00B6                                         ;   floppy disks reset)
s0:00B6                                         ;
s0:00B6                                         ; This is important so we can try the read again
s0:00B8                 pop     bp
s0:00B9                 jmp     short AttemptLoadFromDisk ; Jump
</pre>
<p>For both style of disk reads, if the operation succeeded, the carry flag will be cleared. As such, there is a JNB instruction that is taken if the load succeeded and jumps to the DiskReadSuccess location. If not, the counter we previously set to 5 is decremented. Remember how I talked about that the disk read might fail sometimes? This code is taking into account the drive being busy, not being spun up, or any other reason by just re-trying a few times. If however, it has failed after the 5 attempts, something is wrong. A comparison is then made to see if we are on the first hard drive by comparing the drive letter we wrote to [BP+0] with 80h. If it is, there is a problem loading the OS, so we print an error message. If not, we change the DL register to 80h, indicating the first hard drive, and try the whole process again.</p>
<p>The ReattemptDiskRead code is pretty straightforward. All it does is resets the disk system and jumps back to the AttemptLoadFromDisk location. Pretty simple, huh?</p>
<p>Hopefully the disk read will succeed though, and the code will get to the DiskReadSuccess location. We are very close to actually jumping to the OS in that case. Here is the code:</p>
<pre>
s0:00BB DiskReadSuccess:                        ; CODE XREF: seg000:009Dj
s0:00BB                 cmp     word ptr ds:7DFEh, 0AA55h ; We just loaded new code to 7C00h. Check
s0:00BB                                         ;    to see if it has the bootable signature AA55.
s0:00BB                                         ;    This signature indicates a VBR, which indicates
s0:00BB                                         ;    an operating system
s0:00C1                 jnz     short PrintMissingOperatingSystem ; The last two bytes are NOT AA55h
s0:00C1                                                           ; so there is no OS.
s0:00C1                                         ;    Print an error message.
s0:00C3                 push    word ptr [bp+0]
s0:00C6                 call    CheckKeyboardSystemFlag ; Call Procedure
s0:00C9                 jnz     short CheckForTPM ; Jump if Not Zero (ZF=0)
s0:00CB                 cli                     ; Disable interrupts for a while
s0:00CC                 mov     al, 0D1h ; '-'
s0:00CE                 out     64h, al         ; AT Keyboard controller 8042.
s0:00CE                                         ;    Enables writing the output port
s0:00D0                 call    CheckKeyboardSystemFlag ; Call Procedure
s0:00D3                 mov     al, 0DFh ; '¯'
s0:00D5                 out     60h, al         ; AT Keyboard controller 8042.
s0:00D5                                         ;    Enables writing to the status register
s0:00D7                 call    CheckKeyboardSystemFlag ; Call Procedure
s0:00DA                 mov     al, 0FFh        ; Enable A20 memory line
s0:00DC                 out     64h, al         ; AT Keyboard controller 8042.
s0:00DC                                         ; Reset the keyboard and start internal diagnostics
s0:00DE                 call    CheckKeyboardSystemFlag ; Call Procedure
s0:00E1                 sti                     ; Enable interrupts
s0:0156 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
s0:0156
s0:0156
s0:0156 CheckKeyboardSystemFlag proc near       ; CODE XREF: seg000:00C6p
s0:0156                                         ; seg000:00D0p ...
s0:0156                 sub     cx, cx          ; CX = 0
s0:0158
s0:0158 CheckByte2:                             ; CODE XREF: CheckKeyboardSystemFlag+8j
s0:0158                 in      al, 64h         ; AT Keyboard controller 8042.
s0:015A                 jmp     short $+2       ; Jump
s0:015C                 and     al, 2           ; Logical AND
s0:015E                 loopne  CheckByte2      ; Loop while rCX != 0 and ZF=0
s0:0160                 and     al, 2           ; Logical AND
s0:0162                 retn                    ; Return Near from Procedure
s0:0162 CheckKeyboardSystemFlag endp
</pre>
<p>This code first checks to see that we did, in fact load an OS and not just some garbage into memory by checking for the AA55h signature. If it is not there, we print an error message. Otherwise, we&#8217;re going to fiddle with the keyboard controller a bit. This code makes several calls to the CheckKeyboardSystemFlag function, which basically loops until the keyboard controller is ready to talk to to the CPU. I&#8217;m a little fuzzy on what the output to the ports is doing, but I&#8217;m pretty sure that it is enabling the <a href="http://en.wikipedia.org/wiki/A20_line">A20 address line</a>, which enables larger amounts of memory to be used. It&#8217;s a pretty common task and there are write-ups all over the Internet, so I won&#8217;t go into it.</p>
<p>After the MBR is done fiddling with the keyboard controller, it decides to check for a <a href="http://en.wikipedia.org/wiki/Trusted_Platform_Module">Trusted Platform Module</a>. The TPM is used to do several security related things, such as for Windows BitLocker encryption. There is a lot of complex documentation, so after I figured out that this was TPM code, I decided not to investigate it further. It is listed below:</p>
<pre>
s0:00E2 CheckForTPM:                            ; CODE XREF: seg000:00C9j
s0:00E2                 mov     ax, 0BB00h
s0:00E5                 int     1Ah
s0:00E7                 and     eax, eax        ; Logical AND
s0:00EA                 jnz     short JumpToLoadedMemory ; Jump if Not Zero (ZF=0)
s0:00EC                 cmp     ebx, 41504354h  ; Compare Two Operands
s0:00F3                 jnz     short JumpToLoadedMemory ; Jump if Not Zero (ZF=0)
s0:00F5                 cmp     cx, 102h        ; Compare Two Operands
s0:00F9                 jb      short JumpToLoadedMemory ; Jump if Below (CF=1)
s0:00FB                 push    large 0BB07h
s0:0101                 push    large 200h
s0:0107                 push    large 8
s0:010D                 push    ebx
s0:010F                 push    ebx
s0:0111                 push    ebp
s0:0113                 push    large 0
s0:0119                 push    large 7C00h
s0:011F                 popad                   ; Pop all General Registers (use32)
s0:0121                 push    0
s0:0124                 pop     es
s0:0125                 int     1Ah             ; This makes a call to the TPM
</pre>
<p>The code first checks for the presence of a TPM module. If it is not there, it jumps to the JumpToLoadedMemory location, otherwise it makes a call to the TPM.</p>
<p>Well, ladies and gentlement, thanks for sticking with me. After all that, we are finally ready to jump to the operating system that we loaded into memory. It&#8217;s very simple, so without further adieu:</p>
<pre>
s0:0127 JumpToLoadedMemory:                     ; CODE XREF: seg000:00EAj
s0:0127                                         ; seg000:00F3j ...
s0:0127                 pop     dx
s0:0128                 xor     dh, dh          ; Logical Exclusive OR
s0:012A                 jmp     far ptr 0:7C00h ; Jump to the code we have loaded
</pre>
<p>That&#8217;s it?! Yup, that&#8217;s it. Anti-climactic, though I guess Master Boot Records aren&#8217;t supposed to be entertaining.</p>
<p>There is some more code that I didn&#8217;t talk about yet, because it has to do with printing the error messages out. I&#8217;m not going to explain it here, since I&#8217;m already over 3000 words and I&#8217;m sure you&#8217;re sick of reading. Here it is:</p>
<pre>
s0:0131 PrintMissingOperatingSystem:            ; CODE XREF: seg000:00C1j
s0:0131                 mov     al, ds:7B7h
s0:0134                 jmp     short DisplayErrorMessage ; Jump
s0:0136 ; ---------------------------------------------------------------------------
s0:0136
s0:0136 PrintErrorLoadingOperatingSystem:       ; CODE XREF: seg000:00A8j
s0:0136                 mov     al, ds:7B6h
s0:0139                 jmp     short DisplayErrorMessage ; Jump
s0:013B ; ---------------------------------------------------------------------------
s0:013B
s0:013B PrintInvalidPartitionTable:             ; CODE XREF: seg000:0029j
s0:013B                 mov     al, ds:7B5h
s0:013E
s0:013E DisplayErrorMessage:                    ; CODE XREF: seg000:0134j
s0:013E                                         ; seg000:0139j
s0:013E                 xor     ah, ah          ; Clear out the high byte of the AX register.
s0:0140                 add     ax, 700h        ; We now point to 700h + whatever offset we were given
s0:0140                                         ;    above.
s0:0143                 mov     si, ax
s0:0145
s0:0145 PrintErrorStringLoop:                   ; CODE XREF: seg000:0151j
s0:0145                 lodsb                   ; Load byte at DS:SI into AL
s0:0146                 cmp     al, 0           ; Is the next byte 0? We're looking at a 0 terminated
s0:0146                                         ;     string, so this is important.
s0:0148                 jz      short HaltSystem ; Jump if Zero (ZF=1)
s0:014A                 mov     bx, 7
s0:014D                 mov     ah, 0Eh
s0:014F                 int     10h             ; - VIDEO - WRITE CHARACTER AND ADVANCE CURSOR (TTY WRITE)
s0:014F                                         ; AL = character, BH = display page (alpha modes)
s0:014F                                         ; BL = foreground color (graphics modes)
s0:0151                 jmp     short PrintErrorStringLoop ; Jump
s0:0153 ; ---------------------------------------------------------------------------
s0:0153
s0:0153 HaltSystem:                             ; CODE XREF: seg000:0148j
s0:0153                                         ; seg000:0154j
s0:0153                 hlt                     ; This stops the computer.
s0:0154                 jmp     short HaltSystem ; Jump
s0:0156
s0:0162 ; ---------------------------------------------------------------------------
s0:0163 aInvalidPartiti db 'Invalid partition table',0
s0:017B aErrorLoadingOp db 'Error loading operating system',0
s0:019A aMissingOperati db 'Missing operating system',0
s0:01B3                 db    0
s0:01B4                 db    0
s0:01B5                 db  63h ; c             ; Redirect to the error message at 63h,
s0:01B5                                         ;    i.e. "Invalid Partition Table"
s0:01B6                 db  7Bh ; {             ; Redirect to the error message at 7Bh,
s0:01B6                                         ;    i.e. "Error loading operating system"
s0:01B7                 db  9Ah ; Ü             ; Redirect to the error message at 9Ah,
s0:01B7                                         ;    i.e. "Missing operating system"
</pre>
<p>I realize that a blog post is a pretty difficult way to explain an RE task like this well. As such, I&#8217;m going to make my IDA Pro database available for download <a href="http://samuelkerr.com/wp-content/uploads/2010/07/MBR.idb">here</a>. If you don&#8217;t have IDA, there is a free version (which I use) available <a href="http://www.hex-rays.com/idapro/idadownfreeware.htm">here</a>. It is missing quite a few features, but the price is right, and for work like this (16-bit MBR code), a lot of the newer features aren&#8217;t even relevant.</p>
<p>If you&#8217;re interested, you could do this analysis on your own computer. Depending on your computer&#8217;s manufacturer, you might have some small differences, but those are what makes it fun, right? To get started, get the <a href="http://www.bpsoft.com/downloads/">trial</a> of Hex Workshop, extract the MBR (it&#8217;s the first sector on the disk), then use the free version of IDA Pro to examine it. Happy hunting!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=262</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PEAR, my first publication!</title>
		<link>http://samuelkerr.com/?p=256</link>
		<comments>http://samuelkerr.com/?p=256#comments</comments>
		<pubDate>Wed, 30 Jun 2010 01:15:07 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[General Computing]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=256</guid>
		<description><![CDATA[During my time at school, I participate in research. I have been doing this since freshman year, and have been co-author on a few papers, but have never been lead author. Well, that is now changing. Yesterday, I submitted a &#8230; <a href="http://samuelkerr.com/?p=256">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://samuelkerr.com/wp-content/uploads/2010/06/The_Biting_Pear_of_Salamanca_by_ursulav.jpg"><img class="alignright size-medium wp-image-257" title="The_Biting_Pear_of_Salamanca_by_ursulav" src="http://samuelkerr.com/wp-content/uploads/2010/06/The_Biting_Pear_of_Salamanca_by_ursulav-225x300.jpg" alt="" width="225" height="300" /></a>During my time at school, I participate in research. I have been doing this since freshman year, and have been co-author on a few papers, but have never been lead author. Well, that is now changing.</p>
<p><span id="more-256"></span></p>
<p>Yesterday, I submitted a paper to the 2010 ACM DIM (Digital Identity Management) workshop. My paper was  about a project I have been working on the last semester. I used several different things in my projects, some of which I have written about before. Rather than try to explain the project now, I will show you the abstract. I&#8217;ll post the full paper once it is either officially accepted or rejected.</p>
<blockquote>
<p style="text-align: center;"><span style="font-style: normal;">PEAR: A Hardware Based Protocol Authentication System</span></p>
<p style="text-align: center;">
<div id="_mcePaste" style="text-align: center;">
<div id="_mcePaste" style="text-align: center;"><span style="font-style: normal;">Abstract</span></div>
<div id="_mcePaste" style="text-align: center;">As users have to manage an increasing number of ac-</div>
<div id="_mcePaste" style="text-align: center;">counts, they have to balance password security and pass-</div>
<div id="_mcePaste" style="text-align: center;">word usability. As such, many users use insecure pass-</div>
<div id="_mcePaste" style="text-align: center;">words resulting in their accounts and data being vulnerable</div>
<div id="_mcePaste" style="text-align: center;">to unauthorized accesses. In this paper, we present Phys-</div>
<div id="_mcePaste" style="text-align: center;">ically Enhanced Authentication Ring, or PEAR, a system</div>
<div id="_mcePaste" style="text-align: center;">that alleviates this problem. We leverage Physically Un-</div>
<div id="_mcePaste" style="text-align: center;">clonable Functions (PUF) to create unclonable hardware</div>
<div id="_mcePaste" style="text-align: center;">devices, which users use to authenticate. Using a hardware</div>
<div id="_mcePaste" style="text-align: center;">device, our system uses zero-knowledge proofs, which pro-</div>
<div id="_mcePaste" style="text-align: center;">vide better security than traditional passwords, yet users</div>
<div id="_mcePaste" style="text-align: center;">must only enter a simple PIN. As such, our system is very</div>
<div id="_mcePaste" style="text-align: center;">usable and imposes little to no burden on end users and</div>
<div id="_mcePaste" style="text-align: center;">service providers. We present transaction levels on top of</div>
<div id="_mcePaste" style="text-align: center;">PEAR of as an extension and then discuss some other work</div>
<div id="_mcePaste" style="text-align: center;">that could be done in the future.</div>
</div>
<p style="text-align: center;">
</blockquote>
<div style="text-align: left;">I got a ton of help and feedback from the other authors of the paper, <a href="http://www.cs.purdue.edu/homes/mkirkpat/" target="_blank">Michael Kirkpatrick</a> and <a href="http://homes.cerias.purdue.edu/~bertino/" target="_blank">Elisa Bertino</a>, which I greatly appreciate. We used the name PEAR since it provides a lot of opportunities for cool logos and graphics.</div>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=256</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>One architecture to rule them all&#8230; Or at least rule my free time</title>
		<link>http://samuelkerr.com/?p=243</link>
		<comments>http://samuelkerr.com/?p=243#comments</comments>
		<pubDate>Fri, 22 Jan 2010 20:08:33 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=243</guid>
		<description><![CDATA[I&#8217;m a pretty lazy person. I like to put things off, drag my feet, and make plans that I know will never come true. Perfect example, Fall 2008 I took a digital systems course where we designed a very basic &#8230; <a href="http://samuelkerr.com/?p=243">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a pretty lazy person. I like to put things off, drag my feet, and make plans that I know will never come true. Perfect example, Fall 2008 I took a digital systems course where we designed a very basic (2-bit) CPU and I decided I wanted to continue working out of class to make a better one. Initially, I was actually making some progress, but quickly outgrew the basic chips (<a href="http://en.wikipedia.org/wiki/Generic_array_logic" target="_blank">GAL</a> chips) we were using at the time, so I screeched to a stop. After a few months of poking around, I figured out an <a href="http://en.wikipedia.org/wiki/Field-programmable_gate_array" target="_blank">FPGA </a>might be a better way to go. However, these are expensive and would take a lot of effort to learn, so I put the idea on the back-burner.</p>
<div id="attachment_244" class="wp-caption alignleft" style="width: 310px"><a href="http://samuelkerr.com/wp-content/uploads/2010/01/magic1.jpg"><img class="size-medium wp-image-244" title="magic1" src="http://samuelkerr.com/wp-content/uploads/2010/01/magic1-300x225.jpg" alt="Magic 1" width="300" height="225" /></a><p class="wp-caption-text">Bill Buzbee&#39;s homemade CPU, which provided some inspiration for me.</p></div>
<p>Luckily for me though, my research group started to do some work with FPGA&#8217;s, so I was able to get some <a href="http://samuelkerr.com/?p=207" target="_blank">hands on</a> <a href="http://samuelkerr.com/?p=216" target="_blank">experience </a>with them. Despite having the needed tools though, I was still dragging my feet on doing any work. Well, a few days ago, I got re-inspired when I found a website about a guy called <a href="http://www.homebrewcpu.com/" target="_blank">Bill Buzbee</a> who built his own (and in my opinion) pretty complex CPU. It has all sorts of neat features such as paging and interrupts. Well, that was the inspiration I needed and now, a few days later, I&#8217;ve actually got some progress worth mentioning.</p>
<p><span id="more-243"></span></p>
<p>I&#8217;ve tried designing a CPU several times before, either on paper or just trying to hack out some Verilog code to no avail. I think the main problem is that I haven&#8217;t had any clear direction or plan. Because of this, I decided to make a high-level block diagram of the architecture on the computer before I wrote any code. So far, this seems to pretty helpful, as I&#8217;ve had several *doh* moments already where I found an error in my design. Doing it on computer (hurray for <a href="http://office.microsoft.com/en-us/visio/default.aspx" target="_blank">Visio</a>!) makes it a lot easier than working with pencil and paper too.</p>
<p>As I started my design, I tried to copy what I already knew a little about. In a computer architecture class I took, we had studied the <a href="http://en.wikipedia.org/wiki/MIPS_architecture" target="_blank">MIPS</a> architecture, so I tried to copy their style of pipelining, though I in no way claim my sketches were anything close to a MIPS design. I quickly figured out pipelining would be pretty difficult for me at this point, so I dropped that idea for now.</p>
<p>After I had revised my drawing a little, I noticed that the memory was being referenced in two separate places in the CPU (see diagram). So this meant that I could do one of two things:</p>
<ul>
<li>Revise the whole design to only reference memory in one place, retaining the <a href="http://en.wikipedia.org/wiki/Von_Neumann_architecture" target="_blank">Von Neumann</a> structure.</li>
<li>Use two separate memory modules, giving me a <a href="http://en.wikipedia.org/wiki/Harvard_architecture" target="_blank">Harvard</a> architecture.</li>
</ul>
<p>I thought it might be fun to try something new (and also not redo the drawing again), so I decided to go with the Harvard style and split the data and instruction memory into separate chips. I might regret this later, but we&#8217;ll see how it goes for now.</p>
<div id="attachment_246" class="wp-caption alignright" style="width: 291px"><a href="http://samuelkerr.com/wp-content/uploads/2010/01/CPUdiagram.gif"><img class="size-medium wp-image-246" title="CPUdiagram" src="http://samuelkerr.com/wp-content/uploads/2010/01/CPUdiagram-281x300.gif" alt="My CPU design" width="281" height="300" /></a><p class="wp-caption-text">Here is the initial plan for the CPU. The red parts will be external memory chips. The whole second ALU business may or may not be implemented in the first go-around.</p></div>
<p>Lots of designs are using parallelism today, so of course I didn&#8217;t want to be left out. As such, I&#8217;m going to try to add a second <a href="http://en.wikipedia.org/wiki/Arithmetic_logic_unit" target="_blank">ALU</a> into my design. This would allow me to do two computations at once. This will probably also make the design a lot more difficult to complete as well. I&#8217;m going to add a few restrictions to this second ALU so that it will be easier to work with though, such as it will only operate on certain source and destination registers, unlike the first ALU, which should be able to use most any register available. If this part gets too difficult to deal with, I might drop it, but I am going to try to get it to work.</p>
<p>I haven&#8217;t yet decided whether I want to use 8/16/32 bits for addresses and data sizes, how many I/O ports to have, nor exactly how many registers the chip is going to have, but I don&#8217;t think that is really important yet. Right now, my layout is such that these choices don&#8217;t really matter yet. These issues shouldn&#8217;t really become an issue until after the instruction set is designed. One major problem I do see coming up is the implementation of the bi-directional buses on the FPGA. What I mean is that I will need <a href="http://en.wikipedia.org/wiki/Three-state_logic" target="_blank">tri-state outputs</a> for the bus, but the FPGA can&#8217;t synthesize these internally. It can however, do tri-state outputs on the physical I/O pins. What this means is that I will have to physically wire the bus to various I/O pins on the FPGA, which will be a headache. If you know of an FPGA that can do tri-state logic internally, please leave me a comment!</p>
<p>At this point I have started to write some basic code for the chip. Specifically, I&#8217;m working on designing the registers and I/O port modules in Verilog. These seem pretty simple, but I&#8217;m making a big effort to actually write tests and make sure that they work properly. Hopefully this attempt will pan out better than my previous efforts!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=243</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ever want to build your own computer?</title>
		<link>http://samuelkerr.com/?p=238</link>
		<comments>http://samuelkerr.com/?p=238#comments</comments>
		<pubDate>Sun, 10 Jan 2010 05:20:27 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[FPGA]]></category>
		<category><![CDATA[Science]]></category>
		<category><![CDATA[electronics]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=238</guid>
		<description><![CDATA[I find hardware and electronics pretty interesting. So when I was looking around on the internet and saw a link to a home built CPU, I just had to click! A fellow named Jim has made a complete CPU, called &#8230; <a href="http://samuelkerr.com/?p=238">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I find <a href="http://samuelkerr.com/?p=207" target="_blank">hardware</a> and <a href="http://samuelkerr.com/?p=228" target="_blank">electronics</a> pretty interesting. So when I was looking around on the internet and saw a link to a <a href="http://www.homebrewcpu.com" target="_blank">home built CPU</a>, I just had to click! A fellow named Jim has made a complete CPU, called the Magic-1, out of just 74xx series of circuits. If you haven&#8217;t used or know what 74xx series circuits are, take a look at the picture. These chips were very popular back in the day, as in, a few decades ago. Today there are faster and more powerful chips available. But because Jim used the 74xx series of chips, he was able to get much more control and learn a lot about CPU design.</p>
<div id="attachment_239" class="wp-caption alignright" style="width: 198px"><a href="http://samuelkerr.com/wp-content/uploads/2010/01/74XX.jpg"><img class="size-full wp-image-239" title="74XX" src="http://samuelkerr.com/wp-content/uploads/2010/01/74XX.jpg" alt="" width="188" height="188" /></a><p class="wp-caption-text">These chips can make a whole CPU?!</p></div>
<p><span id="more-238"></span>I personally found Jim&#8217;s work so interesting because I have been toying around with designing a somewhat useful CPU myself, since I took a class on digital design. In that class, we built a simple computer that had 1 register, 4 bit (not byte) address and data bus, and only 7 instructions. It was an interesting exercise and very educational, but it couldn&#8217;t really do anything other than add small numbers together. I have made a few attempts at starting a design, but I usually got hung up on finding a balance between instruction set power, complexity, and size. It would be nice to be able to perform 32 bit vector math with all arguments in the instruction, but thats just not realistic for me at this point.</p>
<p>Seeing Jim&#8217;s work is pretty inspirational; maybe this semester I&#8217;ll get off my butt and start to work on my own computer. However, I don&#8217;t think I will use 74xx chips. <a href="http://en.wikipedia.org/wiki/Field-programmable_gate_array" target="_blank">FPGAs</a> are very powerful tools, and since I&#8217;ve been using them for my research, I figure they will be the perfect way to start any work. I think the biggest thing is to just get started and stop thinking about starting.</p>
<p>P.S. Another interesting point of note is that <a href="http://www.epemag.com/zuse/" target="_blank">Konrad Zuse</a>, a German engineer, had built his own computer during World War 2, but instead of an electric clock, he used a crank as the clock! Pretty neat!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=238</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Websites, Propellers, and Sweet Music!</title>
		<link>http://samuelkerr.com/?p=228</link>
		<comments>http://samuelkerr.com/?p=228#comments</comments>
		<pubDate>Sun, 03 Jan 2010 04:28:13 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Science]]></category>
		<category><![CDATA[microcontroller]]></category>
		<category><![CDATA[parallax]]></category>
		<category><![CDATA[propeller]]></category>

		<guid isPermaLink="false">http://samuelkerr.com/?p=228</guid>
		<description><![CDATA[Well, I&#8217;m sure that you&#8217;ve noticed the new layout and domain name for my blog. Over winter break, I decided it was silly to have both a blog site and a school website. So, I purchased this domain (www.samkerr.com was &#8230; <a href="http://samuelkerr.com/?p=228">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Well, I&#8217;m sure that you&#8217;ve noticed the new layout and domain name for my blog. Over winter break, I decided it was silly to have both a blog site and a school website. So, I purchased this domain (<a href="http://www.samkerr.com">www.samkerr.com</a> was taken) and am now going to host both sites here. My web host, <a href="http://refer.asmallorange.com/25081 " target="_blank">A Small Orange</a>, has a really good deal on a years worth of hosting for only $25, so Idecided to go with that. So far, it&#8217;s <a href="http://samuelkerr.com/?p=108" target="_blank">performing much better than my old site</a>. If you&#8217;re in the market for a new web host, I&#8217;d appreciate you signing up through the previous link, since I get a referral bonus.</p>
<div id="attachment_230" class="wp-caption alignleft" style="width: 225px"><a href="http://samuelkerr.com/wp-content/uploads/2010/01/img217442.jpg"><img class="size-full wp-image-230" title="Propeller Logo" src="http://samuelkerr.com/wp-content/uploads/2010/01/img217442.jpg" alt="Parallax Propeller Logo" width="215" height="173" /></a><p class="wp-caption-text">Propeller Time!</p></div>
<p>Anyways, at Christmas, I got a starter set for the <a href="http://www.parallax.com/tabid/407/Default.aspx" target="_blank">Parallax Propeller microcontroller</a>, an 8 core, 32-bit microcontroller. I really like to work with hardware and embedded type stuff, so I was really excited about this. I&#8217;ve played with AVR chips before, but this chip has a lot more power built-in, but it won&#8217;t require as much work as using an <a href="http://samuelkerr.com/?p=207" target="_blank">FPGA</a> either.</p>
<p><span id="more-228"></span></p>
<p>Due to the nature of the Propeller, it can perform some really complex tasks. Since it&#8217;s 32 bits, it can easily handle some tasks, such as floating point division, that would be more difficult on other architectures. Not only that, but it has 8 &#8216;cores&#8217;! Each core, or &#8217;cog,&#8217; can run up to 80 MHz, has its own <a href="http://en.wikipedia.org/wiki/Arithmetic_logic_unit" target="_blank">ALU </a>(Arithmetic Logic Unit), counters, frequency, and video generators. In addition, each one can control every I/O pin. There is clearly a lot of power available here, but what would be a good starting point? Music of course!</p>
<p>I read an article a few weeks ago about music notes and their frequencies, and since each cog can generate a unique frequency, I thought it would be fun to make some music. I have a small speaker, so this would be a doable project. Since I&#8217;m just starting out, I decided to keep the design relatively simple. Here are a few things I decided I wanted to do:</p>
<ul>
<li>Be able to generate any note.</li>
<li>Be able to use any I/O pin.</li>
<li>Be able to play a chromatic scale (all notes, sharps, and flats on the scale).</li>
<li>Be able to play a note for a specified time.</li>
<li>Be able to play across multiple octaves.</li>
</ul>
<p>I also decided to make some concessions, at least for now:</p>
<ul>
<li>No chord support initially.</li>
<li>All multi-cog management must be handled by the user.</li>
<li>Only quarter notes, eighth notes, sixteenth notes, thirty-second notes, and integer quantities of quarter notes can be played.</li>
<li>A BPM (Beats Per Minute) of 120 (or some other constant) will have to be used.</li>
</ul>
<p>The Propeller chip has to be programmed in its own language, called Spin, so I had to learn that before I could get started. I found it kind of strange, as its syntax is very different from C or Java. It took me a while, but I eventually managed to figure it out a little bit.</p>
<p>The first step was to be able to synthesize a tone. To do this, I would need to generate a specific frequency. To achieve this, I need to calculate how long of a delay to impose between osciallting the output of the I/O pin, i.e. the period. I then need to divide the clock frequency by the period to give me the proper delay. The code for this ends up looking like:</p>
<pre>PUB generateFrequency(Pin, Frequency)
{{
  Given a frequency, specified in Hz,
  output that frequency on the I/O pin Pin.
}}
  DIRA[Pin]~~ ' Set it to output
  repeat      ' Endless loop
    !OUTA[Pin] ' Oscillate the I/O pin
    waitcnt(cnt + CLKFREQ / Frequency) ' Wait for the specified time</pre>
<div id="attachment_234" class="wp-caption alignright" style="width: 235px"><a href="http://samuelkerr.com/wp-content/uploads/2010/01/IMG00021-20100102-23101.jpg"><img class="size-medium wp-image-234" title="Propeller" src="http://samuelkerr.com/wp-content/uploads/2010/01/IMG00021-20100102-23101-225x300.jpg" alt="Propeller Starter Kit" width="225" height="300" /></a><p class="wp-caption-text">Who needs a piano? I have a half-watt speaker and a microcontroller!</p></div>
<p>If you have used the Propeller before, you probably know this section could be re-written to improve performance, using the built-in counters, but I didn&#8217;t really figure those out yet. Maybe I&#8217;ll optimize this later, but it works, so for now it&#8217;s fine.</p>
<p>Now that I can generate an arbitrary frequency, I can play any note I want. However, the code above simply loops endlessly, playing the same note. The next step is to be able to play a note for a specified period of time. This is where the fun will start, since I can use one cog to play the notes and another master cog to manage all the timings.</p>
<p>To achieve this, I need to calculate how long to play the note, get an available cog to start playing the note, wait for the note to play, then stop that cog. Creating a new cog was a little confusing, since I had to provide stack space to the cog, but there are a few examples of how to do this, so I managed to figure it out. Here is what I came up with:</p>
<pre>PUB playNote(Note, Pin, Length) | WaitLength
  {{ playNote:
        Plays a given note for a specified number
        of beats.

        Note: Length must be given in fraction form,
        not decimal form

        Note: This method assumes Length is given
        in terms of beats, not measures, where a
        beat is a quarter note.
  }}
  Cog := cognew(generateFrequency(Pin, Note), @StackSpace) ' Remember which cog was being used
  WaitLength := calculateWait(Length) ' How long do we wait?
  waitcnt(cnt + WaitLength) ' Wait for the note to end
  cogstop(Cog)  ' Stop playing the note</pre>
<p>A problem I see that might arise is if it takes longer to calculate the wait length than the note is supposed to be playing for. I don&#8217;t think this will be a big problem though since the cog is pretty quick and the notes aren&#8217;t really that fast, so for now I think it will be OK.</p>
<p>The biggest difficulty I had was figuring out exactly how long to play the note for. After working on it for a while, I did a little unit elimination to figure it out. Namely, CLK pulses/second * 60 seconds/1 minute * 1 minute / 120 beats * 1 beat = CLK/2 pulses / beat. That will give the length of time for a quarter note. After that, multiply that number by the number of beats to play.</p>
<pre>PUB calculateWait(Length) | BaseLength
  ' A quarter note is one beat long
  if Length == 1/8              ' Thirty-Second Note
    return CLKFREQ * 60 / BPM / 8
  elseif Length == 1/4          ' Sixteenth Note
    return CLKFREQ * 60 / BPM / 4
  elseif Length == 1/2          ' Eight Note
    return CLKFREQ * 60 / BPM / 2
  elseif Length == 1            ' Quarter Note
    return CLKFREQ * 60 / BPM
  elseif Length &gt; 1             ' Multiple Quarter Notes
    return CLKFREQ * 60 / BPM * Length</pre>
<p>I ran into some problems with division, so I put anything shorter than a quarter note into an if statement. Anything longer than a quarter note can be handled normally since its length is greater than one.</p>
<p>Putting those three sections of code together, I can now play a chromatic scale like so:</p>
<pre>CON
  ' Define constants for each note
  ANote = 220
  AShNote = 233
  BNote = 247
  CNote= 261
  CShNote = 277
  DNote = 293
  DshNote = 311
  ENote = 329
  FNote = 349
  FShNote = 367
  GNote = 392
  GShNote = 415
PUB main
  DIRA~~ ' Configure the I/O as output
  ' Play the chromatic scales as eighth notes, finishing with quarter note
  playNote(CNote, 0, 1/2)
  playNote(CShNote, 0, 1/2)
  playNote(DNote, 0, 1/2)
  playNote(DShNote, 0, 1/2)
  playNote(ENote, 0, 1/2)
  playNote(FShNote, 0, 1/2)
  playNote(GNote, 0, 1/2)
  playNote(GShNote, 0, 1/2)
  playNote(ANote * 2, 0, 1/2) ' Multiply the note by 2 to go up an octave
  playNote(AShNote * 2, 0, 1/2)
  playNote(BNote * 2, 0, 1/2)
  playNote(CNote * 2, 0, 1</pre>
<p>This code defines the proper frequencies for each musical note on the scale as constants. Then to switch octaves, I can just multiply or divide the note by a constant to change the octave. Pretty cool huh?</p>
<p>Doing this music program was a lot of fun. I think it has a lot of potential to be improved too. I played around trying to play chords to no avail, but I think that might be because my speaker is so crappy. Ideally, I could write a program to automatically do chords and all the cog management for me. I think the next step will be to program some common songs into the Propeller. I always have been a fan of &#8220;Twinkle, Twinkle,&#8221; so maybe that&#8217;s where I&#8217;ll start&#8230;</p>
<p>Happy new year everyone!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=228</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PUFs are just so cuddly!</title>
		<link>http://samuelkerr.com/?p=216</link>
		<comments>http://samuelkerr.com/?p=216#comments</comments>
		<pubDate>Thu, 10 Dec 2009 14:22:52 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[FPGA]]></category>

		<guid isPermaLink="false">http://samkerr.wordpress.com/?p=216</guid>
		<description><![CDATA[As I wrote a few entries ago, I have been using FPGAs this semester in my research group. Since it&#8217;s the end of the semester and the paper has been submitted, I thought I would talk to you about my &#8230; <a href="http://samuelkerr.com/?p=216">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>As I wrote a <a href="http://samkerr.wordpress.com/2009/09/21/first-steps-with-an-fpga/" target="_blank">few entries </a>ago, I have been using <a href="http://en.wikipedia.org/wiki/Field-programmable_gate_array" target="_blank">FPGAs</a> this semester in my research group. Since it&#8217;s the end of the semester and the paper has been submitted, I thought I would talk to you about my research some. The group that I do research with is mainly concerned with identity management and information security and this project was no exception. Specifically, the project I was working on was using <a href="http://en.wikipedia.org/wiki/Physically_unclonable_function" target="_blank">Physically Unclonable Functions</a>, or PUFs, to identify users. <a href="http://samkerr.files.wordpress.com/2009/12/technology_160_180.jpg"><img class="alignleft size-full wp-image-217" title="technology_160_180" src="http://samkerr.files.wordpress.com/2009/12/technology_160_180.jpg" alt="PUF device" width="160" height="180" /></a></p>
<p><span id="more-216"></span></p>
<p>A PUF is a device that when given a &#8220;challenge,&#8221; will always generate the same &#8220;response.&#8221; In this way, an authority can give a user a challenge and, based on whether or not he produces the correct response, can determine his identity. Generating responses to challenges is also very fast; much faster than systems using exponents and modulus to prove identities through advanced cryptography. These responses are actually hardwired into the PUF device due to the internal circuitry. Since generating a response takes very little computer power and energy, PUFs are a very viable way for low-power and mobile devices to securely identify themselves.</p>
<p>The idea of a PUF might sound interesting, but wouldn&#8217;t it be easy to simply make a copy of a PUF, record several responses, and then impersonate the PUF? A good idea, but PUFs can deal with this easily. You see, Physically <strong><em>Unclonable</em></strong> Functions cannot actually be copied accurately. That is because there is some element of randomness introduced into the PUF so that every PUF gives a different response to the same challenge. The most common way to introduce this randomness is to use manufacturing inconsistencies. For example, you may design the PUF to have 100 nm long wires connecting the internals of the PUF, but if the manufacturing equipment has a tolerance of even 5%, the wire could be 95 nm, 105 nm, or anywhere between those two numbers. Since the tolerance is uncontrollable, two PUFs produced on the same manufacturing line using the same design files will provide very different responses to the same challenges. PUFs are designed to leverage these inconsistencies and amplify them so that even small inconsistencies will cause large differences in the output from all other PUFs.</p>
<p>PUFs are a very cool technology, but as for my first foray into Verilog and FPGA design, they were quite difficult. There are several different designs of PUFs, so first I had to decide which would be the best design to implement. All of them were about the same difficulty, so my group and I decided to implement a <a href="http://www.csl.cornell.edu/~suh/papers/dac07.pdf" target="_blank">ring-oscillator based PUF</a>, as presented by Suh and Devadas of Cornell. At first, it seemed easy enough to implement, but the more I coded and the closer my deadline got, the more difficulty I encountered. Namely, I had big problems with the design software thinking it knew what I wanted and removing large pieces of my code. Normally, it would have been doing me a favor, but in this case I did not want some specific optimizations and it took me forever to notice this was happening. I had some trouble learning and understanding some aspects of Verilog, but this was to be expected, since I hadn&#8217;t ever used it prior to this project.</p>
<p>As of now, the PUF device has been successfully implemented and my team has started to integrate it into the rest of our project. I won&#8217;t go into the rest of the project here, but when the paper is published (or not), I&#8217;ll upload a copy of the final paper, which you can then read for yourself. Or maybe I&#8217;ll give a summary in another post.  We&#8217;ll see I suppose!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=216</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Intel Developer Forum shows off some cool stuff!</title>
		<link>http://samuelkerr.com/?p=210</link>
		<comments>http://samuelkerr.com/?p=210#comments</comments>
		<pubDate>Wed, 23 Sep 2009 00:32:49 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Science]]></category>
		<category><![CDATA[cpu]]></category>
		<category><![CDATA[electronics]]></category>
		<category><![CDATA[hardware]]></category>

		<guid isPermaLink="false">http://samkerr.wordpress.com/?p=210</guid>
		<description><![CDATA[This year, the Intel Developer Forum has some pretty neat stuff to talk about. I&#8217;ve been reading their site today and the article from AnandTech about it. I&#8217;d highly recommend reading the AnandTech article since it has a lot better &#8230; <a href="http://samuelkerr.com/?p=210">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This year, the <a href="http://www.intel.com/idf/" target="_blank">Intel Developer Forum</a> has some pretty neat stuff to talk about. I&#8217;ve been reading their site today and the article from <a href="http://anandtech.com/cpuchipsets/showdoc.aspx?i=3644" target="_blank">AnandTech</a> about it.</p>
<p><img class="alignleft size-medium wp-image-212" title="The move from 4 to 6 cores with Gulftown." src="http://samkerr.files.wordpress.com/2009/09/gulftown1.jpg?w=300" alt="The move from 4 to 6 cores with Gulftown." width="300" height="225" />I&#8217;d highly recommend reading the AnandTech article since it has a lot better description (and pictures) than I could do, but the one thing that I&#8217;m really excited about is the new 32nm Gulftown chips. There supposed to have 6 cores and will come in 2010. Even better, they will drop right into my X58 motherboard after a quick BIOS update. That will save me a lot of money since I won&#8217;t have to buy a new motherboard.</p>
<p>Don&#8217;t get me wrong, I love my quad-core i7 cpu, but 6 cores is better than 4, right?</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=210</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>First steps with an FPGA!</title>
		<link>http://samuelkerr.com/?p=207</link>
		<comments>http://samuelkerr.com/?p=207#comments</comments>
		<pubDate>Tue, 22 Sep 2009 01:32:55 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[FPGA]]></category>
		<category><![CDATA[circuits]]></category>
		<category><![CDATA[electronics]]></category>

		<guid isPermaLink="false">http://samkerr.wordpress.com/?p=207</guid>
		<description><![CDATA[For my research group at Purdue, we&#8217;ve decided we want to do some work with FPGA (or Field Programmable Gate Arrays). These are essentially chips that you can use to program very complex, very fast circuits. They are superior to &#8230; <a href="http://samuelkerr.com/?p=207">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For my research group at Purdue, we&#8217;ve decided we want to do some work with <a href="http://en.wikipedia.org/wiki/Field-programmable_gate_array" target="_blank">FPGA </a>(or Field Programmable Gate Arrays). These are essentially chips that you can use to program very complex, very fast circuits. They are superior to other sorts of chips, such as DIP integrated circuits, because they are smaller, relatively cheap for all the power they have (~$10-$20), fully customizable, and FAST.</p>
<div id="attachment_208" class="wp-caption alignright" style="width: 288px"><img class="size-medium wp-image-208" title="556px-Fpga_xilinx_spartan" src="http://samkerr.files.wordpress.com/2009/09/556px-fpga_xilinx_spartan.jpg?w=278" alt="This is Xilinix Spartan FPGA, the kind I'm using." width="278" height="300" /><p class="wp-caption-text">This is Xilinix Spartan FPGA, the kind I&#39;m using.</p></div>
<p>This was my first foray into FPGAs and it drove me crazy getting my tools all set up properly. I thought I&#8217;d post some thoughts.</p>
<p><span id="more-207"></span>To get started with FPGAs, my research group purchased the <a href="http://www.xilinx.com/products/devkits/HW-SPAR3AN-SK-UNI-G.htm" target="_blank">Xilinx Spartan-3AN Starter Kit</a>. We chose this kit because the board it comes with has all sorts of useful peripherals, such as USB, RS-232, Ethernet, VGA outputs and an LCD character screen. All these extras will really help to speed up development and make learning a lot easier.</p>
<p>Last spring, I had decided I wanted to give FPGAs a try, so I purchased a book called &#8220;<a href="http://www.amazon.com/FPGA-Prototyping-Verilog-Examples-Spartan-3/dp/0470185325" target="_blank">FPGA Prototyping by Verilog Examples</a>&#8220;. This book is actually really helpful now since it uses the exact same chip that my board comes with. It has tons of sample code and examples, and I think it&#8217;s really going to help me learn.</p>
<p>I was really excited when I first got this board, but that&#8217;s always when the problems start don&#8217;t they? Well, firstly, the software that came with the board (an IDE and Xilinx utilities) was version 9.1, but the current version is 11.1. Ok, I&#8217;m sure I won&#8217;t be able to really tell a difference anyways since I&#8217;m just starting out.</p>
<p>The software only runs on Windows XP and RHEL officially. I recently installed Windows 7 and <a href="http://samkerr.wordpress.com/2009/08/29/ive-passed-under-the-linux-arch/" target="_blank">Arch Linux</a> on my computer, so this might cause problems. Well, it did. The software refused to install properly on Windows 7, so I tried it on Linux. The software installed fine on Linux, but I couldn&#8217;t get the drivers to connect tot he chip itself to work. I worked on this problem to no avail for about 10 hours, absolutely drove me crazy! But what good is software if it can&#8217;t talk to the board? Not much. As such, I&#8217;m now using Windows XP on my Mac through Boot Camp. Turns out when they say Windows XP and RHEL only, they really do mean only.</p>
<p>I can program a little Abel, but I&#8217;ve never actually used Verilog before. I&#8217;m pretty excited to learn a new language though, especially an HDL (Hardware Description Language) since it&#8217;s completely different from what I normally work with.</p>
<p>Maybe you&#8217;re asking, what did I do for hello world in a circuit? I did a simple 1 bit comparator! Basically, when 1 of 2 DIP switches is on, an LED is on. If both switches are off, the LED is off. This was actually kind of tricky to do since I had to find the correct pin numbers of the FPGA to communicate with. Luckily, there was a really good starter manual available that mapped all the LEDs to their corresponding pins.</p>
<p>I think starting to work with FPGAs will be a really exciting project and probably teach me a lot along the way. Once my research group moves a little farther along, I&#8217;ll post some updates about how we&#8217;re using the FPGA and how work is progressing.</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=207</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Ciphers, Beaufort, and Bears&#8230; Oh my!</title>
		<link>http://samuelkerr.com/?p=201</link>
		<comments>http://samuelkerr.com/?p=201#comments</comments>
		<pubDate>Thu, 03 Sep 2009 13:39:58 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://samkerr.wordpress.com/?p=201</guid>
		<description><![CDATA[In my cryptography class, we&#8217;re starting to learn about various ciphers, and for a homework assignment, we were tasked with doing some ciphering by hand. I find the task very interesting, but I quickly got tired of coding even a &#8230; <a href="http://samuelkerr.com/?p=201">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my cryptography class, we&#8217;re starting to learn about various <a href="http://en.wikipedia.org/wiki/Cipher" target="_blank">ciphers</a>, and for a homework assignment, we were tasked with doing some ciphering by hand.</p>
<div id="attachment_202" class="wp-caption alignleft" style="width: 310px"><img class="size-medium wp-image-202" title="y205295557144927" src="http://samkerr.files.wordpress.com/2009/09/y205295557144927.jpg?w=300" alt="These rhinos are hot on the trail of some cryptography!" width="300" height="150" /><p class="wp-caption-text">These rhinos are hot on the trail of some cryptography!</p></div>
<p>I find the task very interesting, but I quickly got tired of coding even a 10-letter &#8220;sentence&#8221;. Then I thought to myself, wait, I can program! This specifically seems like something that could quickly be done with a Python script. So I decided to spend a little time typing, and 5 minutes later, no more ciphering by hand! Below are the results for your own amusement!</p>
<p><span id="more-201"></span>For my assignment, we were told to use the <a href="http://en.wikipedia.org/wiki/Beaufort_cipher" target="_blank">Beaufort </a>cipher, which is similar to the <a href="http://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher" target="_blank">Vigenere </a>cipher, both of which are several hundred years old. The Beaufort cipher takes some plaintext M and a key K of length t, and then performs the mathematical operation C[i]=(m[i] + k[i mod t]) mod 26 for each letter i of the plaintext. An interesting fact is that this operation will both encrypt and decrypt, making it a <a href="http://en.wikipedia.org/wiki/Reciprocal_cipher" target="_blank">reciprocal cipher</a>.</p>
<p>Anyways, here is the Python code that I wrote to perform encryption/decryption:</p>
<pre>[code language="python"]

k = [10,4,24]
t = len(k)

def asint(theChar):
    return ord(theChar)-ord('A')

def asletter(theNum):
    return chr(theNum+ord('A'))

def applyBeaufort(plaintext):
    results = []
    for i in range(len(plaintext)):
        results += [asletter((k[i % t] - asint(plaintext[i])) % 26)]
    return results

[/code]</pre>
<p>That code isn&#8217;t bulletproof, obviously, and makes a few assumptions:</p>
<ul>
<li>All text will be entered as a capital letter.</li>
<li>The key will be specified as a list of numbers.</li>
</ul>
<p>These two points aren&#8217;t really that hard to correct, but they&#8217;re the 20% of work that will take 80% to do right. I just wanted to give you a quick sample.</p>
<p>Want to see if it works? Alright, here you go!</p>
<pre>About to encrypt!
Using plaintext: RANTSRAMBLESANDRHINOS
['T', 'E', 'L', 'R', 'M', 'H', 'K', 'S', 'X', 'Z', 'A', 'G', 'K', 'R', 'V', 'T', 'X', 'Q', 'X', 'Q', 'G']
-------
About to decipher!
['R', 'A', 'N', 'T', 'S', 'R', 'A', 'M', 'B', 'L', 'E', 'S', 'A', 'N', 'D', 'R', 'H', 'I', 'N', 'O', 'S']</pre>
<p>That&#8217;s all for now, I hope you enjoyed this little tidbit about the Beaufort cipher and maybe even find the code snippet useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=201</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>I&#039;ve passed under the Linux Arch!</title>
		<link>http://samuelkerr.com/?p=196</link>
		<comments>http://samuelkerr.com/?p=196#comments</comments>
		<pubDate>Sun, 30 Aug 2009 03:54:02 +0000</pubDate>
		<dc:creator>samkerr</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[arch linux]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://samkerr.wordpress.com/?p=196</guid>
		<description><![CDATA[Last time, I wrote about how I was working on installing Linux on my computer. The main question with any Linux install though is, what distro do I use? I&#8217;ve used many different distros before, such as the popular Ubuntu, &#8230; <a href="http://samuelkerr.com/?p=196">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://samkerr.wordpress.com/2009/08/26/back-to-school/" target="_blank">Last time,</a> I wrote about how I was working on installing Linux on my computer. The main question with any Linux install though is, what <a href="http://www.zegeniestudios.net/ldc/" target="_blank">distro do I use</a>? I&#8217;ve used many different distros before, such as the popular <a href="http://www.ubuntu.com" target="_blank">Ubuntu</a>, <a href="http://www.slackware.com/" target="_blank">Slackware</a>, and more recently, <a href="http://www.linuxmint.com/" target="_blank">Mint</a> and <a href="http://fedoraproject.org/" target="_blank">Fedora</a>. I even tried to tackle (somewhat succeeded) <a href="http://www.linuxfromscratch.org/" target="_blank">Linux From Scratch</a>. Each distro has its strengths, but for some reason, I was never happy with any of them. One didn&#8217;t give me enough control over my system and did everything for me, while others *cough* <strong>LFS</strong> *cough* provided me with next to no help, leaving me in over my head.</p>
<div id="attachment_199" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-199" title="ArchLinuxLogo-400x400-400x400" src="http://samkerr.files.wordpress.com/2009/08/archlinuxlogo-400x400-400x4002.jpg?w=300" alt="My new distro of choice" width="300" height="300" /><p class="wp-caption-text">My new distro of choice</p></div>
<p>Well, that&#8217;s when I discovered the wonderful <a href="http://www.archlinux.org/" target="_blank">Arch Linux</a>. I don&#8217;t plan on looking back.</p>
<p><span id="more-196"></span>What really turned me on to Arch Linux at first was its mission statement, aka <em>The Arch Way</em>.</p>
<blockquote><p>Arch Linux defines simplicity as a lightweight <code>UNIX</code>-like base structure without unnecessary additions, modifications, or complications, that allows an individual user to shape the system according to their own needs. In short; an elegant, minimalist approach.</p></blockquote>
<p>I was still a little skeptical though, because I wanted to see how Arch is compared to other distributions. Well, <a href="http://wiki.archlinux.org/index.php/Arch_Compared_To_Other_Distros" target="_blank">Arch thought about this already.</a> A wiki page is provided comparing and making a case for Arch versuses all the other big and a few small distros. It definately convinced me to at least TRY Arch.</p>
<p>Alright, Arch Linux seems like it won&#8217;t provide me with a bunch of features that I don&#8217;t want, but does this mean that I&#8217;ll have a hard time learning how to use and set it up properly? I consider myself a pretty competent Linux user, but I definately don&#8217;t know everything that is needed to set up a whole operating system. Good documentation is invaluable and is key for users to learn how to use your project. On the opposite hand, bad documentation is almost worse than no documentation. Jeff Atwood has a few words on this, which he calls <a href="http://www.codinghorror.com/blog/archives/000451.html" target="_blank">&#8220;undocumentation&#8221;</a>.</p>
<p>After a quick look around Arch&#8217;s website, I found not one, but TWO installation guides for the distribution. There was a <a href="http://wiki.archlinux.org/index.php/Beginners_Guide" target="_blank">beginner guide</a> as well as an <a href="http://wiki.archlinux.org/index.php/Official_Arch_Linux_Install_Guide" target="_blank">official guide</a>, with the former holding your hand through installation and the latter explaining a lot more details but expecting you to know what to do with them. I found it helpful to work through both guides simultaneously, as they were both very complemenetary.</p>
<p>Since Arch wants you to install everything yourself, once you&#8217;re done with the basic installation, you are presented with just a command prompt. No Gnome, no KDE, no X. Oh boy, I&#8217;ve had bad experiences messing around with X before, so I was a little worried about this step. The fact that I have 2 monitors of different sizes didn&#8217;t really make things any better (actually it made it MUCH harder).</p>
<p>Luckily, the install guide covered this topic pretty well. I did have to search forums and the wiki quite a bit since I had a somewhat unique setup with dual monitors and I&#8217;d never configured X before. This was definately the hardest step of the installation, but after I got it all set up properly, I have a <a href="http://www.gnome.org/" target="_blank">Gnome</a> installation with no clutter and customized just the way I want.</p>
<p>Another potential problem that I was worried about was how software management would be. Since Arch is a minimalist, I was concerned that managing packages might fall entirely on my shoulders. If this was the case, I don&#8217;t think I would have used Arch, since while it gives me more control, I&#8217;d much rather just have a package manager handle everything for me automatically. I was very pleased to see that Arch has the pacman package manager. Installing software is as simple as &#8216;pacman -S package&#8217;. The repositories are also current and seem to have a very large selection of software available.</p>
<p>I&#8217;m still getting my system setup to my liking, but so far, I&#8217;ve liked nearly everything I&#8217;ve seen about Arch. This is probably due to the fact that Arch really just provides powerful tools for you to build a Linux system to fit your exact needs. I&#8217;d highly recommend it to you if you&#8217;re looking for a new distro (or even if you&#8217;re not!).</p>
]]></content:encoded>
			<wfw:commentRss>http://samuelkerr.com/?feed=rss2&amp;p=196</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
