<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-21410781</id><updated>2012-01-27T21:27:12.907-08:00</updated><title type='text'>Building a Linux Media Network, one step at a time</title><subtitle type='html'>A step-by-step description of how to build a home media network.  A work in progress.
&lt;br/&gt;&lt;br/&gt;
If you have any questions about this project that aren't already answered on the site, please feel free to contact me.  My domain is razorwire dot ca.  Anything you send there will get to me.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-21410781.post-1244219526993803786</id><published>2009-07-08T12:18:00.000-07:00</published><updated>2009-07-08T12:29:08.146-07:00</updated><title type='text'>Android SwingWorker</title><content type='html'>I've been fooling around with the Android development platform.  It's quite an adjustment, coming from the iPhone world.  More thoughts to follow, although probably on a different blog.  I'm getting sick of this blogger nonsense.&lt;br /&gt;&lt;br /&gt;Anyways, I thought I'd post a simple equivalent to the SwingWorker class that works with Android's Event Dispatch Thread.  Here it is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package ca.razorwire.util;&lt;br /&gt;&lt;br /&gt;import java.util.concurrent.ExecutorService;&lt;br /&gt;import java.util.concurrent.Executors;&lt;br /&gt;&lt;br /&gt;import android.os.Handler;&lt;br /&gt;import android.os.Looper;&lt;br /&gt;import android.util.Log;&lt;br /&gt;&lt;br /&gt;public abstract class UIWorker&lt;br /&gt;{&lt;br /&gt;  private static final ExecutorService __execSvc;&lt;br /&gt;  private static final Handler __edtHandler;&lt;br /&gt;  &lt;br /&gt;  private static final String TAG = "UIWorker";&lt;br /&gt;  &lt;br /&gt;  static&lt;br /&gt;  {&lt;br /&gt;    __execSvc = Executors.newSingleThreadExecutor();&lt;br /&gt;    __edtHandler = new Handler( Looper.getMainLooper() );&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public abstract void doInBackground();&lt;br /&gt;  &lt;br /&gt;  public void done()&lt;br /&gt;  {&lt;br /&gt;    // Log.d(TAG, "done() executing in thread " + Thread.currentThread().getName() );&lt;br /&gt;    // This space intentionally left blank&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public void execute()&lt;br /&gt;  {&lt;br /&gt;    // Log.d(TAG, "execute() executing in thread " + Thread.currentThread().getName() );&lt;br /&gt;    final Runnable doneRunner = new Runnable()&lt;br /&gt;    {&lt;br /&gt;      public void run()&lt;br /&gt;      {&lt;br /&gt;        UIWorker.this.done();&lt;br /&gt;      }&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;    final Runnable bgRunner = new Runnable()&lt;br /&gt;    {&lt;br /&gt;      public void run()&lt;br /&gt;      {&lt;br /&gt;        // Log.d(TAG, "bgRunner executing in thread " + Thread.currentThread().getName() );&lt;br /&gt;        UIWorker.this.doInBackground();&lt;br /&gt;        __edtHandler.post( doneRunner );&lt;br /&gt;      }&lt;br /&gt;    };&lt;br /&gt;    __execSvc.submit(bgRunner);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And here's a sample usage:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;      UIWorker worker = new UIWorker()&lt;br /&gt;      {&lt;br /&gt;        public void doInBackground()&lt;br /&gt;        {&lt;br /&gt;          Log.d( TAG, "Sleeping for a bit." );&lt;br /&gt;          try { Thread.sleep( 10000 ); } catch ( Exception ignore ) {};&lt;br /&gt;        }&lt;br /&gt;      };&lt;br /&gt;      Log.d( TAG, "Executing worker..." );&lt;br /&gt;      worker.execute();&lt;br /&gt;      Log.d( TAG, "Returned from execute()" );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you uncomment the Log calls in UIWorker, you should see some output like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;07-08 12:14:11.015: DEBUG/rweeks(1078): Executing worker...&lt;br /&gt;07-08 12:14:11.015: DEBUG/UIWorker(1078): execute() executing in threadmain&lt;br /&gt;07-08 12:14:11.025: DEBUG/UIWorker(1078): bgRunner executing in thread pool-1-thread-1&lt;br /&gt;07-08 12:14:11.035: DEBUG/rweeks(1078): Sleeping for a bit.&lt;br /&gt;07-08 12:14:11.035: DEBUG/rweeks(1078): Returned from execute()&lt;br /&gt;07-08 12:14:21.038: DEBUG/UIWorker(1078): done() executing in thread main&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I'm 100% sure that Blogger is going to screw up the formatting.&lt;br /&gt;&lt;br /&gt;Public domain code, no guarantees, seems to work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-1244219526993803786?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/1244219526993803786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=1244219526993803786' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/1244219526993803786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/1244219526993803786'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2009/07/android-swingworker.html' title='Android SwingWorker'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-166413658031375216</id><published>2008-01-28T12:08:00.000-08:00</published><updated>2008-01-28T12:21:50.734-08:00</updated><title type='text'>Google/Flickr Image Scraper</title><content type='html'>I just received my &lt;a href="http://laptop.org/"&gt;XO laptop&lt;/a&gt; through the Give-1-Get-1 program.  I don't have a lot of plans for it yet but one thing I want to do is set up some photo albums for my 3-year-old son.  Interests include: helicopters, airplanes, trucks, trains.  The usual!&lt;br /&gt;&lt;br /&gt;I wrote a small app to grab pictures from Google Images based on a query string.  It was a short exercise in concurrent programming, more than anything else.  Lesson learned: the &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-summary.html"&gt;Java 1.5 concurrency APIs&lt;/a&gt; don't make the producer/consumer design pattern as easy as you might think, particularly when it comes to producer shutdown.&lt;br /&gt;&lt;br /&gt;After wrapping up the Google images scraper my friend &lt;a href="http://lunchatthevillage.blogspot.com/"&gt;Gwilli&lt;/a&gt; pointed out that Flickr is a much better resource for this sort of thing.  D'oh!  Fortunately it was a very small change to scrape their database, too.&lt;br /&gt;&lt;br /&gt;Instructions:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Make sure you have Java 1.5 or Java 6.  Download &lt;a href="http://gregchan.com/googlor/googlor.jar"&gt;googlor.jar&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Run &lt;span style="font-family:courier new;"&gt;java -jar googlor.jar &lt;/span&gt;(in OS X, just double-click the jar file)&lt;/li&gt;&lt;li&gt;The fields are pretty straightforward.  By default images will go into the &lt;span style="font-family:courier new;"&gt;images/&lt;/span&gt; subdirectory of the current working directory.&lt;/li&gt;&lt;li&gt;When images are presented, press 'j' to junk them or 'k' to keep them.  That's it.&lt;/li&gt;&lt;/ol&gt;I'm happy to make the source available to anyone who's interested.&lt;br /&gt;&lt;br /&gt;(I should point out, the images grabbed from Flickr are low-res, maximum 500x500.  This is a good fit for the XO's screen)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-166413658031375216?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/166413658031375216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=166413658031375216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/166413658031375216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/166413658031375216'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2008/01/googleflickr-image-scraper.html' title='Google/Flickr Image Scraper'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-8963950233381808748</id><published>2007-11-22T13:04:00.000-08:00</published><updated>2007-11-22T13:15:06.026-08:00</updated><title type='text'>WideFinder in Java6: revision3</title><content type='html'>Revision 3 of my WideFinder implementation is available &lt;a href="http://gregchan.com/wf/wf_03.tar.gz"&gt;here&lt;/a&gt;.  I see a small performance gain when I stagger the thread starts by 50ms.  I've tweaked the processing of the memory mapped "chunk" boundaries.  Now it's 99.9999998% correct :(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-8963950233381808748?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/8963950233381808748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=8963950233381808748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/8963950233381808748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/8963950233381808748'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2007/11/widefinder-in-java6-revision3.html' title='WideFinder in Java6: revision3'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-3742983593137640837</id><published>2007-11-13T17:20:00.000-08:00</published><updated>2007-11-13T18:11:38.867-08:00</updated><title type='text'>WideFinder/Java6 Rev2</title><content type='html'>... The sum total of the next 6 paragraphs is, "I tested a theory without collecting performance data and my changes seemed to have no impact on performance"... Skip to the DTrace Analysis section if that doesn't sound like a fun read...&lt;br /&gt;&lt;br /&gt;In the initial revision of the WideFinder, I couldn't get away from the thought that I was handling the data one too many times.  If you look at WideFinder.run (WideFinder.java:57),&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;  byte&lt;/span&gt;[] seq = &lt;b&gt;new&lt;/b&gt; &lt;span style="color: rgb(128, 0, 0);"&gt;byte&lt;/span&gt;[ seek - _mbb.&lt;span style="color: rgb(0, 0, 128);"&gt;position&lt;/span&gt;() ];&lt;br /&gt;_mbb.&lt;span style="color: rgb(0, 0, 128);"&gt;get&lt;/span&gt;( seq );&lt;br /&gt;nextLine = &lt;b&gt;new&lt;/b&gt; &lt;span style="color: rgb(0, 149, 255);"&gt;&lt;b&gt;String&lt;/b&gt;&lt;/span&gt;( seq, LOG_CHARSET );&lt;span style="font-family:Georgia,serif;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;We're grabbing bytes out of the buffer, sticking them into a fresh byte array, and creating a new String object based on those bytes, using a specific charset.  This is because the character set used by CharBuffer treats each byte as half of a 16-byte char, which means that the bytes are interpreted as non-English characters.&lt;br /&gt;&lt;br /&gt;Creating new byte[]s and new Strings like that, in a pretty tight loop, is just asking for performance trouble.  I wanted to get to the point where the regex could be applied straight to the ByteBuffer.  Looking at the implementation of Charset.encode, it seemed like it suffered from the same sort of space-inefficiency as my original approach.&lt;br /&gt;&lt;br /&gt;The solution was to wrap the ByteBuffer in a trivial implementation of CharSequence that indexed directly into the current line of the buffer.  The only gotcha was to use the mark() and reset() methods of the buffer in the implementation of subSequence.&lt;br /&gt;&lt;br /&gt;Unfortunately, my efforts produced only a minimal increase in performance (~2%) on either my single-core Athlon or the T2K.  So much for "low-hanging fruit".&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;DTrace Analysis&lt;/span&gt;&lt;br /&gt;I created a new revision of the Java 6 WideFinder with some tweaks to the ByteBuffer implementation.  It's available here: &lt;a href="http://gregchan.com/wf/wf_02.tar.gz"&gt;wf_02.tar.gz&lt;/a&gt;. It turned out to be a few hours' effort for a very minimal performance gain.&lt;br /&gt;&lt;br /&gt;With that little misadventure under my belt I decided to run the WideFinder through DTrace to see where the bulk of time was being spent.  &lt;a href="http://www.sun.com/bigadmin/content/dtrace/"&gt;DTrace&lt;/a&gt; is Sun's dynamic tracing tool, it allows you to inspect a bunch of different aspects of a program's performance as it is running.  If you've never used it, you should really give it a try.  It's pretty amazing, the stuff you get visibility into.  I gather it's also available on OS X as the "Instruments" app.&lt;br /&gt;&lt;br /&gt;This is the output of running the method-timings.d script against the WideFinder on a 100-line log file (produced by the DataGenerator).  Times given are in microseconds and represent the total time spent in methods in classes of the given package:&lt;br /&gt;&lt;pre&gt;sun/net/www/protocol/file         103&lt;br /&gt;sun/net/www                       266&lt;br /&gt;sun/net/www/protocol/jar          375&lt;br /&gt;java/nio/channels                 474&lt;br /&gt;java/util/concurrent/atomic       791&lt;br /&gt;sun/security/action              1065&lt;br /&gt;java/util/jar                    1731&lt;br /&gt;java/util/zip                    3146&lt;br /&gt;java/net                         3654&lt;br /&gt;java/security                    3807&lt;br /&gt;java/lang/ref                    5319&lt;br /&gt;java/util/concurrent             7419&lt;br /&gt;java/util/concurrent/locks       8329&lt;br /&gt;java/lang/reflect               10365&lt;br /&gt;sun/misc                        20678&lt;br /&gt;java/nio/channels/spi           25753&lt;br /&gt;sun/nio/ch                      32353&lt;br /&gt;java/nio/charset               160325&lt;br /&gt;java/util                      197794&lt;br /&gt;sun/nio/cs                     204016&lt;br /&gt;java/io                        240720&lt;br /&gt;sun/reflect                    293949&lt;br /&gt;wf                             464158&lt;br /&gt;java/lang                     1061836&lt;br /&gt;java/nio                      1596102&lt;br /&gt;java/util/regex               2738455&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The absolute values are not as meaningful as the relative values.  The act of observing the program's performance has skewed the measurements (where's that damned cat!), but we hope that it's skewed the measurements equally for each package.  From these data, we can see that the "big spenders" are java.util.regex (~39% of total time), java.nio (~25% of total time, with subpackages), and java.lang (~15% of total time).&lt;br /&gt;&lt;br /&gt;Here are the 10 most expensive methods in java.nio (not including subpackages), also measured in microseconds:&lt;br /&gt;&lt;pre&gt;CharBuffer.arrayOffset     43204&lt;br /&gt;CharBuffer.&amp;lt;init&amp;gt;          44219&lt;br /&gt;ByteBuffer.arrayOffset     51038&lt;br /&gt;HeapCharBuffer.&amp;lt;init&amp;gt;      62420&lt;br /&gt;CharBuffer.wrap           122109&lt;br /&gt;Buffer.position           280288&lt;br /&gt;Buffer.limit              286871&lt;br /&gt;Buffer.checkIndex         375539&lt;br /&gt;DirectByteBuffer.ix       485376&lt;br /&gt;DirectByteBuffer.get     1084831&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;And here are the 10 most expensive methods in java.util.regex (although there seem to be a lot of very expensive methods in this package):&lt;br /&gt;&lt;pre&gt;Pattern.escape                   165501&lt;br /&gt;Pattern$CharProperty.&amp;lt;init&amp;gt;      180954&lt;br /&gt;Pattern.peek                     184470&lt;br /&gt;Pattern$8.isSatisfiedBy          199079&lt;br /&gt;Pattern.isSupplementary          238639&lt;br /&gt;Pattern.atom                     240097&lt;br /&gt;Pattern$Slice.match              261159&lt;br /&gt;Matcher.getSubSequence           282353&lt;br /&gt;Matcher.group                    291688&lt;br /&gt;Pattern$BmpCharProperty.&amp;lt;init&amp;gt;   291799&lt;br /&gt;Pattern$BmpCharProperty.match   1080132&lt;/pre&gt;Looks like, if there's low-hanging fruit, it's in the regex processing.  A little regex-optimization may go a long way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-3742983593137640837?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/3742983593137640837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=3742983593137640837' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/3742983593137640837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/3742983593137640837'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2007/11/widefinderjava6-rev2.html' title='WideFinder/Java6 Rev2'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-5318552843059966123</id><published>2007-11-13T16:42:00.000-08:00</published><updated>2007-11-13T17:20:37.389-08:00</updated><title type='text'>Data Processing and the Gravel Biz</title><content type='html'>My Dad's in the gravel business.  Ever watch The Flintstones?  He's like Mr. Slate.  His job is to get as much sand and gravel as possible out of a mountain and onto barges.  From there, it floats down a river to a depot where (presumably) people are willing to pay for it.&lt;br /&gt;&lt;br /&gt;The trick about the gravel business, as with any other commodity industry I guess, is that you pretty much live or die based on 2 factors:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;How often you touch the product.&lt;/li&gt;&lt;li&gt;How much it costs you each time you touch it.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;In my Dad's case, they can't drive loaded trucks down the steep hill of their quarry to get to the river bank.  The road is too narrow to allow the trucks to pass each other.  So this is what they do:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A dumptruck pulls up to a big exacavator, which is scraping away at the side of the mountain pretty much non-stop.&lt;/li&gt;&lt;li&gt;The excavator fills the dump truck.  Takes somewhere around 5-6 scoops, I think.&lt;/li&gt;&lt;li&gt;The dump truck backs into position at the top of the cliff and waits for the all-clear to dump its load.  You don't want to rush that task or you wind up with a lot of expensive metal at the bottom of a cliff.&lt;/li&gt;&lt;li&gt;While that dump truck is getting ready to dump its load, another dump truck (from the &lt;span style="font-weight: bold;"&gt;pool&lt;/span&gt;, see where I'm going with this?) pulls up to the excavator and begins to receive its load.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;It's not a perfect setup: there is a finite amount of room on this plateau where the excavation takes place, you can't fit an unlimited number of dumptrucks in there.  Sometimes a dumptruck is forced to wait while the excavator fills up another truck.  We would not call this problem "embarassingly parallel" but there is definitely a producer-consumer pattern here.&lt;br /&gt;&lt;br /&gt;But a similar pattern plays itself out at the bottom of the cliff: loaders scoop up the dumped gravel and deposit it on a conveyor belt, where it is fed into a crusher (from there into another gravel pile, and from there onto a conveyor belt/barge, and from there to the sales facility, where another loader unloads the barge.  All told, I think they handle the product 4 times).&lt;br /&gt;&lt;br /&gt;The bottleneck here, of course, is the road.  At some point as the production capacity up on the plateau expands, the capital and operational expense of widening the road will become less than the cost of handling all that sand and gravel one extra time.&lt;br /&gt;&lt;br /&gt;What I find interesting about this problem is that the cost of handing a piece of gravel is infinitesimally small.  But when you multiply that cost by several trillion, it adds up to real dollars and cents.  And so it is with the Wide Finder.  Handling a single byte's worth of data, or a line's worth of data, is so "cheap" we hardly ever think about it.  But handling a Gb's worth of data, or 10 million lines worth, now you're talking real money.  Because processing time, especially in a batch environment like this, is money.&lt;br /&gt;&lt;br /&gt;Meh, some neat parallels there, is all I'm saying.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-5318552843059966123?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/5318552843059966123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=5318552843059966123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/5318552843059966123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/5318552843059966123'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2007/11/data-processing-and-gravel-biz.html' title='Data Processing and the Gravel Biz'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-8714927930873285917</id><published>2007-11-09T20:11:00.000-08:00</published><updated>2007-11-09T21:48:07.460-08:00</updated><title type='text'>WideFinder/Java6</title><content type='html'>Tim Bray has recently published a series of articles about a project he calls &lt;a href="http://www.tbray.org/ongoing/When/200x/2007/09/20/Wide-Finder"&gt;Wide Finder&lt;/a&gt;.  It pretty much amounts to a multi-threaded text processor for large files.  The idea is to implement the requirements in a variety of languages and determine the strengths and weaknesses of each implementation in a highly-parallelized environment.&lt;br /&gt;&lt;br /&gt;Here's my stab at it: &lt;a href="http://gregchan.com/wf/wf_01.tar.gz"&gt;WideFinder in Java 6&lt;/a&gt;.  Unfortunately, blogger is a really crappy way to publish this sort of thing, but here goes...&lt;br /&gt;&lt;br /&gt;The idea is to treat the log file as a random-access file and use Java's NIO API to memory-map one chunk of it per worker thread. The file is processed on a line-by-line basis, but the chunks are split up based roughly on the file size / number of workers.  This means that each worker's "chunk" probably doesn't begin or end on a line break.  These edge cases (literally, the edges of the buffer) are resolved after all the worker threads have completed.&lt;br /&gt;&lt;br /&gt;The initial implementation is really straight-forward.  My first approach used ByteBuffer.asCharBuffer to treat the memory mapped chunk as character data.  The problem was that 2 ASCII characters were getting packed into each 16-bit Java char, which meant that all the file data was appearing as CJK characters.  It's totally sensible that Java would do this, but I didn't see a quick way around it.  I'm going to take a closer look, though, because I think that the current implementation handles the data more than it needs to.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Timing Data&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul id=""&gt;&lt;li&gt;The source file is a 4,000,000 line (178Mb) file where each line matches the regex specified by Tim in the Wide Finder article (see the source for wf.DataGenerator).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Times are given as "number of workers"&lt;number&gt;x"elapsed (wall) time in seconds"&lt;total&gt;&lt;br /&gt;&lt;/total&gt;&lt;/number&gt;&lt;/li&gt;&lt;li&gt;Java VM is 1.6.0&lt;br /&gt;&lt;/li&gt;&lt;li&gt;VM arguments are -Xmx1024M -Xms1024M.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;AMD Athlon 64 1x2.2Ghz, 2.5Gb RAM, IO is nothing special (SATA something): 1x13.2 2x12.3 4x12.6&lt;/div&gt;&lt;div&gt;Sun T2000 24x1Ghz 8Gb RAM, IO is nothing special (stock 80Gb): 1x142.9 2x53.0 4x28.2 24x9.7&lt;/div&gt;&lt;div&gt;Intel Xeon 4x2.8Ghz, 3Gb RAM, some kind of SCSI I/O: 1x14.6 2x8.67 4x8.49&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My 2Ghz Core 2 Duo MacBook had to be excluded from this test because the code is currently dependent on Java 6... very frustrating.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Instructions to Run&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once the code has been compiled, the command is:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;java -cp &amp;lt;output directory&amp;gt; wf.WideFinder &amp;lt;log file&amp;gt; &amp;lt;regex&amp;gt; [num-workers]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Where "output directory" is where the classes were compiled to, "log file" is the path to the log file, "regex" is the regex to search for.  In this case, regex=='GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+)'.  If "num-workers" is not specified, the value returned by Runtime.getRuntime().availableProcessors() is used.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Next on the to-do list&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;ul id=""&gt;&lt;li&gt;Figure out how to use the NIO CharBuffer with US-ASCII encoding... or at least something that lets me deal with the characters as something other than CJK chars.  I confess that I'm frightfully ignorant of Unicode and character encodings.  About once a year I think, "I gotta learn that stuff..." so I read up on it, and I get to the point where I think I understand it, but I never seem to apply it in my day job, so it's quickly forgotten.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Run this bad boy through DTrace and see where the hot spots are... just a guess, I reckon Pattern.matches is burning up most of the CPU time.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Some low-hanging fruit is probably to do a plaintext match on the initial, constant portion of the regex... ideally take advantage of the 64-bit architecture and compare the first 8 characters of the line all at once!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Oh, yeah, also I should get around to ensuring that the program is actually &lt;b&gt;correct&lt;/b&gt;... it's definitely at the point where it's useful to gather performance data but I think there may be a couple corner cases that it'd puke on.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Back-port to Java 5 so I can develop/test on my MacBook (low priority)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;... Updated 11/9 21:17, removed inline source, Blogger was having a hissy fit about it.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://gregchan.com/wf/WideFinder.java"&gt;WideFinder.java&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://gregchan.com/wf/DataGenerator.java"&gt;DataGenerator.java&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;... Updated 11/9 21:41, just realized that to run this against actual log data, you'd probably have to change m.matches to m.find at line 76 of WideFinder.java.  That will skew the performance numbers, you may be able to optimize the regex by putting a caret at the beginning.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-8714927930873285917?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/8714927930873285917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=8714927930873285917' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/8714927930873285917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/8714927930873285917'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2007/11/widefinderjava6.html' title='WideFinder/Java6'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-2139499231566876542</id><published>2007-07-27T22:10:00.000-07:00</published><updated>2007-07-27T23:26:26.989-07:00</updated><title type='text'>Comparing Java Performance on Multi-Core CPUs</title><content type='html'>The tests in this article measure fixed-point Java performance on a variety of CPU architectures.  In summary: Java &lt;b&gt;can&lt;/b&gt; take advantage of multiple cores to avoid CPU contention, but in some cases not as well as you'd expect.&lt;br /&gt;I tested on 4 hardware configurations:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Athlon 64 3500+: 1 CPU, 1 Core, 2.2Ghz.  Running Linux kernel version 2.6.13, Java 1.6.0_02.  This was used as a baseline.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;MacBook Core 2 Duo: 1 CPU, 2 Cores, 2.2Ghz.  Running OS X kernel version 8.10.1, Java 1.6.0 (b88)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Dual Opteron 248: 2 CPUs, 1 Core each, 2.2Ghz/core.  Running Linux kernel version 2.6.13, Java 1.6.0_02&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sun T2000: 1 CPU, 6 cores, h/w support for 4 threads per core, Running SunOS kernel version 5.10&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;This is the most trivial test class I could come up with.  It's actually more complex than I thought it would be.  All it does is synchronize 1 or more threads to calculate a lot of large prime numbers at the same time.  This task is designed to provide high CPU contention and low IO/memory contention.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package ThreadTester;&lt;br /&gt;&lt;br /&gt;import java.math.BigInteger;&lt;br /&gt;import java.util.concurrent.Executors;&lt;br /&gt;import java.util.concurrent.CyclicBarrier;&lt;br /&gt;import java.util.concurrent.ExecutorService;&lt;br /&gt;&lt;br /&gt;public class ThreadTester&lt;br /&gt;{&lt;br /&gt;  private static final long START = Long.MAX_VALUE;&lt;br /&gt;  private static final int NUM_PRIMES = 4000;&lt;br /&gt;&lt;br /&gt;  private final CyclicBarrier _start;&lt;br /&gt;  private final CyclicBarrier _finish;&lt;br /&gt;  private final int _numThreads;&lt;br /&gt;&lt;br /&gt;  public ThreadTester( int numThreads )&lt;br /&gt;  {&lt;br /&gt;    _numThreads = numThreads;&lt;br /&gt;    _start = new CyclicBarrier( _numThreads, new Runnable()&lt;br /&gt;    {&lt;br /&gt;      public void run()&lt;br /&gt;      {&lt;br /&gt;        System.out.print( _numThreads + " " + System.currentTimeMillis() + " " );&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;    _finish = new CyclicBarrier( _numThreads, new Runnable()&lt;br /&gt;    {&lt;br /&gt;      public void run()&lt;br /&gt;      {&lt;br /&gt;        System.out.println( System.currentTimeMillis() );&lt;br /&gt;      }&lt;br /&gt;    });&lt;br /&gt;  }&lt;br /&gt;  public static void main( String[] args )&lt;br /&gt;  {&lt;br /&gt;    int numThreads = Integer.parseInt( args[ 0 ] );&lt;br /&gt;    new ThreadTester(numThreads).go();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private void go()&lt;br /&gt;  {&lt;br /&gt;    for ( int i = 0; i &lt; _numThreads; i++ )&lt;br /&gt;    {&lt;br /&gt;      new Thread( new PrimeFinder() ).start();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private class PrimeFinder implements Runnable&lt;br /&gt;  {&lt;br /&gt;    private BigInteger _bigNum = BigInteger.valueOf( START );&lt;br /&gt;&lt;br /&gt;    public void run()&lt;br /&gt;    {&lt;br /&gt;      try&lt;br /&gt;      {&lt;br /&gt;        _start.await();&lt;br /&gt;        for ( int i = 0; i &lt; NUM_PRIMES; i++ )&lt;br /&gt;        {&lt;br /&gt;          _bigNum = _bigNum.nextProbablePrime();&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      catch ( Exception ignore ) {}&lt;br /&gt;      finally&lt;br /&gt;      {&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;          _finish.await();&lt;br /&gt;        }&lt;br /&gt;        catch ( Exception ignore ) {};&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The raw data follows.  The timing data from different architectures should not be compared to each other.  In each graph, as the Y value (Time in Seconds) begins to grow linearly with X (Number of Threads), CPU contention among the threads is increasing.&lt;br /&gt;The Sun T2000 server clearly exhibits the best thread utilization.  This is unsurprising given the number of independent execution units available in the Niagara processor.  Note that had this test involved floating-point math, contention for the Niagara's single FPU among its 24 execution units would be intense.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_kzWwoOMu6QI/Rqrg0VvzhAI/AAAAAAAAAAk/0PxKjPvtW4Y/s1600-h/1graph.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_kzWwoOMu6QI/Rqrg0VvzhAI/AAAAAAAAAAk/0PxKjPvtW4Y/s320/1graph.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5092129518491239426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_kzWwoOMu6QI/Rqrgt1vzg_I/AAAAAAAAAAc/A2tvgtTqKVI/s1600-h/3graphs_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_kzWwoOMu6QI/Rqrgt1vzg_I/AAAAAAAAAAc/A2tvgtTqKVI/s320/3graphs_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5092129406822089714" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_kzWwoOMu6QI/Rqrgolvzg-I/AAAAAAAAAAU/cfwKLudNb7w/s1600-h/3graphs.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_kzWwoOMu6QI/Rqrgolvzg-I/AAAAAAAAAAU/cfwKLudNb7w/s320/3graphs.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5092129316627776482" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_kzWwoOMu6QI/RqrgKVvzg9I/AAAAAAAAAAM/uM1Yb6Umyhw/s1600-h/3graphs_2_2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_kzWwoOMu6QI/RqrgKVvzg9I/AAAAAAAAAAM/uM1Yb6Umyhw/s320/3graphs_2_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5092128796936733650" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Athlon-64     &lt;br /&gt;1  6.81  1185600041009 1185600047814&lt;br /&gt;2  13.58 1185600047914 1185600061492&lt;br /&gt;3  20.3  1185600061558 1185600081853&lt;br /&gt;4  26.9  1185600081925 1185600108820&lt;br /&gt;5  33.34 1185600108906 1185600142247&lt;br /&gt;6  40.13 1185600142336 1185600182463&lt;br /&gt;7  46.84 1185600182546 1185600229390&lt;br /&gt;8  54.85 1185600229477 1185600284327&lt;br /&gt;9  60.45 1185600284394 1185600344845&lt;br /&gt;10 65.59 1185600344954 1185600410545&lt;br /&gt;      &lt;br /&gt;MacBook     &lt;br /&gt;1  7.05  1185596894768 1185596901822&lt;br /&gt;2  11.34 1185596902131 1185596913471&lt;br /&gt;3  17.89 1185596914281 1185596932169&lt;br /&gt;4  25.19 1185596932657 1185596957846&lt;br /&gt;5  31.64 1185596958512 1185596990148&lt;br /&gt;6  37.19 1185596990764 1185597027957&lt;br /&gt;7  42.94 1185597028423 1185597071366&lt;br /&gt;8  48.03 1185597071971 1185597120005&lt;br /&gt;9  54.92 1185597120659 1185597175582&lt;br /&gt;10 59.95 1185597175905 1185597235859&lt;br /&gt;      &lt;br /&gt;248     &lt;br /&gt;1  6.16  1185598190089 1185598196249&lt;br /&gt;2  8.32  1185598196398 1185598204713&lt;br /&gt;3  15.57 1185598204849 1185598220423&lt;br /&gt;4  21.08 1185598220564 1185598241640&lt;br /&gt;5  25.96 1185598241766 1185598267726&lt;br /&gt;6  30.86 1185598267868 1185598298726&lt;br /&gt;7  35.15 1185598298870 1185598334015&lt;br /&gt;8  41.11 1185598334145 1185598375253&lt;br /&gt;9  45.52 1185598375373 1185598420891&lt;br /&gt;10 53.08 1185598421038 1185598474117&lt;br /&gt;&lt;br /&gt;T2K     &lt;br /&gt;1  31.2  1185597917415 1185597948610&lt;br /&gt;2  31.47 1185597949296 1185597980763&lt;br /&gt;3  32.47 1185597981545 1185598014017&lt;br /&gt;4  34    1185598014867 1185598048869&lt;br /&gt;5  32.84 1185598049745 1185598082581&lt;br /&gt;6  34.11 1185598083555 1185598117668&lt;br /&gt;7  35.38 1185598118647 1185598154031&lt;br /&gt;8  37.43 1185598154995 1185598192425&lt;br /&gt;9  38.97 1185598193408 1185598232373&lt;br /&gt;10 40.06 1185598233337 1185598273396&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-2139499231566876542?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/2139499231566876542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=2139499231566876542' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/2139499231566876542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/2139499231566876542'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2007/07/comparing-java-performance-on-multi.html' title='Comparing Java Performance on Multi-Core CPUs'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_kzWwoOMu6QI/Rqrg0VvzhAI/AAAAAAAAAAk/0PxKjPvtW4Y/s72-c/1graph.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-115049051122303082</id><published>2006-06-16T12:53:00.000-07:00</published><updated>2006-06-16T13:41:51.296-07:00</updated><title type='text'>SuSE 10.0: MP3 Support in K3B for Beginners</title><content type='html'>Hey!  In the words of the immortal &lt;a href="http:/www.theonion.com"&gt;Jim Anchower&lt;/a&gt;, I know it's been a while since I rapped at ya.  This entry is going to take a bit of a detour from the Media Center setup.  Instead I'll talk about building functionality into your Linux OS based on a combination of package management and good-old-fashioned building from open source.&lt;br /&gt;&lt;br /&gt;This article is targeted more towards open-source beginners... if you've been following along with the rest of the stuff on this site, you've probably already progressed beyond this point.  In any event, I welcome your comments.&lt;br /&gt;&lt;br /&gt;SuSE Linux, by default, does not ship with MP3 support for many of its applications.  I'm not sure if this is because they would be forced to license such technology from the patent-holders of the MP3 encoding algorithm, or if the RIAA prevents it somehow.  Anyways, it's a pain in the ass.  For instance, K3B, the popular CD-burning software for the K Desktop Environment (KDE), is pretty much crippled for making audio CDs.  Fortunately, it's pretty simple to rebuild K3B and include MP3 support.&lt;br /&gt;&lt;br /&gt;I shouldn't say simple.  The process itself is actually fairly complex, with dozens of different software products interacting with each other.  But the trick is to use the right tools to make it simple.&lt;br /&gt;&lt;br /&gt;Every Linux distribution these days, as far as I know, comes with some sort of package management software.  This tool's job is to resolve all these interactions and interdependencies between various software packages.  In SuSE, the distro I'll be covering here, this tool is called YAST.  In Debian or a debian-based distro such as Ubuntu, it's called apt-get.  In GenToo I believe it's called emerge.  Point is, whatever distribution you've chosen, there will almost certainly be a tool available to help you with this process.&lt;br /&gt;&lt;br /&gt;I should say right up front: if your distro &lt;i&gt;hasn't&lt;/i&gt; got one, or you can't find it, stop now.  In the time it takes you to resolve all the dependencies for building K3B you can install Ubuntu and never have to worry about this again.&lt;br /&gt;&lt;h3&gt;SuSE 10.0 Specific Note&lt;/h3&gt;&lt;br /&gt;You can make these package installs go a lot faster if you (a) have a copy of the original installation media and (b) have some hard drive space to spare.  What I did was create a directory, /suse10dvd/CD1, and copied the entire file/directory structure from my SuSE DVD into that directory.  Then, in YAST, you create a new installation source from the directory /suse10dvd (it will automatically look in CD1 for all the requisite files).&lt;br /&gt;&lt;h3&gt;Setup the development tools&lt;/h3&gt;&lt;br /&gt;Eventually, all the package management in the world is only going to get us so far.  When we reach that point we're going to need to take source code and turn it into a binary executable.  And to do that we will need some tools.  Fortunately, these tools can be installed by - you guessed it - the package management system.  Again, I will be assuming you're using SuSE 10.0 here.  As root, fire up YAST, and click on Software Management (might as well keep that screen open for a while).&lt;br /&gt;&lt;br /&gt;Install the following packages: &lt;code&gt;gcc g++ make automake autoconf&lt;/code&gt;.  Accept any dependencies YAST points out.&lt;br /&gt;&lt;h3&gt;Setup K3B source prerequisites&lt;/h3&gt;&lt;br /&gt;All these packages are also installable via YAST.  Go ahead and install them now: &lt;code&gt;xorg-x11-devel zlib-devel qt-devel libjpeg-devel kdebase3-devel taglib-devel libmusicbrainz-devel&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you notice that you're installing one of these "devel" packages, but the corresponding package is not selected (ie. &lt;code&gt;libjpeg&lt;/code&gt; for &lt;code&gt;libjpeg-devel&lt;/code&gt;), go ahead and select that too.  That's a lot of stuff, and it'll probably take a while to install.  While it's working you can download some of the stuff we'll need that SuSE can't provide.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Getting the source prerequisites&lt;/h3&gt;&lt;br /&gt;You'll need to get the source code for libmad.  This provides K3B with the ability to decode MPEG audio (ie. what we commonly refer to as an mp3 file).  Get it &lt;a href="http://www.underbit.com/products/mad"&gt;here&lt;/a&gt;.  Use SourceForge or their FTP site, doesn't matter.  You don't need the id3tag or madplay stuff, just the libmad download.&lt;br /&gt;&lt;br /&gt;You can build a more complete K3B by downloading LAME from &lt;a href="http://lame.sourceforge.net"&gt;lame.sourceforge.net&lt;/a&gt;.  LAME (Lame Ain't an MP3 Encoder) allows K3B and other tools to encode audio into MP3 format.  This isn't necessary for what we want to do, but it will add valuable functionality to your SuSE installation.&lt;br /&gt;&lt;br /&gt;These source packages come in a .tar.gz format - commonly known as a tarball.  Once you've downloaded them to a convenient spot on your hard disk you can extract them with the "tar xvfz &amp;lt;source package&amp;gt;.tar.gz" command.&lt;br /&gt;&lt;br /&gt;Extracting one of these tarballs will create a directory holding the source code, ie. &lt;code&gt;lame-3.97&lt;/code&gt;.  Once you're in this directory you can build the executable from the source code using these three commands - they're the same for pretty much any open source software package:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;&lt;code&gt;./configure&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;code&gt;make&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;(as root) &lt;code&gt;make install&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;The first command ensures that all the necessary dependencies are available and sets up the eventual install paths.  The second command actually takes the source code and turns it into binary files - executable files, code libraries, etc.  The third command takes those output files and puts them in the proper locations so that other programs (ie. k3b) can find them.&lt;br /&gt;&lt;br /&gt;I should note that the &lt;code&gt;configure&lt;/code&gt; script takes &lt;b&gt;a lot&lt;/b&gt; of options.  You can see some of them by running &lt;code&gt;./configure --help&lt;/code&gt;.  Unless you see something that really jumps out at you, you should accept the defaults for this project.&lt;br /&gt;&lt;br /&gt;Make sure that you run the last command, &lt;code&gt;make install&lt;/code&gt;, as either the root user or someone with root-like permissions.  Otherwise you probably won't be able to put the generated files in the default spots.&lt;br /&gt;&lt;h3&gt;Building K3B&lt;/h3&gt;&lt;br /&gt;Is basically a non-event.  Download the K3B source tarball from &lt;a href="http://k3b.plainback.com"&gt;the K3B homepage&lt;/a&gt;.  Extract it just like you did with the prerequisites (note that if the file ends in a &lt;code&gt;.tar.bz2&lt;/code&gt; suffix, you should use the command &lt;code&gt;tar xvfj &amp;lt;filename&amp;gt;.tar.bz2&lt;/code&gt; rather than &lt;code&gt;tar xvfz&lt;/code&gt;.  Go into the newly-created directory and run the same &lt;code&gt;./configure&lt;/code&gt;,&lt;code&gt;make&lt;/code&gt;,&lt;code&gt;make install&lt;/code&gt; commands as above.&lt;br /&gt;&lt;br /&gt;Note that when you run the &lt;code&gt;configure&lt;/code&gt; script, it will show you which extra features will be built into K3B.  You should see something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;K3b Configure results:&lt;br /&gt;------------------------------------------&lt;br /&gt;Ogg Vorbis support:                    yes&lt;br /&gt;&lt;br /&gt;Mp3 decoding support (libmad):         yes&lt;br /&gt;&lt;br /&gt;Audio meta data reading with Taglib:   yes&lt;br /&gt;&lt;br /&gt;libsndfile audio decoding support:     yes&lt;br /&gt;&lt;br /&gt;FLAC support:                           no&lt;br /&gt;    You are missing the FLAC++ headers and libraries.&lt;br /&gt;    The FLAC decoding plugin won't be compiled.&lt;br /&gt;&lt;br /&gt;Musepack support:                       no&lt;br /&gt;    You are missing the Musepack headers and libraries &gt;= 1.1.&lt;br /&gt;    The Musepack audio decoding plugin won't be compiled.&lt;br /&gt;&lt;br /&gt;Lame Mp3 encoder plugin:               yes&lt;br /&gt;&lt;br /&gt;Audio resampling:&lt;br /&gt;            using version bundled with K3b&lt;br /&gt;&lt;br /&gt;FFMpeg decoder plugin (decodes wma and others):&lt;br /&gt;                                        no&lt;br /&gt;    You are missing the ffmpeg headers and libraries&lt;br /&gt;    version 0.4.9 or higher.&lt;br /&gt;    The ffmpeg audio decoding plugin (decodes wma and&lt;br /&gt;    others) won't be compiled.&lt;br /&gt;&lt;br /&gt;Resmgr support:                        yes&lt;br /&gt;&lt;br /&gt;Audioplayer available (aRts)           yes&lt;br /&gt;&lt;br /&gt;Compile K3bSetup 2:                    yes&lt;br /&gt;&lt;br /&gt;Tag guessing using MusicBrainz          no&lt;br /&gt;    You are missing the musicbrainz headers and libraries.&lt;br /&gt;    K3b will be compiled without support for tag guessing.&lt;br /&gt;&lt;br /&gt;Compile HAL support                     no&lt;br /&gt;    You are missing the HAL &gt;= 0.4 headers and libraries&lt;br /&gt;    or the DBus Qt bindings.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Good - your configure finished. Start make now&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Your new version of K3B will by default be installed right overtop of the old version.  This is convenient, but you must remember now that the package manager (YAST) doesn't know that you've swapped in this new version, so any updates that SuSE may try to apply will probably blow away your changes.  Careful!&lt;br /&gt;&lt;br /&gt;If you'd rather put K3B in a different place, use the &lt;code&gt;--prefix&lt;/code&gt; argument to &lt;code&gt;configure&lt;/code&gt;.  Again, &lt;code&gt;configure --help&lt;/code&gt; has more information.&lt;br /&gt;&lt;br /&gt;That should be it! If you can drag MP3 files into your Audio CD project, you'll know everything's working.  Double check via the Help Menu that the version of K3B that you're running corresponds to the version that you just built - you may be running the old executable.&lt;br /&gt;&lt;br /&gt;If you have any trouble, Google is your friend.  If you're still in trouble, my contact information is on the sidebar to the right of this page.&lt;br /&gt;&lt;br /&gt;Good luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-115049051122303082?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/115049051122303082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=115049051122303082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/115049051122303082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/115049051122303082'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/06/suse-100-mp3-support-in-k3b-for.html' title='SuSE 10.0: MP3 Support in K3B for Beginners'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114356970922960249</id><published>2006-03-28T10:08:00.000-08:00</published><updated>2006-03-28T10:15:09.240-08:00</updated><title type='text'>Day of Disappointment</title><content type='html'>What a bummer.  I was just about ready to wrap this whole thing up when all of a sudden the &lt;a href="http://linuxmedianetwork.blogspot.com/2006/03/lcd-status-display.html"&gt;LCD&lt;/a&gt; display stopped working.  It wouldn't even POST, as soon as I hooked up the power it just showed some garbage on the screen.  My first assumption was that I need a new display - no big deal, the eBay seller has lots more of them and he was a pleasure to deal with.  So I dropped another $15 bucks on a new display.  Then I tried to investigate the problem a little bit more and found that the parallel port on my motherboard seems to have crapped out.  The values that I write to the SELECT_IN, INIT, AUTO_FD, and STROBE are all reset after about 125Ms, whereas before they would persist until I changed them.  This definitely isn't good.  They also all reset themselves to low (which in the case of select, auto feed, and strobe is actually +5v), which is kind of weird.&lt;br /&gt;&lt;br /&gt;Anyways, &lt;a href="http://www.logicsupply.com"&gt;Logic Supply&lt;/a&gt; has been great to me so far, so I'm hoping that they'll process this as a warranty claim without any hiccups.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114356970922960249?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114356970922960249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114356970922960249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114356970922960249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114356970922960249'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/03/day-of-disappointment.html' title='Day of Disappointment'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114289677752615577</id><published>2006-03-20T15:02:00.000-08:00</published><updated>2006-03-20T15:26:51.143-08:00</updated><title type='text'>Removing the Hard Disk</title><content type='html'>One of the last steps in this project is to switch the operating system from the hard disk to a compact flash card.&lt;br /&gt;&lt;br /&gt;The CF card I'm using is a &lt;a href="http://www.sandisk.com/Products/Item(1157)-SDCFH-1024-SanDisk_Ultra_II_CompactFlash_1GB.aspx"&gt;1Gb  SanDisk Ultra II&lt;/a&gt;.  I also have a &lt;a href="http://www.pcengines.ch/cflash.htm"&gt;CFDisk CF-IDE adaptor&lt;/a&gt; so I can plug the card into a regular IDE channel.&lt;br /&gt;&lt;br /&gt;I thought it would be a simple matter of booting into a separate Debian install (I still have one on  it's own partition from my first attempt at all this) and copying the entire file system from the hard disk to the flash card.  Unfortunately, I was unable to write to the Ultra II card while it was in the IDE adaptor.  Actually, I &lt;b&gt;was&lt;/b&gt; able to correctly write about 999,999 bytes out of every 1,000,000, but that just ain't good enough.  This turned out to be a very tricky problem to track down.  Basically I wound up having to recursively diff each file in the source and the destination to determine that there were some bytes that got mangled during the copy.  Also, running &lt;code&gt;/sbin/badblocks -t random -w /dev/hdb&lt;/code&gt; indicated that certain writes would just randomly fail. [Note that the above command will destroy all existing data on your hard disk]&lt;br /&gt;&lt;br /&gt;The solution was to insert the CF card into a standard USB card reader, the kind you might have to go with your digital camera. Debian automatically recognized the device and mounted it as &lt;code&gt;/dev/sdb&lt;/code&gt;.  It was all much more convenient than I imagined it would be. In the end, I guess the write speed through USB was slow enough not to cause a problem.  Once the filesystem was copied over, and I was ready to switch to a read-only file system, I reconnected the card to the IDE adaptor, because reading from the card works fine.&lt;br /&gt;&lt;br /&gt;I followed the instructions that I described &lt;a href="http://linuxmedianetwork.blogspot.com/2006/02/setting-up-ramdisk.html"&gt;here&lt;/a&gt; to get the ramdisk up and running, and then borrowed a couple points from &lt;a href="http://www.linuxjournal.com/article/7233"&gt;here&lt;/a&gt;: notably, creating a symbolic link from &lt;code&gt;/proc/mounts&lt;/code&gt; to &lt;code&gt;/etc/mtab&lt;/code&gt; and editing &lt;code&gt;/etc/fstab&lt;/code&gt; to include the "ro" option for the root filesystem.&lt;br /&gt;&lt;br /&gt;That's all.  Because these disk writes are (infinitesimally) unreliable and it's a real pain in the ass to switch between the hard disk and the cf-card, I'm going to go back to the hard disk for now and then try this whole process one more time when I am sure that I'm 100% finished.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114289677752615577?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114289677752615577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114289677752615577' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114289677752615577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114289677752615577'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/03/removing-hard-disk.html' title='Removing the Hard Disk'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114236425362221554</id><published>2006-03-14T09:14:00.000-08:00</published><updated>2006-03-14T11:24:13.670-08:00</updated><title type='text'>Tying it all together</title><content type='html'>Let's recap all the components of the Media Center so far:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Xine video player + Unichrome XXMC driver for hardware playback&lt;/li&gt;&lt;br /&gt;&lt;li&gt;IR receiver + LIRC daemon with Xine integration for wireless control&lt;/li&gt;&lt;br /&gt;&lt;li&gt;4-line LCD display + LCDProc daemon to show status information&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Backed-up DVD media available via NFS mount to backfire&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Pretty much all that's left is to wire all these things together in software.  The requirements for that piece of software are:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Browse through the available media files&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Play selected media file&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Update the LCD display with title of current media file, pause/play/stop status, and position in stream&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The 'browse' and 'select' actions must be executable via the remote control&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;That's a pretty rough set of requirements, but it'll do for now.  It took me a couple days, but I came up with a bit of software that meets these pretty nicely.  It's about 1500 lines of code spead out over a dozen or so Java classes.  I'm calling it '&lt;code&gt;mediabrowser&lt;/code&gt;' for now and you can download it &lt;a href="http://pub.razorwire.ca/MediaBrowser.tar.gz"&gt;here&lt;/a&gt;.  You'll need JDK 1.5 to build it, or JRE 1.5 to run it.  Both can be obtained from &lt;a href="http://java.sun.com"&gt;java.sun.com&lt;/a&gt;.&lt;br /&gt;&lt;h3&gt;Building Mediabrowser&lt;/h3&gt;&lt;br /&gt;You'll need a recent version of &lt;a href="http://ant.apache.org"&gt;Apache Ant&lt;/a&gt; to do the build.  Just run &lt;code&gt;ant clean dist&lt;/code&gt;.  The file &lt;code&gt;build/dist/mediabrowser.tar.gz&lt;/code&gt; will be created.  Extract that to your installation directory and you're ready to go.&lt;br /&gt;&lt;h3&gt;Configuring Mediabrowser&lt;/h3&gt;&lt;br /&gt;Running Mediabrowser is fairly straightforward.  Before you get started with it, ensure that the &lt;a href="http://linuxmedianetwork.blogspot.com/2006/02/building-and-configuring-lirc.html"&gt;LIRC&lt;/a&gt; and &lt;a href="http://linuxmedianetwork.blogspot.com/2006/03/lcd-status-display.html"&gt;LCDd&lt;/a&gt; daemons are running.  Make sure that you started &lt;code&gt;lircd&lt;/code&gt; with the &lt;code&gt;-l&lt;/code&gt; option so it can provide the IR data over a TCP/IP port.  Then follow these steps to adjust the Mediabrowser to suit your configuration:&lt;ul&gt;&lt;li&gt;Edit &lt;code&gt;conf/xineloader.properties&lt;/code&gt;. Verify that &lt;code&gt;xl.cmd.xine&lt;/code&gt; matches your Xine command.&lt;/li&gt;&lt;li&gt;Edit&lt;code&gt;mb.properties&lt;/code&gt;. Adjust &lt;code&gt;mb.media.root&lt;/code&gt; to match the root directory for your media collection.  If you are using a remote control, change the property &lt;b&gt;names&lt;/b&gt; for the &lt;code&gt;ir.btnmap.[...]&lt;/code&gt; properties to match the button names in your LIRC configuration file.  That will map each button to a Java KeyEvent.&lt;/li&gt;&lt;li&gt;Finally, edit the sample index file &lt;code&gt;index.xml&lt;/code&gt; and place it in the root media directory that you specified above.  This is what the Mediabrowser will inspect to get information about your collection.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Running Mediabrowser&lt;/h3&gt;&lt;br /&gt;Running the Mediabrowser is as simple as &lt;code&gt;java -cp conf:bin ca.razorwire.mb.gui.MediaBrowser&lt;/code&gt;.  A full-screen window should appear, displaying the entries in your &lt;code&gt;index.xml&lt;/code&gt; file.  You can navigate the screen and select an entry using the buttons on your remote that you defined in the &lt;code&gt;mb.properties&lt;/code&gt; file.&lt;br /&gt;&lt;h3&gt;How It Works&lt;/h3&gt;&lt;br /&gt;Briefly: When the GUI launches, it starts a thread to monitor for LIRC output on the default LIRC port, 8765.  When it receives LIRC data that it recognizes it generates a corresponding Java AWT event indicating that a key has been typed (this is what the btnmap and keymap properties in &lt;code&gt;mb.properties&lt;/code&gt; are for).  This event is sent to a hidden UI component in the GUI that always has the keyboard input focus.&lt;br /&gt;&lt;br /&gt;As far as this UI component is concerned, a key has just been pressed.  You can see this yourself by pressing any of the keys defined in the properties file.  The behaviour should be exactly the same as if you'd pressed a button on the remote.  It then maps the keypress to a UI action - either scrolling through the title list, scrolling the current title's description summary, or playing the title.&lt;br /&gt;&lt;br /&gt;When you start playing a title, the GUI launches a new thread to start the Xine application as a separate process.  It also stops processing LIRC output, because we don't to process any button-presses that were meant only for Xine.  If the LCD screen is enabled, this thread keeps a reference to the LCD driver and the title of the current track.  It monitors our hacked-up Xine output to catch the stream position updates, and prints out the track title and current position to the LCD screen.  When the Xine application completes, the thread dies and control is returned to the GUI.&lt;br /&gt;&lt;h3&gt;TODO:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Need some screenshots!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Need a sexier GUI! Right now it's just the standard Swing look and feel.  Perfectly functional, but not that attractive compared to most Media Center offerings.  Maybe whip something up in OpenGL to take advantage of the hardware acceleration?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;MythTV integration... haven't got a capture card yet so I'm still quite a ways behind on the Myth scene.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114236425362221554?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114236425362221554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114236425362221554' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114236425362221554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114236425362221554'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/03/tying-it-all-together.html' title='Tying it all together'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114201186191494061</id><published>2006-03-10T09:22:00.000-08:00</published><updated>2006-03-10T09:31:01.930-08:00</updated><title type='text'>Tweak to DVDBackup</title><content type='html'>Just a quick aside here to talk about a software component that will be going on &lt;a href="http://linuxmedianetwork.blogspot.com/2006/01/hardware.html"&gt;backfire&lt;/a&gt;, the media server.  There's an incredibly useful utility floating around the net called DVDBackup.  As far as I can tell there is no official site for it but some useful information about it can be found &lt;a href="http://dvd.chevelless230.com/dvdbackup.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Version 0.1 has a small bug in it that caused a segfault while I was backing up the Firefly TV series.  A patched version is available &lt;a href="http://backfire.razorwire.ca:1138/public/dvdbackup.c"&gt;here&lt;/a&gt;.  The only difference is moving the call to &lt;code&gt;ifoClose&lt;/code&gt; in &lt;code&gt;DVDGetInfo&lt;/code&gt; to line 852.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114201186191494061?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114201186191494061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114201186191494061' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114201186191494061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114201186191494061'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/03/tweak-to-dvdbackup.html' title='Tweak to DVDBackup'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114185568061905216</id><published>2006-03-08T14:03:00.000-08:00</published><updated>2006-03-08T14:08:00.620-08:00</updated><title type='text'>Extracting command activity from Xine</title><content type='html'>In &lt;a href="http://linuxmedianetwork.blogspot.com/2006/03/stream-position-data-in-xine.html"&gt;this post&lt;/a&gt; I described how to tweak the Xine source code to print the current stream position in a friendly format.  Printing out the command activity (ie. 'pause', 'play', 'stop', etc.) is similarly easy.  In the file &lt;code&gt;src/xitk/event.c&lt;/code&gt;, just add a line in the function &lt;code&gt;gui_execute_action_id&lt;/code&gt; that looks like this: &lt;code&gt;fprintf( stdout, "action\t%d\n", action); fflush( stdout );&lt;/code&gt;.  Then run &lt;code&gt;make debug &amp;&amp; make install-debug&lt;/code&gt; to deploy the changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114185568061905216?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114185568061905216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114185568061905216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114185568061905216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114185568061905216'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/03/extracting-command-activity-from-xine.html' title='Extracting command activity from Xine'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114185485026422345</id><published>2006-03-08T12:32:00.000-08:00</published><updated>2006-03-08T13:59:46.833-08:00</updated><title type='text'>LCD Status Display</title><content type='html'>One neat feature I'd like to incorporate into this media center is the ability to display the unit's status off-screen.  By that, I mean the same sort of functionality that your DVD or CD player gives you: a panel to show the current position in the track, the play/pause/stop status, etc.&lt;br /&gt;&lt;br /&gt;I started by ordering a 20-character, 4-line display from "rainbow_city_store" on eBay.  The service was prompt and wholly satisfactory.  This display is compatible with the popular HD44780 LCD controller, and can basically be plugged straight into a parallel port once you've got the wiring all sorted out.  The seller provided a couple of schematic diagrams, and also some helpful links to more wiring diagrams and various HD44780 projects.  I wired up the display to the parallel port as described &lt;a href="http://www.moddershq.net/guides.asp?guideid=13"&gt;here&lt;/a&gt; (I didn't use the port cups, but the schematic was great).&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/breadboard.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1286/264/400/breadboard.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;(ignore the extra notes for now)&lt;br /&gt;&lt;br /&gt;Once the display was wired up I investigated a project called &lt;a href="http://lcdproc.omnipotent.net"&gt;LCDProc&lt;/a&gt;.  This is a useful little tool that can display things like CPU, Memory, and Disk usage on an external display.  But what's more important is the component of LCDProc that can drive the HD44780 over the parallel port (LCDd).  This really simplifies the interface to the display by providing simple commands that can be executed via a regular TCP/IP socket.&lt;br /&gt;&lt;br /&gt;Here are some notes on establishing communication with the display:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;At the hardware level, you can check that your signals are correct by using a multimeter to measure the voltage between certain pins and the ground.  The SP800 sets the data pins to 3.3V (high) or 0.5V (low).  The other pins will be between 1.5V and 5V high or 0.5V low, I believe.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If you have applied power to Pin 2 on the LCD and grounded pins 1 and 3, you should see lines 2 and 4 on the display illuminate (barely).  If you apply power to pin 15 and ground pin 16 &lt;b&gt;(make sure you get that right)&lt;/b&gt; you will activate the backlight, and the lines should be much more visible.  This is the HD44780 self-test.  You may be stuck here a while :)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pin 1 on the parallel port (pin 6 on the display) is the Strobe.  If you are interfacing directly with the hardware (ie. not using LCDd), be sure to set this to high, and then to low to tell the LCD controller that the signal on the data pins are valid.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Access to the data pins of the parallel port on the SP800 is at IO 0x378.  You can access the status pins at 0x38A. More info &lt;a href="http://www.faqs.org/docs/Linux-mini/IO-Port-Programming.html#ss6.1"&gt;here&lt;/a&gt;.  Some sample code is &lt;a href="http://backfire.razorwire.ca:1138/public/lptout.c"&gt;here&lt;/a&gt;.  Compile like so: &lt;code&gt;gcc -o lptout lptout.c&lt;/code&gt;.  Just tweak the &lt;code&gt;outb&lt;/code&gt; call to direct the byte to the data or status pins.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If you are using LCDproc/LCDd and have wired your display like mine, you want the HD44780 driver and the "8bit" wiring configuration.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Build and install LCDd like so:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;# Download and extract the tarball to /usr/local/src&lt;br /&gt;cd lcdproc-0.4.5&lt;br /&gt;./configure --enable-drivers=hd44780&lt;br /&gt;make &amp;&amp; make install&lt;br /&gt;&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Edit LCDd.conf.  Uncomment the line "Driver=HD44780" and comment out any other drivers.  In the [HD44780] section, ensure the &lt;code&gt;Port&lt;/code&gt; parameter is set to &lt;code&gt;0x378&lt;/code&gt; and the &lt;code&gt;ConnectionType&lt;/code&gt; parameter is set to &lt;code&gt;8bit&lt;/code&gt;.  The size should also be set to 20x4.  Finally, copy this file to &lt;code&gt;/etc&lt;/code&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Start LCDd by running &lt;code&gt;LCDd /etc/LCDd.conf&lt;/code&gt;.  It runs in the foreground by default. This is configurable within the conf file.  If LCDd was able to connect and interface with your display, the screen should change from the two active lines (self-test screen) to something like this:&lt;code&gt;&lt;br /&gt;LCDProc Server&lt;br /&gt;Clients: 0&lt;br /&gt;Screens: 0&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;(The display pinout on my LCD screen is actually at the top of the display, so this screen currently appears upside-down.  If you know of a way to rotate the display via the controller I would love to know.)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Test the connection by opening a new terminal window and running &lt;code&gt;lcdproc C&lt;/code&gt;.  This will try to connect to LCDd on the default address and port and display your CPU usage statistics on the LCD screen.  If it works, congratulations!&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h3&gt;Extra Credit&lt;/h3&gt;&lt;br /&gt;That backlight ain't gonna last forever, you know.  It would be convenient if we could turn it on and off at will.  A simple potentiometer or switch between pin 16 and ground would do the trick. Or... we could wire it up to one of the unused status pins on the parallel port and control it by a transistor... oooh!  Good idea!&lt;br /&gt;&lt;br /&gt;Turns out, I wasn't the first one to think of it.  But I did it slightly differently than described in the (excellent) &lt;a href="http://lcdproc.sourceforge.net/docs/stable-0-4-x-user-html/"&gt;LCDproc documentation&lt;/a&gt;.  Here's the schematic:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/img_2297_edited-1.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1286/264/400/img_2297_edited-1.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;The transistor is a &lt;a href="http://www.fairchildsemi.com/ds/2N/2N3904.pdf"&gt;2N3904&lt;/a&gt;, which we happened to have lying around the office.  The collector goes to pin 16 on the LCD, the emitter goes to ground, and the base to pin 17 of the parallel port via a 1K resistor.  If you're interested, here's the math, as I understand it:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;By hooking up an ammeter &lt;b&gt;in series&lt;/b&gt; with the LCD display pin 15 we can see that the backlight draws ~51mA of current.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The two figures we need from the 2N3904 data sheet are the gain (h&lt;sub&gt;fe&lt;/sub&gt;) and the base/emitter saturation V&lt;sub&gt;BE(sat)&lt;/sub&gt;, which is 0.65 ~= 0.7 for a current draw of 0.051A.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The high voltage on parallel port pin 17 (SEL) will be 1.5V.  We subtract the saturation voltage from this to get 0.8V.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;We calculate the required resistance for the transistor like so: 0.8V / ( 0.051A / 60 ).  This gives us a resistance of 941 Ohms, ~= 1K.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;LCDd has some backlight functionality built-in, but I had to tweak it a little bit to get it to work with this setup.  There appears to be some conflict with pin 17 and the "multiple display" feature of LCDproc - when I started LCDd, the backlight would blink on and off repeatedly.  The easiest way to stop this, if you're just using one display like me, is to force the &lt;code&gt;displayID&lt;/code&gt; to 0 in the function &lt;code&gt;lcdwinamp_HD44780_senddata&lt;/code&gt; (server/drivers/hd44780-winamp.c).  I also had to swap the values for BacklightBrightness and BacklightOffBrightness in LCDd.conf.  Then I just set the &lt;code&gt;Backlight&lt;/code&gt; parameter in the HD44780 section of the conf file to "yes".&lt;br /&gt;&lt;br /&gt;After the code change, run &lt;code&gt;make &amp;&amp; make install&lt;/code&gt; to deploy the changes. Restart LCDd.  You can test the backlight by telnetting to &lt;code&gt;localhost 13666&lt;/code&gt; and entering the following commands:&lt;code&gt;&lt;br /&gt;hello&lt;br /&gt;screen_add 0&lt;br /&gt;backlight on&lt;br /&gt;backlight off&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Note that the &lt;code&gt;backlight&lt;/code&gt; command has no effect until at least one screen has been created.&lt;br /&gt;Here's a shot of the LCD display in action.  If you look closely, you can see that it's displaying the timing data that we just took out of Xine. More on that in the next post.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/img_2302.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1286/264/400/img_2302.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114185485026422345?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114185485026422345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114185485026422345' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114185485026422345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114185485026422345'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/03/lcd-status-display.html' title='LCD Status Display'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114168733632230236</id><published>2006-03-06T14:48:00.000-08:00</published><updated>2006-03-06T15:22:17.183-08:00</updated><title type='text'>Stream Position Data in Xine</title><content type='html'>Now that Xine is up and running, it would be handy to be able to extract the stream position data from the application and display it elsewhere (on a status display, for instance).  This way, we could see how much of the movie we've played, how much time remains, etc.&lt;br /&gt;&lt;br /&gt;This is pretty easy, once you figure out where to look.  In the xine-ui source, go into &lt;code&gt;src/xitk/stdctl.c&lt;/code&gt;.  In the function &lt;code&gt;xine_stdctl_loop&lt;/code&gt;, change the line:&lt;br /&gt;&lt;code&gt;int secs, last_secs;&lt;/code&gt; to &lt;code&gt;int secs, last_secs, len_secs, stream_pos;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Just below that, you should see where &lt;code&gt;last_secs&lt;/code&gt; is initialized to 1.  Copy that line twice and replace &lt;code&gt;last_secs&lt;/code&gt; with &lt;code&gt;len_secs&lt;/code&gt; and &lt;code&gt;stream_pos&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Near the end of that function, replace the call to &lt;code&gt;gui_xine_get_pos_length(...)&lt;/code&gt; with &lt;code&gt;gui_xine_get_pos_length( gGui-&gt;stream, &amp;stream_pos, &amp;secs, &amp;len_secs )&lt;/code&gt;.  Divide &lt;code&gt;len_secs&lt;/code&gt; by 1000 afterwards, as is already done with &lt;code&gt;secs&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Replace the call to &lt;code&gt;fprintf&lt;/code&gt; with this: &lt;code&gt;fprintf(stdout, "time\t%d\t%d\n", secs, len_secs)&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Run &lt;code&gt;make &amp;&amp; make install&lt;/code&gt; to deploy your changes.&lt;br /&gt;&lt;br /&gt;Finally, Xine suppresses output to standard out (stdout) shortly after it prints its introductory banner/copyright data.  The easiest way to prevent this is by prepending the &lt;code&gt;--verbose&lt;/code&gt; option to the command line.  A slightly cleaner way (only cleaner in terms of the output) is to run &lt;code&gt;make clean &amp;&amp; make debug &amp;&amp; make install_debug&lt;/code&gt; to deploy your changes instead.  If everything's working right, you should see a bunch of lines like this displayed on the screen:&lt;br /&gt;&lt;code&gt;time 0 97&lt;br /&gt;time 1 97&lt;br /&gt;time 2 97&lt;/code&gt;&lt;br /&gt;The first number is the current position in seconds in the current stream and the second is the length of the current stream, in seconds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114168733632230236?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114168733632230236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114168733632230236' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114168733632230236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114168733632230236'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/03/stream-position-data-in-xine.html' title='Stream Position Data in Xine'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114107251016208378</id><published>2006-02-27T12:26:00.000-08:00</published><updated>2006-02-27T12:35:11.126-08:00</updated><title type='text'>Trimming the disk usage</title><content type='html'>Here are some areas where we can probably trim some fat from the hard disk:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;/usr/share/doc&lt;/code&gt; - 20M&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/share/man&lt;/code&gt; - 6.7M&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/local/bin/via&lt;/code&gt; - 9.7M (this was where I downloaded the VIA DRI binaries to, but they've been installed so I can remove them&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/X11R6/man&lt;/code&gt; - 12M&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/X11R6/lib/X11/doc&lt;/code&gt; - 14M&lt;/li&gt;&lt;li&gt;&lt;code&gt;/usr/X11R6/lib/modules/dri&lt;/code&gt; - 24M (but obviously not the VIA driver)&lt;/li&gt;&lt;li&gt;&lt;code&gt;/lib/modules/2.4xxx/*&lt;/code&gt; - 29M&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Also removing &lt;code&gt;binutils bison flex g++ g++-3.3 gcc gcc-3.3 gcc-3.3-base kernel-source-2.6.8 linux-kernel-headers make&lt;/code&gt; through apt-get will free another 60Mb or so.  Best to do this before deleting the above files, in case any dependencies get mucked up.&lt;br /&gt;&lt;br /&gt;This will be entirely offset by the installation of the Java 1.5 Runtime Environment, which I'm considering installing... that will weigh in at 91Mb.  Ouch.  Maybe need to rethink that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114107251016208378?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114107251016208378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114107251016208378' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114107251016208378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114107251016208378'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/trimming-disk-usage.html' title='Trimming the disk usage'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114093718337497135</id><published>2006-02-25T22:49:00.000-08:00</published><updated>2006-02-27T09:22:22.776-08:00</updated><title type='text'>Getting Video</title><content type='html'>Just some notes on building and installing the requisite tools for DVD playback on the Via Epia SP800 (CN400 Chipset)... will clean up as time allows... see the sidebar for contact info if you have questions.&lt;br /&gt;&lt;br /&gt;Building Xine:&lt;br /&gt;I grabbed Debian's ALSA (Advanced Linux Sound Architecture) user-space packages first since I enabled ALSA support when I rebuilt the kernel... &lt;code&gt;apt-get install libasound2 libasound2-dev&lt;/code&gt;.  Configuring ALSA is as simple as running &lt;code&gt;alsaconf&lt;/code&gt; and selecting the VIA sound driver.&lt;br /&gt;&lt;br /&gt;Download source tarballs for xine-lib and xine-ui from http://xinehq.de&lt;br /&gt;For xine-lib:&lt;br /&gt;./configure --prefix=/usr&lt;br /&gt;make &amp;&amp; make install&lt;br /&gt;&lt;br /&gt;For xine-ui:&lt;br /&gt;&lt;code&gt;./configure --prefix=/usr --x-includes=/usr/X11R6/include --x-libraries=/usr/X11R6/lib&lt;/code&gt;&lt;br /&gt;I needed to patch the file &lt;code&gt;src/xitk/oxine/Makefile&lt;/code&gt;.  It does not include the X11 headers as specified in the ./configure command line.  So just search for &lt;code&gt;AM_CPPFLAGS =&lt;/code&gt; and add &lt;code&gt;-I/usr/X11R6/include&lt;/code&gt; to the end of the line. Then,&lt;br /&gt;&lt;code&gt;make &amp;&amp; make install&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The last piece of the puzzle is to invoke xine and tell it to use the drivers we have just set up: ALSA for audio, and the Via XVMC driver for video.  Let's say that you've backed up the &lt;a href="http://www.imdb.com/title/tt0379786/"&gt;Serenity&lt;/a&gt; DVD to &lt;code&gt;/media/movies/SERENITY.iso&lt;/code&gt;.  The command would then be:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;xine -V xxmc -A alsa dvd:/media/movies/SERENITY.iso&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Assuming that you have removed the CSS encryption from the DVD.  That will be covered in the next lesson.&lt;br /&gt;&lt;br /&gt;Note that we specify the "xxmc" video driver.  Running &lt;code&gt;xine --help&lt;/code&gt; shows that the more intuitively-named driver "xvmc" is available, but specifying that on the command line crashes xine.  Using "xxmc" works, and we can tell that it's using the onboard MPEG accelerator because running &lt;code&gt;top&lt;/code&gt; while watching the movie shows CPU utilization at around 3%.  Contrast that to the un-accelerated driver, where CPU utilization will be around 20-30%.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114093718337497135?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114093718337497135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114093718337497135' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114093718337497135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114093718337497135'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/getting-video.html' title='Getting Video'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114090924953479874</id><published>2006-02-25T14:56:00.000-08:00</published><updated>2006-02-27T09:22:00.906-08:00</updated><title type='text'>Building and Configuring LIRC</title><content type='html'>Building LIRC is actually pretty simple.  Download the source package from &lt;a href="http://www.lirc.org"&gt;lirc.org&lt;/a&gt; and extract it to /usr/local/src.  As indicated in the INSTALL file in that package, compiling it is as simple as running &lt;code&gt;setup.sh &amp;&amp; make install&lt;/code&gt;.  But you'll need the "dialog" package to run the setup script, so &lt;code&gt;apt-get install dialog&lt;/code&gt; first.  It's a small package and you can remove it as soon as you're done.&lt;br /&gt;&lt;br /&gt;When I ran the setup script it correctly detected my port configuration (IO and IRQ).  Note that the onboard serial header is &lt;code&gt;COM2&lt;/code&gt;, known to Linux as &lt;code&gt;/dev/ttyS1&lt;/code&gt;.  The default parameters for this port on the SP800 are 2F8 and IRQ3.&lt;br /&gt;&lt;br /&gt;The configure script expects the kernel source to be installed in /usr/src.  I had actually moved it to a separate partition to free up some room, so I just mounted the partition and made a symbolic link to the source.  The source should be in a directory like &lt;code&gt;kernel-source-2.6.8&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;Save the configuration, run &lt;code&gt;./configure&lt;/code&gt;, and then &lt;code&gt;make &amp;&amp; make install&lt;/code&gt;.   If you encounter the error "LIRC modules currently require module unloading...", go back into the kernel source, run "make menuconfig" and select "Loadable Module Support -&gt; Module Unloading" from the menu options.  The run &lt;code&gt;make &amp;&amp; make install&lt;/code&gt; in the kernel source directory, reboot, and try to build LIRC again.&lt;br /&gt;&lt;br /&gt;Once LIRC is built you should follow the instructions at LIRC.org to get the driver up and running.  The quickest way to test the input is like this:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Tell the kernel to release the serial port by running &lt;code&gt;setserial /dev/ttyS1 uart none&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Insert the LIRC serial module into the kernel: &lt;code&gt;modprobe -v lirc_serial&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Run &lt;code&gt;mode2&lt;/code&gt;.  This program should display no output until you start pressing buttons on your remote control.  If it prints values while no buttons are being pressed, you probably have an interference problem.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If you get errors complaining that the device is busy, make sure that you've a) enabled COM2 in the VIA BIOS, b) configured LIRC's setup script with the correct values for COM2, and c) referred to the device &lt;code&gt;/dev/ttyS1&lt;/code&gt;.  I banged my head against the wall for half a day because I didn't twig to the zero-based port numbering.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Then it's just a matter of using &lt;code&gt;irrecord&lt;/code&gt; to generate a .conf file, and starting &lt;code&gt;lircd&lt;/code&gt; with that .conf file.  Those steps are all very well documented at &lt;a href="http://www.lirc.org"&gt;lirc.org&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114090924953479874?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114090924953479874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114090924953479874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114090924953479874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114090924953479874'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/building-and-configuring-lirc.html' title='Building and Configuring LIRC'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114090781477471086</id><published>2006-02-25T13:56:00.000-08:00</published><updated>2006-02-27T09:36:37.446-08:00</updated><title type='text'>IR Remote Control and LIRC</title><content type='html'>&lt;a href="http://www.lirc.org"&gt;LIRC&lt;/a&gt; is a Linux utility that allows input from many common types of remote controls.  It integrates very nicely with XMMS, the media player I've chosen to install on Fulcrum.&lt;br /&gt;&lt;br /&gt;The LIRC website has a bunch of instructions on how to build your own homebrew IR receiver that hooks up to a standard serial port.  From what I understand, it's not "true" serial communication as all the data is transferred over one of the handshake lines, but everything seems to work out OK.&lt;br /&gt;&lt;br /&gt;The schematic that I used is &lt;a href="http://www.lirc.org/images/schematics.gif"&gt;here&lt;/a&gt;.  I ordered all the parts from Digikey, except the breadboard, which I got from a local electronics store.  And the case, which is an Altoids tin. &lt;p&gt;Here's the Digikey parts list:&lt;/p&gt;&lt;div&gt;&lt;table&gt;&lt;br /&gt;&lt;tr&gt;&lt;th&gt;Digikey Part #&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PNA4602M-ND&lt;/td&gt;&lt;td&gt;Infrared photoreciver + IC&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;AN78L05-ND&lt;/td&gt;&lt;td&gt;Voltage Regulator&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;P974-ND&lt;/td&gt;&lt;td&gt;Capacitor - 4.7 uf 25V&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;P4.7KBACT-ND&lt;/td&gt;&lt;td&gt;4.7 kilo-ohm resistor&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;C3APT-1018M-ND&lt;/td&gt;&lt;td&gt;IDC Cable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1N4148DICT-ND&lt;/td&gt;&lt;td&gt;Diode&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;br /&gt;Some notes:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Digikey charges a substantial service fee for orders under $35 (CAD).  So if there's anything else you need, tack in onto the order.  Pick up a few of the voltage regulators and a couple of the IR receivers in case anything goes sideways.  Digikey also sells several similar receivers (PNA4612M00YB-ND, PNA4612M00XD-ND) with metal holders, which may help reduce interference.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I can't say for sure that the diode I've listed above is correct.  I made a mistake and got the surface-mount casing; but I checked the catalog and that looks like the right one.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The pinouts on the IR receiver (substitute for the TSOP1738 in the schematic) and the voltage regulator are different than the ones described on the LIRC homebrew instruction page.  As that page suggests, double-check that you've got them wired correctly.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;One end of the IDC cable I specified above is a perfect fit for the serial header on the SP800 motherboard. The other end can be munged a little bit to fit into a 0.1" printed circuitboard on an angle.  Since I had to visit the local electronics shop anyways, I picked up a proper IDC 16 pin crimp connector and used that instead.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Total costs were $33.60 to Digikey + ~= $10.00 to the local electronics shop.  Definitely more practical to pick up a Windows Media Centre remote + USB receiver (which I believe is compatible with LIRC), but not nearly as much fun.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Assembling the circuit is actually really easy, and I say that as someone with very little experience in electronics.  I'd suggest wiring it up on a solderless breadboard first, especially if you are as unfamiliar with this sort of thing as I was.  Once you're comfortable with how everything hooks together, it's then just a challenge of laying it out on the breadboard with as little soldering as possible.&lt;br /&gt;&lt;br /&gt;This is pretty much how I laid it out on the final breadboard, although I stretched it out a little bit to give myself some more room to work:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/IMG_2257_edited-1.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1286/264/400/IMG_2257_edited-1.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a picture of the final product with the case open:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/IMG_2268.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1286/264/400/IMG_2268.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I added the case (a butchered Altoids Mints container) because I was trying to resolve some interference problems.  These problems only arose while I was working on this at the office, not at home.  The case didn't actually resolve the problem, but I'm  not too worried about it.&lt;br /&gt;&lt;br /&gt;Finally, an up-to-date picture of Fulcrum.  The Altoids case is closed in the picture.  Notice that I have attached a proper momentary contact switch, so I don't have to short the jumpers with the needlenose pliers.  That was fun for a while but got tiring.  Notice also that the ghetto piece of plywood has been replaced with a ghetto piece of 1/16" sheet steel.  However, that piece of steel was taken from a damaged &lt;a href="http://www.cray.com/products/xd1"&gt;Cray XD1&lt;/a&gt;, so I think I score some geek points for that.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/IMG_2257.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/1286/264/400/IMG_2257.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;That covers the hardware.  Next up, building and configuring the software.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114090781477471086?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114090781477471086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114090781477471086' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114090781477471086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114090781477471086'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/ir-remote-control-and-lirc.html' title='IR Remote Control and LIRC'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114064918572916690</id><published>2006-02-22T14:47:00.000-08:00</published><updated>2006-03-21T09:20:01.110-08:00</updated><title type='text'>Building up from Minimal Debian</title><content type='html'>I'm a sucker for punishment, so I've decided to put all my progress on hold for a while and try to rebuild the system from (almost) scratch. The OS was getting a little bloated, and I'd like to keep a tighter rein on what's getting installed. This post is a compilation of several earlier posts, with some extra details added here and there.&lt;br /&gt;&lt;br /&gt;Note that you can skip steps 1 and 2 by burning the Debian businesscard ISO to a CD and configuring your BIOS to boot from CD.&lt;br /&gt;&lt;br /&gt;Note also that I've kept my previous installation on a different partition. If this doesn't work out, I can switch back with a simple change to the GRUB boot menu.&lt;br /&gt;&lt;br /&gt;Finally... building xorg (the X Windows Server) from scratch is really a post unto itself... the documentation for version 6.9.0 is available &lt;a href="http://xorg.freedesktop.org/releases/X11R6.9.0/doc/html"&gt;here&lt;/a&gt;.  If you still have questions I'll do my best to help.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Format a fresh partition with the ext3 file system.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Follow the instructions &lt;a href="http://linuxmedianetwork.blogspot.com/2006/01/installing-debian.html"&gt;here&lt;/a&gt; to load the debian installer.  Briefly,&lt;br /&gt;&lt;code&gt;mkdir /boot/debian-installer&lt;br /&gt;cp businesscard.iso /boot&lt;br /&gt;cd debian-installer&lt;br /&gt;wget http://ftp.debian.org/debian/dists/stable/main/installer-i386/current/images/hd-media/initrd.gz&lt;br /&gt;wget http://ftp.debian.org/debian/dists/stable/main/installer-i386/current/images/hd-media/vmlinuz&lt;br /&gt;edit /boot/menu/grub.lst, add new entry. Recall that the partition numbering is 0-based.&lt;br /&gt;root(0,0)&lt;br /&gt;kernel /boot/debian-installer/vmlinuz ramdisk_size=12000 root=/dev/ram0&lt;br /&gt;initrd /boot/debian-installer/initrd.gz&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Activate the installer by rebooting.&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;accept the defaults up to the screen where you are asked about disk partitioning. Choose to manually edit the partition table. Choose the partition you were just in as the install target. Do not format the partition if you are booting from the hard disk. Specify "/" as the mount point.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Reboot. The installation proceeds. When you are asked about the system's "profile", ie. webserver, desktop, etc. select the packages manually. This launches the aptitude package manager frontend.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Select "&lt;code&gt;kernel-source-2.6.8&lt;/code&gt;" "&lt;code&gt;libncurses5-dev&lt;/code&gt;" "&lt;code&gt;module-init-tools&lt;/code&gt;" "&lt;code&gt;flex&lt;/code&gt;" "&lt;code&gt;bison&lt;/code&gt;" "&lt;code&gt;g++&lt;/code&gt;" "&lt;code&gt;libpam-dev&lt;/code&gt;". You can use the "/" key to open a search box and the "n" key to advance through the search hits. Use the "+" key to select packages for installation. Installing these packages will install a number of ancillary developer tools.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Quit the installer&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;li&gt;Log in as root. (All further steps should be performed as root)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Build a more appropriate kernel as described &lt;a href="http://linuxmedianetwork.blogspot.com/2006/02/debian-post-install.html"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;code&gt;cd /usr/src&lt;br /&gt;tar xvfj kernel-source-2.6.8.tar.bz2 &amp;&amp;amp; rm kernel-source-2.6.8.tar.bz2&lt;br /&gt;cd kernel-source-2.6.8&lt;br /&gt;make menuconfig&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;In the kernel config GUI, select "Processor Type and Features" &gt; "Processor Family" &gt; "VIA C3-2 (Nehemiah)"&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Optionally disable drivers to get faster compile time:  ISDN, Telephony, all graphics drivers except VGA and VESA&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Enabled ALSA (and all its sub-items, and the VIA drivers), Parallel Port Support, PC-Style Hardware&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Exit, save, run &lt;code&gt;make all install modules_install&lt;/code&gt; Wait a long, long time.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Run &lt;code&gt;mkinitrd -o /boot/initrd-2.6.8 2.6.8&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Add new entry to &lt;code&gt;/boot/grub/menu.lst&lt;/code&gt;:&lt;code&gt;&lt;br /&gt;title       Debian 2.6.8&lt;br /&gt;root        (hd0,2)&lt;br /&gt;kernel      /boot/vmlinuz-2.6.8 root=/dev/hda3 ro&lt;br /&gt;initrd      /boot/initrd-2.6.8&lt;br /&gt;savedefault&lt;br /&gt;boot&lt;br /&gt;&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Get and Build the xorg source (for the X server)&lt;br /&gt;&lt;code&gt;cd /usr/local/src&lt;br /&gt;wget http://xorg.freedesktop.org/releases/X11R6.9.0/src-single/X11R6.9.0.tar.bz2&lt;br /&gt;tar xvfj X11R6.9.0.tar.bz2 &amp;&amp;amp; rm X11R6.9.0.tar.bz2&lt;br /&gt;cd xc/config/cf&lt;br /&gt;cp xorgsite.def host.def&lt;br /&gt;# Note: the xorg distribution comes with its dependencies,&lt;br /&gt;# but it does a shitty job building them.  Also, none of the&lt;br /&gt;# executable perms have been set.&lt;br /&gt;cd ../../extras/expat&lt;br /&gt;chmod a+x configure&lt;br /&gt;./configure --prefix=/usr &amp;amp;&amp; make &amp;amp;&amp; make install&lt;br /&gt;cd ../freetype2&lt;br /&gt;chmod a+x configure builds/unix/configure builds/unix/install-sh builds/unix-mkinstalldirs&lt;br /&gt;./configure --prefix=/usr &amp;amp;&amp; make &amp;amp;&amp; make install&lt;br /&gt;cd ../..&lt;br /&gt;make World | tee World.log 2&gt;&amp;amp;1&lt;br /&gt;make install install.man&lt;br /&gt;# Not sure if there's a more correct way to do this&lt;br /&gt;cd /usr/bin&lt;br /&gt;ln -s /usr/X11R6/bin X11&lt;br /&gt;&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Download and build the Openchrome Drivers as described &lt;a href="http://wiki.openchrome.org/tikiwiki/tiki-index.php?page=Compiling+the+source+code"&gt;here&lt;/a&gt;.  If you haven't got a SVN/CVS client, you can download one of the snapshot tarballs from &lt;a href="http://openchrome.org"&gt;openchrome.org&lt;/a&gt;.  Here I have downloaded the source to /usr/local/src.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd /usr/local/src&lt;br /&gt;# Follow directions in README&lt;br /&gt;cd drm/linux-core&lt;br /&gt;make LINUXDIR=/usr/src/kernel-source-2.6.8 DRM_MODULES=via&lt;br /&gt;cp *.ko /lib/modules/2.6.8/kernel/drivers/char/drm/&lt;br /&gt;depmod -ae&lt;br /&gt;export PATH=$PATH:/usr/X11R6/bin&lt;br /&gt;xmkmf /usr/local/src/xc&lt;br /&gt;make &amp;&amp; make install&lt;br /&gt;cd ../unichrome&lt;br /&gt;xmkmf /usr/local/src/xc&lt;br /&gt;&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The DRM and Mesa stuff that's packaged with X.org is a piece of shit.  To install the DRI drivers I had to download the binaries from &lt;a href="http://dri.freedesktop.org/snapshots"&gt;here&lt;/a&gt; (just get the latest VIA drivers).  Extract the tarball and copy &lt;code&gt;unichrome_dri.so&lt;/code&gt; to &lt;code&gt;/usr/X11R6/lib/modules/dri&lt;/code&gt;.  You can follow the directions &lt;a href="http://wiki.openchrome.org/tikiwiki/tiki-index.php?page=3D+driver+troubleshooting"&gt;here&lt;/a&gt; to verify that hardware acceleration is being used.  On GLXGears, the SP800 should be capable of about 30-60fps un-accelerated and approximately 500fps when hardware acceleration is active.&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Download, Build and Install a Window Manager&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Obtain the fluxbox development release source from &lt;a href="http://fluxbox.sourceforge.net"&gt;http://fluxbox.sourceforge.net&lt;/a&gt;. Don't go with the "stable" 0.1.14 release; it doesn't even compile.  ("stable"?!?)&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Extract to &lt;code&gt;/usr/local/src&lt;/code&gt;; Enter fluxbox directory&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;code&gt;./configure --prefix=/usr &amp;&amp; make &amp;&amp; make install&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Edit the file &lt;code&gt;/etc/X11/xinit/xinitrc&lt;/code&gt;.  Remove the lines after "start some nice programs" and replace with:&lt;code&gt;&lt;br /&gt;fluxbox &amp; wmpid=$!&lt;br /&gt;wait $wmpid&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Start the xserver with &lt;code&gt;startx&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114064918572916690?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114064918572916690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114064918572916690' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114064918572916690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114064918572916690'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/building-up-from-minimal-debian.html' title='Building up from Minimal Debian'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114019914620390784</id><published>2006-02-17T09:56:00.000-08:00</published><updated>2006-02-17T09:59:17.020-08:00</updated><title type='text'>Disabling the Ramdisk</title><content type='html'>Setting up the ramdisk as I just described was a little premature, because I'm not quite done with all my software installations yet.  But at least now I know that it's possible.  I can disable the ramdisk until I'm ready with these simple commands:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;init 1&lt;br /&gt;umount /var&lt;br /&gt;mv /var /var_rd&lt;br /&gt;mv /var_orig /var&lt;br /&gt;chmod a-x /etc/init.d/setup_ramdisk&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;That still leaves the ramdisk_size kernel parameter in the GRUB configuration, but since we've disabled the ramdisk creation script that memory won't be consumed, so we're OK.  Might as well leave it as-is, it's one less thing to re-enable when the time comes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114019914620390784?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114019914620390784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114019914620390784' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114019914620390784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114019914620390784'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/disabling-ramdisk.html' title='Disabling the Ramdisk'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-114013502764832204</id><published>2006-02-16T14:56:00.000-08:00</published><updated>2006-02-16T16:10:27.690-08:00</updated><title type='text'>Setting up a Ramdisk</title><content type='html'>Wow, it's been a while since I've updated.  I've been busy building the infrared receiver described here: &lt;a href="http://www.lirc.org/receivers.html"&gt;http://www.lirc.org/receivers.html&lt;/a&gt;.  I'll post more about that once I've got the last few kinks worked out and had a chance to take some pics of it.&lt;br /&gt;&lt;br /&gt;For now, though, I'll describe how I've altered the Linux install to make use of a ramdisk for parts of the filesystem.  A ramdisk is a section of memory that the operating system treats like a regular disk.  One advantage of using a ramdisk instead of a physical disk is that it provides really, really fast read/write times.  A big disadvantage is that anything that you write to a ramdisk gets obliterated when your computer shuts down.&lt;br /&gt;&lt;br /&gt;I'm using a ramdisk in this situation because when I switch Fulcrum over to compact flash, I want it to treat the CF card as a read-only file system.  But because applications expect to be able to write data to &lt;code&gt;/var&lt;/code&gt; and &lt;code&gt;/tmp&lt;/code&gt;, we need to provide some write capability.  We will "graft" the ramdisk onto the root filesystem, and none of the applications will even know they're writing to a ramdisk.&lt;br /&gt;&lt;br /&gt;The linux kernel creates a bunch of ramdisks as soon as it starts, and identifies them as separate devices in the &lt;code&gt;/dev&lt;/code&gt; filesystem.  Do an ls there and you can see them, labelled from &lt;code&gt;/dev/ram0&lt;/code&gt; to &lt;code&gt;/dev/ram15&lt;/code&gt; or so.&lt;br /&gt;&lt;br /&gt;The kernel restricts the size of these ramdisks based on the ramdisk_size kernel parameter.  The value of this parameter is measured in kilobytes, so to define a ramdisk of 128Mb you would pass this as a kernel parameter in the GRUB configuration file, menu.lst:&lt;br /&gt;&lt;code&gt;ramdisk_size=131072&lt;/code&gt;&lt;br /&gt;(131072 = 128 * 1024)&lt;br /&gt;&lt;br /&gt;As far as I know, all ramdisks are created with the same size limit.  If you know of a way to independently specify the size of each ramdisk, I would love to hear about it.&lt;br /&gt;&lt;br /&gt;Let's deal with ram-ifying &lt;code&gt;/var&lt;/code&gt; first.  Obviously, the &lt;code&gt;/var&lt;/code&gt; directory is full of important files and stuff.  We want to:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Backup the whole damn thing&lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;Save these files someplace safe&lt;/li&gt;   &lt;li&gt;Empty out the &lt;code&gt;/var&lt;/code&gt; directory&lt;/li&gt; &lt;/ul&gt; Then, on every boot:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;Tell Linux to move the files from "someplace safe" to the ramdisk&lt;/li&gt;   &lt;li&gt;Mount the ramdisk on &lt;code&gt;/var&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; Here's a quick way to do the backup, presuming you have some unallocated space on your hard disk.  In the example below, my OS is installed on &lt;code&gt;/dev/hda2&lt;/code&gt; and I've created a partition &lt;code&gt;/dev/hda3&lt;/code&gt; that is &lt;span style="font-weight: bold;"&gt;exactly&lt;/span&gt; the same size using &lt;code&gt;fdisk -u&lt;/code&gt;.  (Creating the backup target partition is pretty easy, it just takes a little adding and subtracting to determine the number of sectors and the end point of the partition)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# Do a byte-by-byte backup of /dev/hda2 to /dev/hda3&lt;br /&gt;dd if=/dev/hda2 of=/dev/hda3 bs=16MB&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Lastly, you can go into &lt;code&gt;/boot/grub/menu.lst&lt;/code&gt; and clone the entries there to boot your new partition - or, you can just edit the existing entries by hand if you ever need to boot into that partition.  Remember to change both the &lt;code&gt;root(n,m)&lt;/code&gt; line and the &lt;code&gt;root=/dev/hda(n)&lt;/code&gt; part of the GRUB entry.&lt;br /&gt;&lt;br /&gt;Now that you've got a backup (hey - maybe test that it works, while you're at it), we can proceed with ram-ifying /var.  Follow these commands:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#A flimsy way of "quieting" the system&lt;br /&gt;#to prevent writes to /var while we work&lt;br /&gt;init 1&lt;br /&gt;#relocate the files&lt;br /&gt;mv /var /var_orig&lt;br /&gt;#create the new empty directory&lt;br /&gt;mkdir /var&lt;br /&gt;mkdir /mnt/rd&lt;br /&gt;cd /etc/init.d&lt;br /&gt;#create a script to do the work at every boot&lt;br /&gt;cat setup_ramdisk &lt;&lt; EOF&lt;br /&gt;#! /bin/sh&lt;br /&gt;echo "**** Initializing Ramdisk ****"&lt;br /&gt;mkfs -V -t ext2 /dev/ram1&lt;br /&gt;mount /dev/ram1 /mnt/rd&lt;br /&gt;cp -a /var_orig/* /mnt/rd&lt;br /&gt;umount /mnt/rd&lt;br /&gt;mount /dev/ram1 /var&lt;br /&gt;echo "Ramdisk Created"&lt;br /&gt;EOF&lt;br /&gt;# make it executable&lt;br /&gt;chmod a+x setup_ramdisk&lt;br /&gt;cd /etc/rcS.d&lt;br /&gt;# make it run very early it the boot process&lt;br /&gt;ln -s /etc/init.d/setup_ramdisk S03setup_ramdisk&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The script that's embedded in those commands is actually what's responsible for most of the heavy-lifting (it's saved to &lt;code&gt;/etc/init.d/setup_ramdisk&lt;/code&gt;).  What it does is format the ramdisk using the ext2 file system, mount it to a temporary directory, copy all the stuff from the original &lt;code&gt;/var&lt;/code&gt; directory, and then move the mount point from the temporary directory to &lt;code&gt;/var&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;At this point, double check that you've allowed for a big enough ramdisk in the kernel parameter.  Do a &lt;code&gt;df --si /var&lt;/code&gt;, grow that number by, say, 20%, and convert that to kilobytes and enter it into &lt;code&gt;/boot/grub/menu.lst&lt;/code&gt; as described above.&lt;br /&gt;&lt;br /&gt;Reboot, cross your fingers, and hopefully you won't even notice the difference!&lt;br /&gt;&lt;br /&gt;If something goes wonky and your system won't boot, select your backed-up partition from the GRUB boot menu.  Then mount the original parition and check for any mistakes.  The messages during boot will tend to fly past before you can read them, so it may be very helpful to include a "&lt;code&gt;sleep 60&lt;/code&gt;" command just after the "Ramdisk Created" line in the setup_ramdisk script.&lt;br /&gt;&lt;br /&gt;I'm going to assume that everything has gone swimmingly and you've now got linux using a ramdisk for &lt;code&gt;/var&lt;/code&gt;.  The last step is to get it to use a ramdisk for &lt;code&gt;/tmp&lt;/code&gt; as well.&lt;br /&gt;&lt;br /&gt;I ran into a problem here.  Because every ramdisk is the same size, and I need roughly 100Mb for &lt;code&gt;/var&lt;/code&gt;, I didn't have enough free memory to create a whole new ramdisk for &lt;code&gt;/tmp&lt;/code&gt;, which only needs a little bit anyways.   The easiest workaround here is to just symbolically link &lt;code&gt;/tmp&lt;/code&gt; to &lt;code&gt;/var/tmp&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;init 1&lt;br /&gt;rm -rf /tmp&lt;br /&gt;ln -s /var/tmp&lt;br /&gt;chmod a+rw /tmp&lt;br /&gt;chmod a+rw /var_orig/tmp&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Make sure you get the permissions right, or nobody but root will be able to do very much.&lt;br /&gt;&lt;br /&gt;Let me know how that works for you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-114013502764832204?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/114013502764832204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=114013502764832204' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114013502764832204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/114013502764832204'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/setting-up-ramdisk.html' title='Setting up a Ramdisk'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113952222231013051</id><published>2006-02-09T13:51:00.000-08:00</published><updated>2006-02-09T13:57:02.320-08:00</updated><title type='text'>LIRC: Help!</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/space_on.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/1286/264/400/space_on.jpg" alt="" border="0" /&gt;&lt;/a&gt;The above graph shows the 'space' values when I activate my remote control. Note that the noise around the 2000-level is constantly displayed during mode2.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/pulse_on.0.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/1286/264/400/pulse_on.0.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The above graph shows the 'pulse' values for the same scenario.  Again, the noise around the 2000-level is constantly printed during mode2.&lt;br /&gt;&lt;br /&gt;Any ideas, please contact me.  My name is Russ, you can reach me at [my name] at razorwire.ca&lt;br /&gt;&lt;br /&gt;ps. Sorry that the colors got wanged.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113952222231013051?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113952222231013051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113952222231013051' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113952222231013051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113952222231013051'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/lirc-help.html' title='LIRC: Help!'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113883657464138876</id><published>2006-02-01T15:26:00.000-08:00</published><updated>2006-02-01T15:43:35.230-08:00</updated><title type='text'>Getting GUI (step 2)</title><content type='html'>What the hell, let's throw caution to the wind and just go with &lt;a href="http://www.gnome.org"&gt;GNOME&lt;/a&gt;. It's a robust, widely supported GUI, although it's a little heavier than I'd like. Perhaps we can slim it down once we've got everything set up, but even if we can't, I think we'll still be well under 1Gb.&lt;br /&gt;&lt;br /&gt;Installing GNOME is as easy as:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;apt-get -t sarge-backports install x-window-system-core gnome-session gnome-applets nautilus metacity xscreensaver gdm gedit gnome-terminal&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Reboot (or simply &lt;code&gt;startx&lt;/code&gt;), and you're done.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/debian-fulcrum.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/1286/264/320/debian-fulcrum.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113883657464138876?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113883657464138876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113883657464138876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113883657464138876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113883657464138876'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/getting-gui-step-2.html' title='Getting GUI (step 2)'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113883457117038001</id><published>2006-02-01T14:41:00.000-08:00</published><updated>2006-02-01T14:56:11.180-08:00</updated><title type='text'>Getting GUI (step 1)</title><content type='html'>The first step to getting a GUI (a window manager, actually) is to install an X server.  With Debian, you can choose from at least 2 X servers: Xfree86 or Xorg.  Xfree86 is the more popular choice, but we will need the Xorg server to be able to compile the driver for our on-board graphics card.&lt;br /&gt;&lt;br /&gt;The biggest obstacle here is that the Xorg packages are listed as "experimental" and are not readily available with the standard configuration of apt-get.  So, follow the instructions &lt;a href="http://backports.org/instructions.html"&gt;here&lt;/a&gt; to gain access to these experimental packages.  Skip the bit between "To activate a package..." and "...as usual".  It's much easier to just use the -t option to apt-get when you want to install one of the experimental packages.&lt;br /&gt;&lt;br /&gt;Download the xserver-xorg package by running &lt;code&gt;apt-get -t sarge-backports xserver-xorg&lt;/code&gt;.  You can accept all the defaults for the X configuration process and just choose the "Vesa" driver for the graphics card.&lt;br /&gt;&lt;br /&gt;Download the corresponding source code - we'll need this when we come to building the video driver.  I don't think there's a Debian package for this code, so we'll have to download it the old fashioned way.  Currently the xserver-xorg package is 6.9.0 and the corresponding source is available &lt;a href="http://xorg.freedesktop.org/releases/X11R6.9.0/src-single/X11R6.9.0-src.tar.gz"&gt;here&lt;/a&gt;.  You can check the version of your xserver-xorg package in aptitude.  Expand this file into /usr/local/src.&lt;br /&gt;&lt;br /&gt;If you check the disk space with &lt;code&gt;df --si /&lt;/code&gt;, you'll see that we're up at around 1.2Gb.  At first blush, this is pretty bad.  But do a &lt;code&gt;df&lt;/code&gt; on &lt;code&gt;/usr/src&lt;/code&gt; and &lt;code&gt;/usr/local/src&lt;/code&gt;, and you'll see that over 750Mb of that is just source code, which will be removed long before we cut over to compact flash.  So we're actually doing OK.&lt;br /&gt;&lt;br /&gt;Now that we've got the X server up we just need a Window Manager.  That'll be the next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113883457117038001?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113883457117038001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113883457117038001' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113883457117038001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113883457117038001'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/getting-gui-step-1.html' title='Getting GUI (step 1)'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113883327815917617</id><published>2006-02-01T14:08:00.000-08:00</published><updated>2006-02-01T14:39:37.816-08:00</updated><title type='text'>Debian Post-Install</title><content type='html'>The more I use Debian, the more I like it. &lt;code&gt;apt-get&lt;/code&gt; is a &lt;span style="font-weight: bold;"&gt;really&lt;/span&gt; powerful package management tool. The minimal install is a bit larger than I'd like, around 250Mb, but I've basically resigned myself to getting a bigger compact flash card, so it's not that big a deal. As long as I can keep it under 1Gb, I should be OK.&lt;br /&gt;&lt;br /&gt;Here's how I customised the standard Debian install:&lt;br /&gt;&lt;br /&gt;I got the installer onto the hard disk as described &lt;a href="http://linuxmedianetwork.blogspot.com/2006/01/installing-debian.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I accepted all the defaults, the only tricky bit was to manually edit the partition table and force the install into one of my 2Gb partitions. That's just a matter of selecting the partition, specifying the file system you wish (I went with ext3), and setting it to be the root (/) mount point.&lt;br /&gt;&lt;br /&gt;After the installer reboots, the last step in the installation process is to choose which "profile" you would like to set up the system with: file server, print server, web server, desktop, etc. The last option is to perform the package selection manually using aptitude, a frontend for apt-get. I went with that, and then promptly quit it without selecting any packages. This minimal install weighs in at 246Mb.&lt;br /&gt;&lt;br /&gt;It's not quite suitable, though. The installer decided to use the i386 kernel, which is compatible with the VIA C3 chip, but doesn't take advantage of all its features. The modern (2.6.8) kernel has a special configuration for this chip, it's just a matter of specifying it at build-time. So let's build a fresh kernel.&lt;br /&gt;&lt;br /&gt;The first thing to do is drag down the necessary packages via apt-get. This is going to incur another couple hundred megs of disk usage, but we can get rid of it all when we're done:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;apt-get install kernel-source libncurses5-dev&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Then, go into the &lt;code&gt;/usr/src&lt;/code&gt; directory and expand the &lt;code&gt;.tar.bz2&lt;/code&gt; file:&lt;br /&gt;&lt;code&gt;tar xfvj kernel-source-2.6.8.tar.bz2&lt;/code&gt;&lt;br /&gt;Then in the directory that just got created:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;make mrproper menuconfig&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This brings up the kernel configuration GUI. Under "processor family" select VIA C3-2 (Nehemiah). Exit. Save when prompted. Next, enter:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;make install modules_install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And go get some coffee. Take a long lunch. Wash your car. Seriously. This will take about 3 hours, and 98% of this time will be spent compiling drivers for ISDN cards and SCSI devices and a whole host of other crap you don't need. If you know of a way to speed up this process, I'd love to know.&lt;br /&gt;&lt;br /&gt;So far we've built and deployed the kernel and all the necessary kernel modules for the C3 chip. The penultimate step is to build a new initrd image:&lt;br /&gt;&lt;pre&gt;mkinitrd -o /boot/initrd.img-2.6.8 2.6.8&lt;/pre&gt;&lt;br /&gt;And finally, to add the entries in the GRUB boot menu to boot our wonderful new creation:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;title  Debian GNU/Linux, kernel 2.6.8&lt;br /&gt;root  (hd0,1)&lt;br /&gt;kernel  /boot/vmlinuz-2.6.8 root=/dev/hda2 ro&lt;br /&gt;initrd  /boot/initrd.img-2.6.8&lt;br /&gt;savedefault&lt;br /&gt;boot&lt;br /&gt;&lt;br /&gt;title  Debian GNU/Linux, kernel 2.6.8 (recovery mode)&lt;br /&gt;root  (hd0,1)&lt;br /&gt;kernel  /boot/vmlinuz-2.6.8 root=/dev/hda2 ro single&lt;br /&gt;initrd  /boot/initrd.img-2.6.8&lt;br /&gt;savedefault&lt;br /&gt;boot&lt;/pre&gt;&lt;br /&gt;Note that your value for the root parameter may vary - details explained &lt;a href="http://linuxmedianetwork.blogspot.com/2006/01/linux-is-beefy.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Don't expect anything fancy when you reboot - there's still no X server or window manager.  I'll get to those next.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113883327815917617?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113883327815917617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113883327815917617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113883327815917617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113883327815917617'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/02/debian-post-install.html' title='Debian Post-Install'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113866939615089095</id><published>2006-01-30T16:55:00.000-08:00</published><updated>2006-01-30T17:03:16.160-08:00</updated><title type='text'>Installing Debian</title><content type='html'>Installing DSL went fine, but I wanted to take a little side-track and setup Debian on Fulcrum (Via Epia SP800).  I have a feeling that the drivers for the CN400 chipset, which can help out in the video decoding, will be better supported under Debian.&lt;br /&gt;&lt;br /&gt;I thought that installing Debian without a CD would just take a similar sort of jiggery-pokery as installing DSL or SUSE from one partition to another.  Unfortunately, the default Debian installer is hard-coded to look for a CD-ROM drive and will refuse to load its packages from anywhere else.  Once I figured out the necessary steps, it was pretty straightforward:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt; Download the "business card" &lt;a href="http://cdimage.debian.org/debian-cd/3.1_r1/i386/iso-cd/debian-31r1a-i386-businesscard.iso"&gt;network install CD&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;RTFM: see sections 4.5 and 5.1.2 and 6.3.1.5 of &lt;a href="http://www.debian.org/releases/stable/i386/"&gt;Debian Install Guide&lt;/a&gt;&lt;/li&gt;   &lt;li&gt;In a clean partition, create /boot/newinstall.  Copy vmlinuz and initrd.gz from&lt;a href="http://ftp.debian.org/debian/dists/stable/main/installer-i386/current/images/hd-media"&gt; here&lt;/a&gt; to /boot/newinstall.  Copy businesscard.iso from step one to /boot.&lt;/li&gt;   &lt;li&gt;Add new entry to GRUB configuration:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;title  New Install&lt;br /&gt;kernel (hd0,3)/boot/newinstall/vmlinuz root=/dev/ram0 ramdisk_size=12000&lt;br /&gt;initrd (hd0,3)/boot/newinstall/initrd.gz&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Accept all defaults in installer.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113866939615089095?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113866939615089095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113866939615089095' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113866939615089095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113866939615089095'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/01/installing-debian.html' title='Installing Debian'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113830170635579581</id><published>2006-01-26T10:42:00.000-08:00</published><updated>2006-01-26T10:55:06.366-08:00</updated><title type='text'>Installing DSL</title><content type='html'>At this point, Fulcrum is running a LiveCD version of Damn Small Linux 2.0. Creating an actual hard disk installation is pretty easy. When DSL boots to the desktop, right-click on any blank space and select Apps&gt;Tools&gt;Install to Hard Drive. Specify the target partition, in this case, &lt;span style="font-family:courier new;"&gt;hda3&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;It asks a few other questions that are irrelevant for our purposes. I disabled multi-user logins and enabled the ext3 filesystem. I said no when it offered to configure GRUB, just because I'm not sure how nicely it will play with the boot loader we already configured. So after the install, I went into the &lt;span style="font-family:courier new;"&gt;menu.lst&lt;/span&gt; file I'd already set up and added a new entry:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;###dsl-2.0###&lt;br /&gt;title Damn Small Linux 2.0&lt;br /&gt;   root (hd0,2)&lt;br /&gt;   kernel /boot/linux24 root=/dev/hda3 quiet vga=794 noacpi noapm nodma noscsi frugal&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The entire menu.lst file is available &lt;a href="http://backfire.razorwire.ca/public/menu.lst"&gt;here&lt;/a&gt;.  It contains two entries, one for the LiveCD and one for the proper install.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113830170635579581?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113830170635579581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113830170635579581' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113830170635579581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113830170635579581'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/01/installing-dsl.html' title='Installing DSL'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113822556350859701</id><published>2006-01-25T13:37:00.000-08:00</published><updated>2006-01-25T13:55:47.823-08:00</updated><title type='text'>Changing the Hostname</title><content type='html'>The &lt;a href="http://www.damnsmalllinux.org/wiki/index.php/Changing_the_Hostname"&gt;DSL Wiki&lt;/a&gt; has a thorough article about how to permanently change a machine's hostname. It's the last two steps, the mailname and the knoppix-specific stuff, that I was unaware of.  Note that a different page on that Wiki suggests using the boot parameter "host=&lt;hostname&gt;" or "dslhost=&lt;hostname&gt;" to set the host name.  That don't work, at least not in 2.0.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113822556350859701?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113822556350859701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113822556350859701' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113822556350859701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113822556350859701'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/01/changing-hostname.html' title='Changing the Hostname'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113815278367661441</id><published>2006-01-24T16:33:00.000-08:00</published><updated>2006-01-24T17:33:03.706-08:00</updated><title type='text'>Linux is Beefy</title><content type='html'>I'm not sure if the aphorism "Linux is Beefy" means anything outside of Cray Canada.  BEFE is the post code we use to indicate that the kernel is up and running, that the boot sequence is effectively complete.  I've just reached this point with Fulcrum.  Herewith, a description of how it got there.&lt;br /&gt;&lt;br /&gt;I've picked &lt;a href="http://www.damnsmalllinux.org"&gt;Damn Small Linux&lt;/a&gt; as the distro for this machine.  It's a compact, full-featured distribution that I've had some good luck with so far.  As a LiveCD - a "self-sufficient" CD that can be used to boot a computer - it fits into 50Mb.  As an installed operating system, I believe it can squeeze into around 200Mb.&lt;br /&gt;&lt;br /&gt;Now, I don't have a spare CD drive to hook up to Fulcrum, and even if I did, the tricky route is a lot more interesting and educational.  Fortunately, I have a Linux workstation to help with the task.&lt;br /&gt;&lt;br /&gt;The first step is to get the hard disk into a system where I can lay out and format the partitions just the way I want them.  So I plugged the drive into my desktop PC, which runs SUSE 10.0 and had a free IDE channel.&lt;br /&gt;&lt;br /&gt;I used the &lt;span style="font-family: courier new;"&gt;parted&lt;/span&gt; utility to create three primary partitions.  The first was 1GB and the second and third were 2GB each.   The first partition will be used to hold the images for the boot loader (1GB is way, way too much here, but it doesn't really matter).  The second partition will hold the LiveCD ISO and the third partition will hold the actual installation.&lt;br /&gt;&lt;br /&gt;Installing the boot loader was a little harder than it should have been.  First, I created three mount points for the partitions and mounted them:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mkdir /mnt/fulcrum&lt;br /&gt;mkdir /mnt/fulcrum/grub&lt;br /&gt;mkdir /mnt/fulcrum/iso&lt;br /&gt;mkdir /mnt/fulcrum/os&lt;br /&gt;mount /dev/hdc1 /mnt/fulcrum/grub&lt;br /&gt;mount /dev/hdc2 /mnt/fulcrum/iso&lt;br /&gt;mount /dev/hdc3 /mnt/fulcrum/os&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then I ran the grub-install command to install the boot loader on the disk:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;grub-install --root-directory=/mnt/fulcrum/grub /dev/hdc&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, as far as I know, what this should do is install GRUB boot loader into the master boot record of the disk, and install all the extra GRUB data into the /dev/hdc1 partition.  But I got an error message that looked a lot like a disk error when I tried that... something like "unable to read stage1 file".&lt;br /&gt;&lt;br /&gt;Looking at the newly-created directory tree, it was pretty apparent that some files were missing from &lt;span style="font-family: courier new;"&gt;/mnt/fulcrum/grub/boot/grub&lt;/span&gt;.  So I cleaned out the partition and just copied over the entire &lt;span style="font-family: courier new;"&gt;/boot&lt;/span&gt; directory into &lt;span style="font-family: courier new;"&gt;/mnt/fulcrum/grub&lt;/span&gt;.  What this means is, I took SUSE's &lt;span style="font-family: courier new;"&gt;/boot&lt;/span&gt; directory and all the GRUB data it uses and cloned it for Fulcrum.&lt;br /&gt;&lt;br /&gt;I tweaked the device.map file a little bit - it's fairly self-explanatory and pretty well documented online - and also added a fresh entry to boot the DSL LiveCD, which we're about to install.  The new entry looks like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;###dsl-2.0-live###&lt;br /&gt;title Damn Small Linux 2.0 LiveCD&lt;br /&gt;    root (hd0,1)&lt;br /&gt;    kernel /boot/isolinux/linux24 root=/dev/hdb6 init=/etc/init lang=us vga=normal BOOT_IMAGE=knoppix&lt;br /&gt;    initrd /boot/isolinux/minirt24.gz&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This tells GRUB to look in the 1'th partition for the Damn Small Linux kernel and initrd image.  I believe GRUB numbers disks and partitions starting from 0, so this corresponds to the partition we called /dev/hdc2 above.&lt;br /&gt;&lt;br /&gt;The last step is to actually get the Damn Small Linux LiveCD into that partition, which is empty right now.  This is fairly straightforward.  First, we mount the LiveCD iso (which I had downloaded earlier via BitTorrent from damnsmalllinux.org):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mkdir /tmp/dsl2&lt;br /&gt;mount -o loop /usr/local/downloads/dsl-2.0.iso /tmp/dsl2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then we copy the contents into the empty partition:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cp -R /tmp/dsl2/* /mnt/fulcrum/iso&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And that's it!  At this point I shut down my desktop PC, removed the hard drive, and connected it back to Fulcrum.  DSL booted successfully and asked me a couple questions related to video and mouse configuration, and that was it.&lt;br /&gt;&lt;br /&gt;So now what we have is a fake LiveCD distribution.  It's running Linux, sure, but it's basically treating the hard drive as a read-only file system and making all its changes in a ramdisk.  That's sub-optimal, because none of our configuration changes will be saved next time we reboot.&lt;br /&gt;&lt;br /&gt;The next step is to install the operating system to that third partition we created and really get to work setting up this media center.  After that, we can start to think about cutting over to the compact flash and getting rid of this hard disk entirely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113815278367661441?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113815278367661441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113815278367661441' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113815278367661441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113815278367661441'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/01/linux-is-beefy.html' title='Linux is Beefy'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113814876943214443</id><published>2006-01-24T16:20:00.000-08:00</published><updated>2006-01-24T16:31:02.003-08:00</updated><title type='text'>It Boots!</title><content type='html'>I just got Fulcrum (the client node) to boot. It would've been easier if I had a proper case rigged up for it. Since it's just sitting on a cheesy piece of plywood right now, I had to jumper pins 6 and 8 on the F_PANEL pin array. This is described on page 26 (actually page 34) of the &lt;a href="http://www.via.com.tw/download/mainboards/3/4/EPIA-SP_v100.pdf"&gt;manual&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The only trick is that these pins should be hooked up to a &lt;span style="font-weight: bold;"&gt;momentary contact&lt;/span&gt; switch - which makes sense. Think about the power button on your PC: you push it in, it pops right back out, and your PC starts to boot. So to simulate that behaviour without a switch, you just need to short the two pins briefly. I used a pair of needlenose pliers to push the jumper down and then immediately pull it off. Thanks to Brian for pointing this out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113814876943214443?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113814876943214443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113814876943214443' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113814876943214443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113814876943214443'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/01/it-boots.html' title='It Boots!'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113805979569162059</id><published>2006-01-23T15:28:00.000-08:00</published><updated>2006-01-23T16:22:38.543-08:00</updated><title type='text'>The Hardware</title><content type='html'>As I mentioned in the &lt;a href="http://linuxmedianetwork.blogspot.com/2006/01/introduction.html"&gt;intro&lt;/a&gt;, our little media network will initially have two nodes.&lt;br /&gt;&lt;br /&gt;First, the server, which we shall christen "&lt;a href="http://en.wikipedia.org/wiki/Tupolev_Tu-22M"&gt;Backfire&lt;/a&gt;", because it is large, loud, and ungainly:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/backfire.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/1286/264/320/backfire.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Wow.  Okay, so the labelling didn't turn out so good.  Anyways, these are some of the components:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;&lt;a href="http://www.antec.com/us/productDetails.php?ProdID=94552"&gt;Antec 4U Rackmount&lt;/a&gt; (no, I don't have a rack in my house. But I have a sturdy shelf, and a large storage space under the stairs. It'll do, for now...)&lt;/li&gt;   &lt;li&gt;Dual Opteron 248's. This server is going to be doing a lot of stuff other than acting as a server for this project. These 64-bit processors ought to give it plenty of horsepower.&lt;/li&gt;   &lt;li&gt;The cheapest PCI-express video card I could find. This thing will be running headless, so I just needed the video card to get it set up. I believe it's an &lt;a href="http://www.nvidia.com/page/geforce6200_agp.html"&gt;NVidia 6200&lt;/a&gt;.&lt;/li&gt;   &lt;li&gt;The motherboard, a &lt;a href="http://www.tyan.com/products/html/thunderk8we.html"&gt;Tyan Thunder K8WE&lt;/a&gt; (minus the SCSI controller).  Stocked with 2Gb of PC3200 RAM, or 1Gb per processor.&lt;/li&gt; &lt;/ol&gt;&lt;br /&gt;This stuff isn't cheap - at least, not on my budget. But I got a sweet deal on the processors and the RAM, and the rest of the gear came to about $900CAD total. You could definitely save a few hundred bucks and go with a cheaper motherboard, for instance the &lt;a href="http://www.asus.com/products4.aspx?modelmenu=1&amp;model=456&amp;amp;amp;amp;amp;amp;l1=9&amp;l2=39&amp;amp;l3=174"&gt;ASUS K8N-DL&lt;/a&gt;. I went with the Tyan 'cause it's got a little more room for expandability. And the rackmount ... well, that's a bit of an extravagance. But I've always wanted a rackmount.&lt;br /&gt;&lt;br /&gt;The first client in this network will be a Mini-ITX based PC, which we shall name "&lt;a href="http://en.wikipedia.org/wiki/Mikoyan_MiG-29"&gt;Fulcrum&lt;/a&gt;" because... well, because I like that name.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/1286/264/1600/IMG_2103_edited-1.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/1286/264/320/IMG_2103_edited-1.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;(Sharpie provided for scale)&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;   &lt;li&gt;The centrepiece of this computer is the &lt;a href="http://www.logicsupply.com/product_info.php/products_id/306"&gt;Via EPIA SP800 motherboard&lt;/a&gt;, an 800Mhz motherboard with onboard LAN, Video, TV-out, and sound in a 17cmx17cm form factor.  I strongly recommend the folks at &lt;a href="http://www.logicsupply.com"&gt;Logic Supply&lt;/a&gt; as a source for this part - they were great to me even when some trouble arose with shipping that was not at all their fault.  The SP800 is currently the fastest fan-less motherboard Via makes.  As I mentioned, one of the goals of this system is to have no moving parts. &lt;br /&gt;   &lt;br /&gt;Another advantage to the SP800 is that it has some hardware built-in to help out with video and audio encoding/decoding.  This means that the CPU doesn't have to busy itself with these tasks, and will be available to do other stuff while we're watching a movie or playing an MP3.&lt;br /&gt;   &lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;Power is supplied to the board by a 60W DC-DC converter and a 12VDC power supply.  This is the Morex 60W kit available from &lt;a href="http://www.logicsupply.com"&gt;Logic Supply&lt;/a&gt;.&lt;br /&gt;   &lt;br /&gt; &lt;/li&gt;   &lt;li&gt;512 Mb of PC3200 RAM.  Because I hope to construct a read-only file system (I'll get to that in a minute), it would be good to have as much RAM as possible.  The SP800 supports up to 1Gb but I only had a 512Mb stick lying around.&lt;br /&gt;   &lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;A Compact Flash/IDE adaptor.  This is also available from Logic Supply (those guys are great, did I mention that?)  The idea here is to load the operating system up onto a compact flash card and have the computer treat it just like a regular hard drive.  But because compact flash only supports a limited number of write cycles (granted, a &lt;span style="font-weight: bold;"&gt;large&lt;/span&gt; number), we need to make it read-only.&lt;br /&gt;   &lt;br /&gt;  &lt;/li&gt;   &lt;li&gt;A hard drive cage, with a 6Gb hard drive inside.  We'll use this disk to get everything set up, and only cut over to the compact flash at the last minute.&lt;/li&gt; &lt;/ol&gt;&lt;br /&gt;Well, that's what we've got to work with!  Let's see how far we can get...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113805979569162059?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113805979569162059/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113805979569162059' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113805979569162059'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113805979569162059'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/01/hardware.html' title='The Hardware'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113805856612818558</id><published>2006-01-23T15:12:00.000-08:00</published><updated>2006-01-23T15:22:46.136-08:00</updated><title type='text'>Introduction</title><content type='html'>This blog is an ongoing journal of my attempt to build a digital media network.  The rough idea goes like this:&lt;br /&gt;&lt;br /&gt;I will have a media server in my basement, located in a spot where it can make as much noise as it wants.  This computer will host all my digital photos (roughly 3600 ~ 8Gb worth), all my movies (which, depending on compression, could easily break 1Tb), all my MP3's (about 20Gb), and any digital video I choose to capture (probably from a combination of cable TV and my in-laws' camcorder).&lt;br /&gt;&lt;br /&gt;In addition to this, I will have at least one "client" computer, which will display media from the server.  The primary requirement for this computer is that it be &lt;span style="font-weight: bold;"&gt;quiet&lt;/span&gt;.  Secondary requirements are:&lt;br /&gt;&lt;ul&gt;   &lt;li&gt;No moving parts (so I can leave it on all the time without wearing out fan bearings, drive motors, etc) - this obviously relates to the noise level.&lt;/li&gt;   &lt;li&gt;Cheap!  I want to put one of these in the living room, in the rec room, in the bedrooms, etc.&lt;/li&gt; &lt;/ul&gt;&lt;br /&gt;I expect there are a lot of people that would like to have a setup like this, so hopefully this site can become a useful resource.  My contact info can be found in the "About" section that shows up on all pages; if you have any questions that aren't answered on the site please don't hesitate to ask.&lt;br /&gt;&lt;br /&gt;Russ&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113805856612818558?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113805856612818558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113805856612818558' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113805856612818558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113805856612818558'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/01/introduction.html' title='Introduction'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-21410781.post-113805581172015788</id><published>2006-01-23T14:35:00.000-08:00</published><updated>2006-01-23T14:36:51.726-08:00</updated><title type='text'>Just getting started...</title><content type='html'>First post, just figuring stuff out.  Finding my blog-legs, as it were.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/21410781-113805581172015788?l=linuxmedianetwork.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://linuxmedianetwork.blogspot.com/feeds/113805581172015788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=21410781&amp;postID=113805581172015788' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113805581172015788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/21410781/posts/default/113805581172015788'/><link rel='alternate' type='text/html' href='http://linuxmedianetwork.blogspot.com/2006/01/just-getting-started.html' title='Just getting started...'/><author><name>Russ Weeks</name><uri>http://www.blogger.com/profile/13378665170311903751</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
