October 25, 2007

My experiment with Mythtv

I love my tivo. I've added a big disk to it. But I want to see more of my "personal media" on the tv (pictures, movies, etc) so I decided to make a Mythtv box.

I made a nice new pc in a "stereo cabinet like" box. I used a motherboard with built in HDMI output (very nice) and a 64 bit AMD cpu. I got all this from Mwave.

  • Motherboard: BIOSTAR TF7050-M2 nVIDIA GeFORCE 7050PV CHIPSET MICRO ATX
  • Box: ANTEC NSK2400 (BLACK / SILVER) MICRO ATX DESKTOP CASE

And of course I stuffed a dvd cdrom drive and a huge SATA disk drive.

Using a motherboard with HDMI out was key, becauase I just bought a big lcd hdtv.

When it arrived installed Ubuntu using this page:

MythTV_Feisty_Backend_Frontend

I bought a Tivo remote control because everyone in my house knows how to use one. I got it from WeaKnees. I love the stuff they sell.

I then found I had an "IR problem". I solved it with a USBUIRT device, which I also love. Get the one with the 56k detector. It "just worked".

Interesting bits:

- I found a tivo control file which described the tivo remote. And then I had to hack the mapping file quite a bit to get it to be the way I wanted.

- Support for the nvidia chipset was not in the kernel. I used an install package from Nvidia which was scary. But it did provide a nice X windows based config tool which turned out to be handy.

(X windows looks *really* nice on my hdtv. It makes me thing my next monitor for my office will be a 40" lcd hdtv. why not? huge screen!)

- DVD's did not "just play" by default. Instead I got odd /dev/hdc i/o errors. I asked a friend (thanks Bill!) and installed a few missing DVD decode packages. apt-get to the rescue. It then worked fine. I thought for a 1/2 day I had a bad cd-rom drive.

Result:

After many apt-gets and much twiddling I now have a nice Mythtv box which responds to a tivo remote. I can view my video and pictures and watch Jim Lehrer on the big screen (my record list is only PBS and F1 on Speed :-)

I may still get a HD Tivo, but the MythTv is a very nice adjunct and allows me to do things in a nice linuxy way with my home media. I plan to try firewire next and if that works ok I may skip the tivo hd...

March 18, 2007

Modifying read-only file systems in an embedded system

It's often a good idea to make the root file system in a embedded system read-only. If you do this and only make changes to files in a ram disk (mounted under /tmp, for example) the device will always come back to a known state when powered up. This is a nice feature and often a requirement.

But sometimes you need to make changes which persist. Check out the "mini fan out" file system. It allows you to layer changes on top of a read-only file system.

I have not used this package directly, but I plan to shortly.

Firefox bookmarks

Just a quick note on bookmarks. I use several laptops, a common machine at home and a workstation at work. This can sometimes get confusing when I save web bookmarks in various different places.

I recently discovered "foxmarks". I only used Firefox, and foxmarks is an extension which syncs up my bookmarks everyplace I install it. It's very handy.

I also discovered "gmarks", which places the bookmarks in a window on the left makes them easy to use. I'm still on the fence with gmarks

Sometimes I wish there was a way to make cross platform "notebooks" with firefox, which would combine a directory tree under SVN control, bookmarks, pdf and an email folder all into one. And make it easy to archive.

December 2, 2006

RCU in the linux kernel; an alternative to reader-writer locks

I ran into something in the announcement of the 2.6.19 kernel called "sleepable rcu". I found this wikipedia entry for rcu. It gives some nice background on rcu's.

I don't normally place much credence in wikipedia pages but this one seems reasonably good. And it explains why RCU's are a better alternative to multiple-reader-single-writer locks.

You don't care about this unless you're doing low level work on multiple CPU systems, which I do from time to time. I'm working on several at them moment, each small.

I'm new to rcu's but they look like a very low cost way to manage updates to high(er) contention data items which are updated (note the work "generations" in the wiki). This concept looks a lot like various academic techniques I've read about over they years to create safe software locks.

November 15, 2006

VPS - virtual linux at an ISP

Why VPS?

I had some problems with my colocated serve the other day so I thought I'd try out one of the "VPS" server companies. These are firms which sell "virtual linux", basically a virtual machine running on their hardware. It's a good idea if the hardware is located at a data center with backup power and multiple high speed internet connections.

But if you do some research you find out that many of these have a poor reputation. I wanted to find one one on the east coast which limited the field - many of the better ones are in southern California.

For the purposes of this discussion, "VPS" means a virtual server running Linux which makes use of Xen. It's being commercialized here.

Signing up for VPS

So, as an experiment, I signed up for three of them, vpsland, unixshell# and LeeWare Development.

All of them happily took my credit card and sent me automated email. But then nothing happened.

unixshell came back first with a machine - overnight - which is not bad. But the certificate on their billing web server is expired and 6 months old which does not fill me with confidence. I then followed their instructions to install a distro and boot. The install worked but the vm would not boot. And (apparently) no way to see why. I sent email. Nothing happened.

After 24 hours I opened a ticket on vpsland. Nothing happened.

LeeWare responded to email very quickly. They said they don't have any free Centos machine but I could use FC6. So, I agreed.

We'll see how this ends up. So far it's not a great picture.

1/2 a day passes
LeeWare came back first. I had to pick FC6 instead of Centos because they didn't have any machine free. But they did get the machine up and it seems fast and responsive. I've been installing things.

No word from vpsland or unixshell. My open tickets are unmodified.

(very late in the evening)
I got an email from a support person at unixshell describing all the problems they had setting up my account. They did finally get it going and it's working fine. Despite the late hour I start installing things.

(one night passes)
Over night someone a vpsland woke up and started setting up my account. This morning I could log in and start setting things up.

So, now all 3 are up and all within the promised "24-48 hours". Well, at least vpsland promised that. We'll see how the install/reboot/test cycle goes next.

Remembering the Original Goal

(several days pass)
Ok, everyone is up and I've gotten good at cloning my 4 services. Just to review, I am trying to run a web site with these services:

  • DNS - named as a master and slave to several domains
  • MAIL - qmail running as relay for several domains
  • WEB - apache 2.0 serving static pages and as a caching proxy to a little lisp based web server.
  • LIST - mailman running a very slow mailing list

I managed to clone my existing colocated server to 3 vps sites. All were up and running after a few days of fooling around. I was able to get all the services up with only a few problems.

Good things I found

  • yum
  • ssh, rsync
  • rebooting

Yum worked everywhere and was a very helpful. If something was not installed I just did "yum install xxx" and it worked. A breath of fresh air.

ssh and rsync worked everywhere. I made extensive use of rsync to clone whole directory subtrees. This turned out to be very helpful. I use rsync to clone my website - I keep all the files on a local server and then rsync to update the site. If I lost the entire VPS I would not loose my data.

After pairing down and configuring the servers, "/sbin/shutown -r now" worked as expected. The sites all seem reboot safe after a little tweaking.

Problems I found

  • Different versions of the base O/S.
  • Different versions of Apache
  • Selinux problems

Different versions of the base O/S

I wanted everyone to use Centos 4.4. But I ended up with FC6/Selinux, Centos 4.1 and Centos 4.4. For sanity I'd like to stick with Centos as yum works and it's a modern distro.

Different versions of Apache

Each site has a different version of Apache. And, the all behaved slightly differently with my proxy setup. I ended up building and older version (2.0.55) on all 3 machines since that worked. I've since changed my Apache config to rewrite the URL's and I bet that will work with the different Apache's - I'll try at some point.

Selinux problems

This turned out to be mostly fear of the unknown. I'd never used Selinux. It seems big and complex (because it is). All I wanted to do was run my old services. The biggest issues seemed be running my proxy server on a non-standard TCP port and moving my dns zone files.

Convincing selinux to allow me to run my server took some time to figure out but I found out there is a tool which will read the log file entries when it fails and generate config files to allow it to work. Moving my dns zone files from /var/named to /var/named/data was much easier.

I'm not sure I need selinux in the end, but it does make for a pretty bullet proof server.

Summary

As I said, I signed up for three of VPS servers. I managed to get them to take my money and set up a server. I was able to hack on the server, set it up the way I wanted and reboot it. It felt just like my existing colocated server, only faster.

Here's a summary of my experience with each ISP:

vpsland

Extremely slow customer support - almost non-existant. Took 1.5 days to get server up. Interesting billing web site which looks helpful. Very fast machine, very good connectivity. Located in Atlanta. Checkered reviews on the web. Flashy website. Good price/features.

unixshell

Better customer support - slow but informative. These are are clearly closer to the metal. Took a 1.5 days to get up but got some technical email about the issue (it's a bit odd that there was a problem since I ordered a vanilla vps, but I think this whole concept is a bit new). Somewhat fast machine, not bad. Ok connectivity. Located in Atlanta. Checkered reviews on the web. Techy web site. Good price/features.

LeeWare Development

Best customer support. I suspect this is a small shop but they give personal attention. The could not offer me Centos but did offer to refund my money and put me on a waiting list (which was very nice). Reasonably fast machine, good connectivity. Located in the mid-west. Very simple web site. Limited offerings but they matched what I needed.

Current thoughts

I like VPSland the best because they have Centros 4.4 and excellent connectivity. TThis is troubling to me, however, because their customer support is pretty non-existant. They do answer sales email, however, but only after 24 hours.

I like the unixshell# guys since I think they are more like me (geeks) rather than slick marketing folks. But their connectivity is not as good.

I really like Leeware because they were so helpful, but the lack of Centos (right now) puts them 3rd.

My current plan is to drop one and keep two. Originally I liked the idea of one in Atlanta and one in Chicago but right now I'm leaning toward ignoring the geography and focusing on two reasonable Centos based sites.

I totally expect one of these (or 2) do dissapear at some point. It's just too common an occurrence to ignore. So, my plan is to maintain two sites and keep them up to date. If one dies, I just move the DNS and don't look back.

The good news is that even two VPS servers are cheaper than my current colo server and I don't have to maintain the hardware. I just wonder how this will all look in 5 years.

November 12, 2006

HTML from lisp

(aside: this is a pretty funny intro to lisp casting spels in lisp)

Generating HTML from lisp is nothing new. Many people have done it and there are lots projects on the web using it. There's also a lot of interesting XML/HTML lisp code floating around. It turns out that XML and HTML lend themselves rather well to symbolic processing.

I've recently been frustrated writing and maintaining html web pages. So, I thought I'd try an experiment. I modified a simple scheme based http server, placed it behind a caching apache2 server. These are ideas I got while looking at Hunchentoot and TBNL. It seems you can make a pretty robust and quick web server with SBCL and these tools. I also like this package (htout).

My needs are more simplistic, and I'm lazy, so I used scheme (siod). I took my old html web pages and extracted out the boiler-plate from the content. The I wrote some translation code which would generate HTML from lisp s-expressions. This translation takes several steps as I implemented some simple macros to make my life easier (common things like anchors in side a list element for example).

It only took a few days and I had parity with my old pages and found the new "content only, lispy style" pages much easier to read and edit.

Here's an example of one of the pages from www.unlambda.com. This pages as a standard look and style sheet as well as standard navigation but all of that is hidden. I can use all of html, but I get to use nice s-expression which are much easier to navigate (for me) than the XML syntax.

;; $Id$
(project-page
 :title "Various Lisp Machine Keyboards"
 :start "Various Lisp Machine Keyboards"
 :body
 '(
   (p "These some pictures of various Lisp Machine keyboards.  I don't have
any documentation on the actually keys (yet).")

   (h2 "CADR")

   (ul
    (li-url "http://world.std.com/~jdostale/kbd/SpaceCadet.html"
	    "")
    (li-url "http://world.std.com/~jdostale/kbd/Knight.html"
	    ""))

   (h2 "Symbolics")

   (ul
    (li-url "/keyboards/symbolics.gif"
	    "")
    (li-url "/keyboards/DSC_2077-small.jpg"
	    "Symbolics 3600 keyboard")
    (li-url "/keyboards/keyboard_6074.jpg" 
	    "Symbolics keyboard (PN 365407 Rev C)"))

   (p)))

I'm pretty happy with this an plan to redo all my pages. Worst case I can always generate raw html and go back to the old way. Best case I can continue to leverage lisp and make better and more interesting (and active) pages.

November 1, 2006

A quick Scheme / embedded-system example

Usually when I find myself fighting to prove a point it's usually becuase it's a loosing battle and my ego just won't let go.

But let's assume you actually might be interesting seeing why a simple lisp like scripting language might be intesting.

I wanted to change the behavior of a display terminal. I wanted it to have a list of times (hours in the day) and different behaviors.

  • homework time = m-f, 3-5pm
  • blank display, all ways, 10pm - 6am

I cranked out some quick scheme code in 15 minutes to do this. Basically I made a list of times with functions to call to check if the time is now and a function to be called when the time starts and stops.

I don't think I could have done that as generally in C, C++ or /bin/sh in the same time. I could have done something pretty specific in /bin/sh but then it would be a pain and lots of duplicated text if I wanted to add another time, event. C or C++ would have required some debugging time and more pain dealing with lists, etc... (assuming no STL++, thank you very much)

going backwards (or starting at the top), I first defined the times:

   ;;
   (define (time-init)
     (add-sleep-time (config-get 'sleep-hours))
     (add-homework-time (config-get 'homework-hours))
   t)

Note that config-get returns a "dotted pair" of begin & end times, i.e. "(10 . 6)" or "(3 . 5)". In lisp a dotted pair is between an atom (like a number) and a list (often a list of atoms).

Then I define how to add times to the list:

    ;; add time, any day
    (define (add-sleep-time hour-pair)
      (add-special-time 'hour-check hour-pair 'its-sleep-time '*sleeping*))

    ;; add time, but weekday only
    (define (add-homework-time hour-pair)
      (add-special-time 'hour-check-weekday hour-pair
                         'its-homework-time '*homework*))

    ;; make list of special times with check & action functions
    (define (add-special-time check-function hour-pair action-function state-var)
      (set! *special-times*
	    (nconc *special-times*
		   (cons (list check-function hour-pair
			       action-function state-var)))))

Note that *sleeping* is a globle variable which gets set. It's quoted so it won't be evaluated to it's value (we just want it's name). hour-check is the function to call to check the time. its-sleep-time is the function to call when the time is entered.

Then I define the functions to check the time:

    ;;
    (define (weekday)
      (let* ((ltime (localtime))
	     (wday (cdr (assoc 'wday ltime))))
	;; 0=sunday, 6=saturday
	(and (> wday 0)
	     (< wday 6))))

    ;;
    (define (hour-check-weekday time-pair)
      (and (weekday)
	   (hour-check time-pair)))

I then spent 10 minutes debugging it (interactively) and then installed it in the larger body of code. Viola. New behavior.

And, or completeness, here the other functions:

;;
(define (check-time)
  (let ((st *special-times*))
    (while st
	   (let* ((item (car st))
		  (func (eval (first item)))
		  (data (second item))
		  (action (eval (third item)))
		  (state-var (fourth item))
		  (state (eval state-var)))
	     (printf "item % % data %\n" item state data)
	     ;; enter
	     (and (not state)
		  (func data)
		  (event-time t action item)
		  (set-symbol-value! state-var t))
	     ;; exit
	     (and state
		  (not (func data))
		  (event-time nil action item)
		  (set-symbol-value! state-var nil)))
	   (set! st (cdr st)))))
;;
(define (hour-check time-pair)
  (let* ((ltime (localtime))
	 (hour (cdr (assoc 'hour ltime)))
	 (mins (cdr (assoc 'min ltime)))
	 (min (car time-pair))
	 (max (cdr time-pair)))
    (printf "hour-check % % %\n" hour min max)
    ;; if span crosses midnight
    (if (> min max)
	(or (>= hour min)
	    (< hour max))
	;; normal span
	(and
	 (>= hour min)
	 (< hour max)))))

With any luck this is mildly interesting. And, maybe it shows how simple it is to add complex functionalty. Or maybe it doesn't. But it was fun to do and I didn't get all bolluxed up with bad pointers or overflowing arrays or gdb. To me this is a fairly compact representation of a simple behavior and very handy on a small embedded system.

October 27, 2006

Scheme + Bogl + SDL = simple, quick embedded UI

I have been struggling with a way to make a simple user userface for an embedded system with a 640x480 LCD but no keyboard or mouse. The machine only has 64mb of ram and wants to run largely out of ram. This eliminates things like X windows, TK, etc... And, I wanted to be able to hack up experiments quickly.

I originally tried Java, but it ate the machine and all it's ram. Then I recoded in C++. This worked well but required recompiling and was hard to debug. It was fun, however, but not fast to develope and not flexible.

Then I found a nice small scheme interpreter called "siod". It supports very simple extension via shared libraries. I also foubd "bogl" -- ben's own graphics library. This is a simple set of graphics primative (lines, blt, simple fonts) which runs directly on a frame buffer, i.e. "/dev/fb" in the unix world.

I wrote an extension library for bogl and was quickly writing scheme (lisp) code to draw on the screen. In order to make progress quickly I hacked bogl to also output using SDL. This way I could compile everything on my desktop X86 machine and SDL provides a 640x480 X window which looks like my target display.

Once the library was stable I had X86 and target (ARM) versions in place an I had to do wasmove updated scheme text files to the target after each debugging session.

Scheme is very nice and easy to learn. It's basically a simplified version of lisp. If you are scared of lisp Scheme is a great place to start. You write scheme code in a text file and siod interprets the text files. It's just like writing shell scripts only much more expressive.

for example, here are some simple scheme functions to blank, unblank and draw a little text on the screen

;;
(define (fb-blank)
  (ioctl *fb-fd* FBIOBLANK 3))

;;
(define (fb-unblank)
  (ioctl *fb-fd* FBIOBLANK 0))

;;
(define (fb-comment current last)
  (let* ((word1 (number->string current 10))
	 (word2 (number->string last 10))
	 (text (string-append word1 "/" word2))
	 (tx 0)
	 (ty 0))
    (bogl-drawtext tx ty text 0 12)))

In lisp/scheme the convension is to decorate global variables with "*"'s. (i.e. *fb-fd* is a global variable). And scheme is nice because is knows about strings.

Basically you can crank out a simple UI pretty fast, testing it all on an X86 box. I've added support for gif, jpeg, http get and unix low level file i/o (read/write/poll). So now I have crank out a sophisticated UI very quickly and easily make changes.

I like scheme because you end up writing verbs which describe the problem you want to solve, like

      ;;
      (define (idle-weather)
	(if (not (weather-still-valid-p))
	    (begin
	      (update-weather)
	      (show-weather)
	      (show-rss)))
	(weather-idle))

This function gets called when the program is idle and in "weather display mode". The weather page also shows various rss feeds, as well as getting the XML weather from weather.com and displaying it in a nice day by day format with an icon and text.

And it's all interpreted. Pretty fast too. I can fix bugs right on the target using vim on a text file.

October 21, 2006

Never Say Die... (reviving a Linksys WRT54GS)

A while back I did a project using the Linksys wireless routers. Well,
more truthfully an associate did all the work, I just managed the project.

Anyway, my associate, being rusty with hardware at that point managed to "brick"
one of the units. It was toasted and would not respond to the simple
recovery proceedure. (aside: I do this all the time. generally I like
to produce smoke, sparks and flames. apparently all he got was a dead
unit. He'll need to practice shorting wires of higher amperage if he wants
to catch up)

Most recently I found myself needing two more Linksys boxes for some
distributed computing I'm doing. I found one and it runs OpenWRT which
I now love. The other was the "bricked" unit. (to brick = to render a device
no more useful than a brick)

I figured I'm a tough guy so I soldered the serial connector and JTAG
port. I connected up a simple jtag box and ran the "debrick" code
someone (hairdairymaid) wrote for windows. It didn't work. I fooled
around with it for hours. hours. I resoldered the pins. I used the
o-scope. I beeped out the lines. I compiled/hacked/fixed the linux
"wince jtag tools" to work with this particular broadcom cpu chip
(which, I might add, I did the original board port for). Still nothing.
I almost managed to get the linux jtag tools to erase the flash and
rewrite it but I had to modify the code and it was ugly. pain.
frustration. why am I spending 1/2 a day on a $50 box?

So, I put the board in the trash. But I didn't take out the trash. A
day goes buy. I break down and use a bogus WRT54GP box I had which
won't run linux. Blech. But it worked.

Today I notice (on accident) a posting where a guy says "hey, I tried
that hairydairymaid debrick code but it didn't work on my Intel J3
strataflash until I added a 2 second delay here and a 5 second delay
here..." His symptoms matched mine (erase appeared not to work). So, I
made the same change to the code and VIOLA! it's debricked! it works!
it runs OpenWRT! happy happy! joy joy!

Seems dumb all for a $50 box.

But, the interesting thing is that I found the answer on the web, but it
was not the first one. Many of the low level 'instructructions'
surrouding the WRT are marginal/flawed. But they often work well
enough. The high level ones seem to be largely good.

Wasn't that fun? :-)

January 6, 2006

Why I'm not an ISP Anymore



I had a nice year long run with a web hosting company (www.aqhost.com)
which ended in disaster. I stopped getting email from them in
December and then they shut me off and deleted my account on
12/31/2005.

They claim they sent me email throughout December but I never got any of it and my qmail SMTP logs don't show any email from them. I get a lot of email and I log all the headers so I know if something didn't arrive.

Anyway, the summarily deleted all my blog info. I had no backup (oops) but fortunately between the Internet wayback machine and Google I have been able to reconstruct most of the entries.

And, now I'm using a different method to archive and submit them which is based on one of my machines :-)

Needless to say I've chosen a new web hosting service with different policies.

In the end I've concluded that their billing system made a mistake (my credit card works fine) and their email never reached me. But they seemed uninterested in helping me or even looking into the problem so I wish them luck and have moved on.