Flying

Tue, 13 May 2008 06:18:52 +0000
travel a380

You would think after a few hundred flights and around 300,000 miles the wonder of flying would have worn off. And to a very large extent it has. There is nothing magical or exciting being stuck in a cramped narrow seat for 12 hours, but there are definitely times when you can't help but be amazed where technology and industralisation has got us.

Taking off for the first time on the massive double decker, super jumbo, A380 is definitely one of those experiences. Despite the solid engineering and science behind it, it is still pretty amazing when something that big actually gets of the ground. The fact that this aircraft is so quite when operating ust adds to the experience.

I was lucky enough to get a window seat on the upper deck on my flight from Sydney to Singapore last week. It was comfortable, seat, there is storage right next to you which is great, and the entertainment system is freaking cool. Nice, large crisp LCD screens, and a huge range of TV shows (I watched Buffy, and Bones), movies (I finally saw Juno), and multiplayer games (I cleaned up on Texas Hold-em). All in all, Singapore still gets my vote for best airline.

The next 10 flights (Singapore-Frankfurt, Frankfurt-Marseille, Marsielle-Munich, Munich-Berlin, Berlin-Copenhagen, Copenhagen-Helsinki, Helsinki-Frankfurt, Frankfurt-Zürich, Zürich-Washington D.C, Washington D.C-San Francisco), were nothing to write home about, I didn't get any upgrades, I went very close to missed connections, I ran out of battery on my laptop, all the usual things that make flying fun. I really must recommend not flying through Dulles. It took around 90 minutes to get though immigration, customs, baggage recheck, and security. It looked as though they were upgrading the airport, but if you are flying Europe to west coast US I'd recommend anywhere else, except maybe Denver where you are liable to get snowed in, or Chicago where you are likely to miss your connection. In fact just try and fly direct.

Thankfully after the 8 hours to east-coast plus 6 more hours to the west-coast, I was able to look forward to flying in business class home to Sydney. I'm not sure if it was the 14 hours of flying in economy, but this has been one of my most relaxed flights ever. For some reason the flight was basically empty, the business class cabin was only half-full, and I think anyone in economy probably got a row to themselves.

But none of that would usually inspire me to bother writing. What really did it was the view from the airplane at dawn. Seeing the sun rise of the horizon when you are flying 10km above the planet it pretty amazing when you think about it.

Trying to capture the view is not easy, while shooting out the plane window is not exactly ideal, I just don't think my point-and-shoot is up to it (blame the tools). Anyway, this photo is the best of the lot, it kind of works, but in real life, the blues are bluer, the sun a deeper orange, and the view far more expansive.

At CELF and Embedded Systems Conference this week

Mon, 14 Apr 2008 16:30:31 +0000
tech linux embedded celf photos

I'm in San Jose at the moment for both the CELF Embedded Linux Conference and the Embedded Systems Conference (ESC). (Which are conveniently scheduled at the same time, in different places!). I'm not quite sure how much of each I'll see. I'm primarily going to at CELF, but will probably end up playing some time as booth babe at the Open Kernel Labs stand at ESC.

Most importantly there will be beer at Gordon Biersch (San Jose) on Tuesday night from around 7pm. (Not Thursday night as I may have told people previously, of course if anyone wants to meet up on Thursday as well, that works too.)

I did manage to take a quick break from work yesterday and took advantage of the awesome weather in northern California to drive down to Big Sur along Highway 1. It was some pretty spectacular scenery. Hopefully I won't have a sprained ankle next time and will be able to do some hiking.

Big Sur

ESC seems to bring out some fun billboards, such as this one that I saw driving outside my hotel room today.

tightly couple and fully integrated

pexif 0.11 released

Thu, 27 Mar 2008 13:22:11 +0000
pexif code python tech

I released a new version of pexif today. This release fixes some small bugs and now deals with files containing multiple application markers. This means files that have XMP metadata now work.

Now I just wish I had time to actually use it for its original purpose of attaching geo data to my photos.

On apostrophes, Unicode and XML

Thu, 28 Feb 2008 12:51:39 +0000
artcile tech unicode web

So, I started with something reasonably straight-forward — update my blog posts so that the <title> tag is set correctly — which quickly led me down the rabbit hole of typographically correct apostrophes, Unicode, XML, encodings, keyboards and input methods. Updating my blog software took about 15 minutes, delving down the rabbit hole took about 5 hours.

So, the apostrophe. This isn’t about the correct usage of the apostrophe. This is entirely about correctly typesetting of the apostrophe. Now there are lots of opinions on the subject. It basically comes down to the choice between ASCII character 0x27 and Unicode code point U+2019. Of course it just so happens that ASCII character 0x27 is also Unicode code point U+0027, so really, this comes down to a discussion about which Unicode code point is most appropriate for representing the apostrophe. After way too much searching, it actually turns out to be a really simple decision. Unicode provides the documentation for the code points in a series of charts. The chart C0 Controls and Basic Latin (pdf) documents the APOSTROPHE. It is described as:

0027 ' APOSTROPHE 
= apostrophe-quote (1.0) 
= APL quote 
• neutral (vertical) glyph with mixed usage 
• 2019 ’  is preferred for apostrophe 

So, despite the fact that it is named APOSTROPHE, it is described as a neutral (vertical) glyph with mixed usage, and it notes that U+2019 is the preferred code point for apostrophe. This looks pretty conclusive but let’s check the General Punctuation chart:

2019 ’ RIGHT SINGLE QUOTATION MARK 
= single comma quotation mark 
• this is the preferred character to use for apostrophe

So, my conclusion is that the most appropriate character for an apostrophe is U+2019. OK, great, now I have to decide how I can actually encode this. I’m used to writing plain ASCII text documents, and U+2019 is not something I can represent in ASCII. So, since I’m mostly concerned about document I’m publishing on the interwebs, and I figured that character entities refernences would be the way to go. So there appears to be a relevant entity:

<!ENTITY rsquo   CDATA "’" -- right single quotation mark, U+2019 ISOnum -->

Of course is seems a little odd using &rsquot; to represent an apostrophe, but so be it. Now in XML a new character entity is defined &apos;, which you might on first glance think is exactly what you want, but on second glance, it isn’t, since it maps to U+0027, not U+2019. &apos; is mostly used for escaping strings which are enclosed in actual ' characters. So, &apos; is out. XML itself only defines character entities for ampersand, less-than, greater-than, quotation mark, and apostrophe. XHTML however defines the rest of the character entities that you have come to love and expect from HTML, so &rsquot; is still in, as long as it is used in an XHTML document, not a general XML document.

So I was set on just using &rsquot;, and I sent my page off to the validator. This went fine, except it pedantically pointed out that I had not defined a character encoding, and really I should. Damn, now I need to think about character encoding too. OK, so what options are there? Well, IANA, has a nice list of official names for characters sets that may be used in the internet.

ANSI_X3.4-1968 (a.k.a US-ASCII, a.k.a ASCII) had to be a big first contender, since that is basically what I had been doing for many a year, but to be honest, this seemed a little backwards. The idea of having to use numeric character references (NCRs) everytime I wanted an apostrophe seemed a little silly. Besides the W3C recommends using

an encoding that allows you to represent the characters in their normal form, rather than using character entities or NCRs

OK, so since XML spec defines that:

A character reference refers to a specific character in the ISO/IEC 10646 character set

it seems that I really should choose an encoding that can directly encode Unicode code points. (The Unicode standard and ISO/IEC 10646 track each other.) So, what options are there for encoding Unicode? Well it seem that one of the Unicode transformation formats would be a good choice. But there are so many to choose from, UTF-8, UTF-16, UTF-32, even UTF-9. While UTF-9 was definitely a contender, UTF-8 seems to sanest thing for me. For a start it seems to just-work™ in my editor. So, going with UTF-8, I still end up needing to let other people know my files are encoded in UTF-8. There appears to be a few options for doing this, and the article goes into a long explanation of the various different pros and cons. In the end, I just put it into the XML prolog.

Of course the final piece of the puzzle is actually inputing characters. OS X seems to have fairly good support for this. If you poke around a bit in internationalisation support in system preferences and enable Show Keyobard Viewer, Show Character Viewer and Unicode Hex Input, you should be able to works things out.

So, I can now have lovely typographically correct apostrophes and they work great, and all is good with the world. (Except of course that this page probably renders like crap in Internet Explorer. Oh well.)

Emacs backup files

Tue, 26 Feb 2008 18:47:45 +0000
tech article emacs

The backup files that emacs litters your filesystem with can be a real pain. Stupid tilde files can be annoying and dangerous. Especially since ~ does double duty of being a short cut for your home directory. (I can't be the only person who has accidently typed rm -fr *~ as rm -fr * ~).

Anyway, the easy solution is to add this to your config file:

(setq backup-directory-alist '(("" . "~/.emacs.d/emacs-backup")))

Are microkernels hardware abstraction layers?

Mon, 25 Feb 2008 16:58:27 +0000
tech article microkernel okl4

In a recent post Gernot made a comparison between nanokernels and hardware abstraction layers (HALs). This prompted a question on the OKL4 developers mailing list: well, couldn’t you consider a microkernel a HAL?.

I think the logical conclusion, both theoretical and practical, is a resounding, no.

Why? Well, a microkernel is, in theory (if not always in practise) minimal. That is, it should only include things in the kernel are those pieces of code that must run in privileged mode.

So, if a microkernel was to provide any hardware abstractions, it will only be providing the abstraction that have to be in the kernel. Which really falls short of a complete hardware abstraction layer.

Venn diagramm shoing overlap between HAL and microkernel properties

Now, probably the more interesting question is should the microkernel provide any hardware abstraction, and if so what hardware should it be abstracting, and what is the right abstraction. After starting to write some answers to these questions I reminded myself of the complexity involved in answering them, so I will leave these questions hanging for another post.

linux.conf.au 2008 Day 1

Mon, 28 Jan 2008 19:01:51 +0000
tech lca linux android

After two weeks in California, I spent two days in Sydney, before flying down the sunny Melbourne yesterday for linux.conf.au 2008.

Monday and Tuesday at linux.conf.au are the miniconf days. The wide variety of topics on display make things a little difficult. I was back and forward between the embedded and virtualisation mini-confs.

I gave two presentations today, the first this morning was on how to port OKL4 to a new system-on-a-chip. The chip in question is the virtual Goldfish SoC, which forms the core of the emulated platform in Google's Android SDK.

The second presentation on a more high-level talk on why virtualisation is a useful technology not just for large data-centers and server applications, but also for embedded systems, such a mobile phone handsets.

Unfortunately because I was presenting, I didn't really have much time to focus on some of the other great presentations that went on today. With any luck I'll be able more attentively attend some talks tomorrow.

For those interested, the talks were filmed, so hopefully videos will be up online in the near future.

Updating the Android system image

Thu, 29 Nov 2007 08:34:00 +0000
tech android article

A lot of people on the groups page seem to be wanting to update the /system directory for a bunch of sane (and sometimes insane) reasons. As they and others have found out, changes to /system do not persist across reboots. This explains how to get around this.

The easiest way is to make a simple change to the Qemu source. First you download the source from the Android open source page. Then it is a very simple matter of chaning one line:

sprintf(tmp, "system,size=0x4200000,initfile=%s", arg_nand0);

Replace initfile, with simply file:

sprintf(tmp, "system,size=0x4200000,file=%s", arg_nand0);

Recompile and start using your shiny new emulator. Note: You probably want to make a backup of the system.img file so when you hose it you can start fresh.

As far as I can tell there isn't anyway to do this without hacking the code. This is probably easier than trying to get yaffs filesystem generatiogn tools working though.

A quick look inside the Android emulator

Thu, 29 Nov 2007 00:37:01 +0000
tech android article

I've been working on getting OKL4 up and running on the Android simulator. In doing so I've ended up getting quite involved with the simulator code base and thought I would share some of my findings.

At the core the simulator is Qemu version 0.8.2. The Android team has provided a wrapper main(), which does some slightly nicer argument naming and parsing, and ends up calling the traditional Qemu entrypoint. Inside, the main change is that a new platform called goldfish has been added to supplement the existing Integrator and Versatile platforms.

When porting a different OS to a new platform, the first thing you need to do is get some basic device drivers, such as interrupt controller, serial console and timer, up and running. Usually, the way to do this is find the published spec sheet, and go off that. Unfortunately there is no published spec sheet for the goldfish, but we have something infinitely more useful; the actual source code to the simulated device. (The number of times I've found bit errors in device documentation is pretty amazing!).

This post will share some of the details of the simulated platform (as it stands at this point in time!), along with some commentary. I'm only covering the bits that I have needed in bootstrapping OKL4, so keypads, framebuffers, etc will have to wait for another day. (Hopefully, tomorrow).

Physical memory layout

The physical memory layout is about as simple as it gets. RAM starts at address 0, and continues up to size of ram, in one contiguous block.

Cache

The data cache is 16KiB, 4 way set associative, with 32 byte lines. This is pretty standard, although it would be nice to have higher associativity. (Of course, it makes not very much difference in terms of simulation, so one can only guess that this cache layout is going to be similar to some real system-on-chip being used in an actual phone.)

Interrupt controller

The interrupt controller has a 4KiB block of registers residing at 0xff000000. It consist of 5 32-bit registers.

STATUS at offset 0x0 contains the number of pending interrupt. It is a read-only register.

NUMBER at offset 0x4 contains the lowest pending, enabled interrupt number. It is a read-only register.

DISABLE_ALL at offset 0x8 is a write-only register. Writing any value to it will disable all interrupts.

DISABLE at offset 0xC is a write-only register. Writing an interrupt number to it will disable to specified interrupt.

ENABLE at offset 0x10 is a write-only register. Writing an interrupt number to it will enable to specified interrupt.

This has to be the best interface to an interrupt controller ever. No messy shifting, or updating multiple registers to get the job done. Every function I need to implement in my driver ends up being just a register read or write. Bliss!

Serial

The serial controller has a 4KiB block of registers residing at 0xff002000. It consist of 5 32-bit registers.

PUT_CHAR at offset 0x0 is a write-only register. Writing a value to it puts a character onto the console.

BYTES_READY at offset 0x4 returns the number of characters waiting to be read from the console. This register is read-only.

CMD at offset 0x8 is a write-only register. Writing a command performs one of four actions.

DATA_PTR at offset 0x10 is a write-only register. The value in this register is the virtual address used in read and write buffer commands.

DATA_LEN at offset 0x14 is a write-only register. The value in this register is the number of bytes to copy on the read or write buffer commands.

This is a really nice interface. My one reservation is that it would be really nice if performing a read from PUT_CHAR returned a character if available. (Of course then it should be renamed from PUT_CHAR.) It was an interesting decision to use virtual addresses for the buffers, rather than a physical address. This will be different from most hardware out there.

Timer

The serial controller has a 4KiB block of registers residing at 0xff003000. It consist of 5 32-bit registers. Time is represented by a flowing 64-bit counter.

TIME_LOW at offset 0x0 return the lowest 32-bit from the 64-bit counter. It also latches the high 32-bits into TIME_HIGH. You must read TIME_LOW, before reading TIME_HIGH to get consistent values. It is a read-only register.

TIME_HIGH at offset 0x4 is a read-only register storing the top 32-bits of the 64-bit counter. It should only be read after reading the TIME_LOW value.

ALARM_LOW at offset 0x8 is a write-only register storing the lowest 32-bits of the next alarm value. When written it takes the top 32-bits for the alarm value from ALARM_HIGH and stores the value in an internal register. To get consistent results the ALARM_HIGH should be stored first when setting an alarm. When the counter value reaches the alarm value and interrupt is triggered.

ALARM_HIGH at offset 0xc is a write-only register storing the top 32-bits of the next alarm value. Writing to this register does not update the internal 64-bit alarm register. This is done on writes to ALARM_LOW

CLEAR_INTERRUPT at offset 0x10 is a write-only register. When written to it will clear an interrupt previously posted by the alarm.

This is a nice simple way to access an OS timer. The only thing missing is a periodic mode so the next alarm value doesn't need to be calculated each time. (Of course, periodic ticks are on the way out, so this isn't very critical.)

Bug fixes

The first bug fix is to actually make the thing compile on my machine. This mostly involved removing what seems to be dead code. SDL is used, but the build system is set up to only use SDL on specific files, and on those files, the correct include would be #include <SDL.h>. It turns out this code is unused, so we can just get rid of it entirely. This isn't really a problem for anyone using Android, just if you want to try and recompile.

--- android-emulator-20071111.orig/qemu/vl.c 2007-11-12 17:58:42.000000000 +1100
+++ android-emulator-20071111/qemu/vl.c   2007-11-29 00:29:35.000000000 +1100
@@ -78,12 +78,6 @@
 extern void  android_emulation_setup( void );
 extern void  android_emulation_teardown( void );
 
-#ifdef CONFIG_SDL
-#ifdef __APPLE__
-#include 
-#endif
-#endif /* CONFIG_SDL */
-
 #ifdef CONFIG_COCOA
 #undef main
 #define main qemu_main

The next bug is a little odd. This was found during a run of L4 test. Basically, the code goes to a lot of trouble to register a real-time alarm, and hook up a signal handler to service this. (This is how timer interrupts end up being injected into the emulated machine.) The problem is that the default sigprogmask seems to have SIGALRM blocked, which means we don't end up getting timer interrupts, or at least not if the emulated code is running in a tight loop. This bug could actually affect people using Android. It is possible that in this case timer interrupts are missed and the system becomes unresponsive. I'm not sure if it is something strange in my setup that makes SIGALRM blocked by default, or if this is a general problem. It should probably be investigated further.

diff -ru android-emulator-20071111.orig/qemu/vl.c android-emulator-20071111/qemu/vl.c
--- android-emulator-20071111.orig/qemu/vl.c 2007-11-12 17:58:42.000000000 +1100
+++ android-emulator-20071111/qemu/vl.c   2007-11-29 00:43:34.000000000 +1100
@@ -1282,6 +1276,7 @@
     {
         struct sigaction act;
         struct itimerval itv;
+        sigset_t nset;
 
         sigfillset(&act.sa_mask);
         act.sa_flags = 0;
@@ -1304,6 +1299,10 @@
         /* we probe the tick duration of the kernel to inform the user if
            the emulated kernel requested a too high timer frequency */
         getitimer(ITIMER_REAL, &itv);
+
+        sigemptyset(&nset);
+        sigaddset(&nset, SIGALRM);
+        sigprocmask(SIG_UNBLOCK, &nset, NULL);
     }
 #endif
 }

The next bugs are nasty. Really nasty. And I didn't really debug them, I kind of guessed and looked at diffs to find them. They deal with the innards of the ARM MMU, and are only really exposed by kernels that make full use of the memory management unit (e.g: domains for fast context switching, super pages, PID relocation). OKL4 does this, which I why I'm hitting these bugs, where as Linux doesn't right now, so it avoids them. The first of these problems was fixed upstream in Qemu 0.9.0, the second was actually found by another engineer at OK Labs, Matt Warton, and has been pushed upstream already.

diff -ru android-emulator-20071111.orig/qemu/target-arm/helper.c android-emulator-20071111/qemu/target-arm/helper.c
--- android-emulator-20071111.orig/qemu/target-arm/helper.c 2007-11-12 17:58:42.000000000 +1100
+++ android-emulator-20071111/qemu/target-arm/helper.c   2007-11-29 00:26:44.000000000 +1100
@@ -247,7 +247,7 @@
 
   switch (ap) {
   case 0:
-      if (access_type != 1)
+      if (access_type == 1)
           return 0;
       switch ((env->cp15.c1_sys >> 8) & 3) {
       case 1:
@@ -428,6 +428,7 @@
         break;
     case 3: /* MMU Domain access control.  */
         env->cp15.c3 = val;
+        tlb_flush(env, 1);
         break;
     case 4: /* Reserved.  */
         goto bad_reg;

New features

Since I was having to modify the emulator anyway, I decided to add a feature to make my live just a little easier. Qemu expects to be loading and a Linux kernel, but not all kernels out there are Linux, and they have different expectations about where they should be loaded and what data if any should be passed to them.

I've extended Qemu, and the android wrapper to support a new -os-type flag, so that you can specify what type of OS is being emulated. By default this is set to Linux, and the normal Linux kernel loading algorithm applies. If it is set to anything else, then it simply loads the specified kernel directly in at the start of memory and doesn't do any string or command line passing.

diff -ru android-emulator-20071111.orig/qemu/android_sdl.c android-emulator-20071111/qemu/android_sdl.c
--- android-emulator-20071111.orig/qemu/android_sdl.c 2007-11-12 17:58:41.000000000 +1100
+++ android-emulator-20071111/qemu/android_sdl.c   2007-11-29 00:59:24.000000000 +1100
@@ -3537,6 +3537,7 @@
 static char *arg_nand0 = 0;
 static char *arg_nand1 = 0;
 static char *arg_sdcard = 0;
+static char *arg_os_type = 0;
 static char *arg_kernel = 0;
 static char *arg_ramdisk = 0;
 static char *arg_tracefile = 0;
@@ -3573,6 +3574,7 @@
     const char *help;   /* description text for this option */
 } argmap[] = {
     { "-system",   &arg_sysdir,    0,              0,                   "<dir>",    "search system, ramdisk and userdata images in <dir>" },
+    { "-os-type",  &arg_os_type,   0,             "linux",              "<os-type>","kernel image is of given OS type. E.g: linux, okl4" },
     { "-kernel",   &arg_kernel,    0,             "kernel-qemu",        "<file>",   "use <file> as the emulated kernel" },
     { "-ramdisk",  &arg_ramdisk,   0,             "ramdisk.img",        "<file>",   "use <file> as the ramdisk image (default is <system>/ramdisk.img)" },
     { "-image",    &arg_nand0,     0,             "system.img",         "<file>",   "use <file> as the system image (default is <system>/system.img)" },
@@ -4270,6 +4272,10 @@
 
     n = 1;
     /* generate arguments for the underlying qemu main() */
+    if(arg_os_type && arg_os_type[0]) {
+        args[n++] = "-os-type";
+        args[n++] = arg_os_type;
+    }
     if(arg_kernel && arg_kernel[0]) {
         args[n++] = "-kernel";
         args[n++] = arg_kernel;
--- android-emulator-20071111.orig/qemu/vl.c 2007-11-12 17:58:42.000000000 +1100
+++ android-emulator-20071111/qemu/vl.c   2007-11-29 00:56:47.000000000 +1100
@@ -199,6 +193,8 @@
 int dcache_store_miss_penalty = 5;
 #endif
 
+char *os_type = "linux";
+
 extern void  dprint( const char* format, ... );
 
 /***********************************************************/
@@ -6005,6 +6006,7 @@
     QEMU_OPTION_smb,
     QEMU_OPTION_redir,
 
+    QEMU_OPTION_os_type,
     QEMU_OPTION_kernel,
     QEMU_OPTION_append,
     QEMU_OPTION_initrd,
@@ -6095,6 +6097,7 @@
     { "redir", HAS_ARG, QEMU_OPTION_redir },
 #endif
 
+    { "os-type", HAS_ARG, QEMU_OPTION_os_type },
     { "kernel", HAS_ARG, QEMU_OPTION_kernel },
     { "append", HAS_ARG, QEMU_OPTION_append },
     { "initrd", HAS_ARG, QEMU_OPTION_initrd },
@@ -6564,6 +6567,9 @@
                 pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
                 nographic = 1;
                 break;
+            case QEMU_OPTION_os_type:
+                os_type = optarg;
+                break;
             case QEMU_OPTION_kernel:
                 kernel_filename = optarg;
                 break;
--- android-emulator-20071111.orig/qemu/hw/arm_boot.c 2007-11-12 17:58:41.000000000 +1100
+++ android-emulator-20071111/qemu/hw/arm_boot.c   2007-11-29 00:57:04.000000000 +1100
@@ -64,6 +64,8 @@
     stl_raw(p++, 0);
 }
 
+extern char *os_type;
+
 void arm_load_kernel(int ram_size, const char *kernel_filename,
                      const char *kernel_cmdline, const char *initrd_filename,
                      int board_id)
@@ -71,19 +73,27 @@
     int kernel_size;
     int initrd_size;
     int n;
+    int linux_image = (strcmp(os_type, "linux") == 0);
 
     /* Load the kernel.  */
     if (!kernel_filename) {
         fprintf(stderr, "Kernel image must be specified\n");
         exit(1);
     }
-    kernel_size = load_image(kernel_filename,
-                             phys_ram_base + KERNEL_LOAD_ADDR);
+
+    if (linux_image) {
+      kernel_size = load_image(kernel_filename,
+               phys_ram_base + KERNEL_LOAD_ADDR);
+    } else {
+      kernel_size = load_image(kernel_filename,
+               phys_ram_base);
+    }
     if (kernel_size < 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
         exit(1);
     }
-    if (initrd_filename) {
+
+    if (linux_image && initrd_filename) {
         initrd_size = load_image(initrd_filename,
                                  phys_ram_base + INITRD_LOAD_ADDR);
         if (initrd_size < 0) {
@@ -94,12 +104,14 @@
     } else {
         initrd_size = 0;
     }
-    bootloader[1] |= board_id & 0xff;
-    bootloader[2] |= (board_id >> 8) & 0xff;
-    bootloader[5] = KERNEL_ARGS_ADDR;
-    bootloader[6] = KERNEL_LOAD_ADDR;
-    for (n = 0; n < sizeof(bootloader) / 4; n++)
-        stl_raw(phys_ram_base + (n * 4), bootloader[n]);
-    set_kernel_args(ram_size, initrd_size, kernel_cmdline);
+    if (linux_image) {
+        bootloader[1] |= board_id & 0xff;
+        bootloader[2] |= (board_id >> 8) & 0xff;
+        bootloader[5] = KERNEL_ARGS_ADDR;
+        bootloader[6] = KERNEL_LOAD_ADDR;
+        for (n = 0; n < sizeof(bootloader) / 4; n++)
+            stl_raw(phys_ram_base + (n * 4), bootloader[n]);
+        set_kernel_args(ram_size, initrd_size, kernel_cmdline);
+    }
 }

What is Android?

Mon, 26 Nov 2007 10:35:40 +0000
tech android article

For some reason over the past two weeks I've had friends and colleagues coming up to me and asking What is android? This is a, hopefully short, post to try and answer that question. In an effort to keep this post short, I'm making statements without necessarily backing them up with argument. If anyone disagrees with my analysis, please email me, and I can address any of the points. Of course people should probably first read the official What is android? page.

The simple five words answer is: Android is an operating system. Of course, while factually true, this doesn't explain much. The next important point is that it is a component based operating system. This means that rather than writing programs as such, extra functionality is added in the form of components. The next interesting point is that it includes an integrated Java virtual machine, and that the system interfaces are only exposed through Java libraries. The final, and in my opinion least important, point is that the operating system is based on the Linux kernel. While the OS is based on the Linux kernel, it is not a GNU/Linux-like OS; the system libraries, system initialisation and programmer interface are distinctly different from a standard Linux operating system.

As part of the announcement of this new operating system, Google has also released the Android software development kit (SDK). The SDK is designed to allow developers to write and test software to run on top of the operating system. The SDK is not designed to allow third parties to extend the OS itself, or port it to new devices. (Although some people have been able to use it to achieve this, it is very much not designed for this.) The SDK includes the usual things; tools for building Android packages (components), sample files, templates for new projects, documentation, and a system simulator. The SDK only provide facilities for writing components in Java, and relies on the programmer to have a JDK already installed.

An open system

The system has been promoted as an open system. I would really like to point out that open is a lot different from open source. I'm sure there will be discussion as to what one means vs. the other, but from my point of view it is an open system from the point of view that it is open for programmers to develop new applications for the platform. The operating system has been built using a number of different open source components, and Google has complied with the licenses under which is has obtained the code by acknowledging the authors (in the cases where code is released under BSD), and by releasing code when required to under a reciprocal license (e.g: GPL). Google has pledged to release the code under an Apache license, but this isn't expected to happen until late 2008 - until then it is an open, but closed source operating system.

What Android isn't

Here are some other perspectives of what Android is, and why I disagree with that point-of-view.

A Java API for phones: This is certainly part of the picture, but I don't think this by itself correctly represents what Android is, as there is a lot more to it than just that.

An application framework for Linux: This is a description I have a bit of sympathy for, and one which ultimately comes down to a mostly philosophical discussion of what is an operating system. While it is definitely a framework for developing applications, and it is running on the Linux kernel, I think there is more to an operating system than just the kernel, it has to include all the system libraries, system initialisation, and system interfaces. From all these point of views, Android differs from a standard Linux based operating system. I definitely have a new appreciation for Stallman's quest to refer to standard Linux based operating systems as GNU/Linux. I think this really helps distinguishes between Linux the kernel, and GNU/Linux the operating system, and I'm certainly going to start using this terminology, for simple practical reasons, rather than any ideological reasons.

Hopefully this has given you a good insight to what Android is and also what Android isn't.