Wednesday, July 14, 2010

Some ideas about Linux Kernel unit testing

Going through the internet, it looks like the concept "Linux Kernel unit testing" is quite unpopular. People can't even find "linux kernel unit test" on Google (

The traditional kernel development and debugging tool is still probably "printk". I think if I get desperate about kernel debugging, I may try user-mode linux (UML) or KGDB, and also hope JTAG may provide some relief since it doesn't distinguish kernel vs. userspace that much.

Recently, KGDB has been mainlined into Linux Kernel, which allows remote debugging of the kernel like userspace code -- one can set breakpoints, step through, and watch variables in GDB. After playing with KGDB, it feels like it shouldn't be too difficult to hijack the kernel like what KGDB does, and add in some simple scaffolding for unit testing.

What I am thinking of is to create a service in the kernel like KGDB, which can communicate with a userspace command-line front-end, and let users test kernel function calls. So people can test functions in device drivers in a more interactive and controllable manner like in UML. Since all these can be done on device and the code can run in kernel, it should be quite convenient compared to setting up a KGDB connection between two devices or using other methods.

Some thoughts about how to implement this:

1) Specify what kernel functions can be exercised with the unit test framework. This can be done maybe by marking these functions with a macro (or tag) so some scanner can pick them up at compile time.

2) Use some C parser to generate stubs for these functions so that they can be called in a parameterized way (like RPC). CINT may be a good try for this.

3) Run a C interpreter (maybe still CINT) in the userspace to take unit-test C scripts or commands. For those kernel functions, it communicates to the kernel service to make these function calls, either in the current process context or simulates some interrupt context.

In this way, it should be very easy to unit-test new features/functions in device drivers, or other kernel code, so that hopefully it should make kernel development more efficient, and improve the code quality, by making it easier to debug code and try out new implementations.

Saturday, May 15, 2010

My Linux/Android Wiki

To collect information about Linux (PC and embedded) and Android development. I put together a website It will include some information about linux kernel development, booting of embedded systems, tools, and references to typical problems.

Saturday, May 8, 2010

The Tao of iPhone UI (draft)

This is an article I have wanted to write for a while...

The first impression is that it is using advanced human-computer interaction theories and principles to guide the overall design. The final implementation of various gadgets doesn't look like the creation of individual developers, but looks like a rare solution to a set of very complicated criteria. What I mean is, it is new, strange, but it is not new and strange because someone just wanted something new and fancy, but it is a difficult solution to satisfy multiple design principles and human factors together.

This being my first impression, an effective competitive UI system would probably need to consider almost all the background critieria and factors used to restrict and motivate the iPhone/iPad UI. Then, propose another solution which satisfies all the criteria too, but looks significantly different. That's a path to creating a strong UI which may immediately obtain customer approval and popularity as iPhone did. iPhone's immediate success lies in the difficulty of solving the UI problem.

This explains why there is only one iPhone -- it may be an outstanding "local maximum" in the huge design landscape. Android's UI so far is quite primitive, including useful features to be extended by OEMs. There is a very good chance that the openness of the implementation will generate competitive and sleek phones -- the more it tries, the more probable that something great and stunning will come out. Linux GUI took more than a decade to finally rise to a similar level as Windows and Mac OS in Ubuntu. Having the Linux success to borrow from and given the relative simpleness of the system, Android has already achieved equal level as WinMobile and RIM. Its only competitor is iPhone.

A likely approach to defeat iPhone is indeed to consider its openness advantage as good for a "numbers game" -- a game which Apple's perfectionist and unique solution will not follow. When a lot of phonemakers are trying new ideas, something cool and satisfying may come out even though the background secrets of iPhone are not re-discovered and religiously followed.

From my impression, some of the hidden secrets or driving factors of iPhone UI design, can be listed below (though a more complete list will require some more formal study and research):

Goal of design (it's just mathematics):
1. Minimize a new user's (or all potential users' total) learning time (expaned in 3 below).

2. Maximize the user's experience of productivity and pleasure

a. This includes minimize the total time of user working-memory overload. Given that people's working memory span is 7 plus/minus 2 items, all fixed menus that need to be selected by the user should contain no more than 7 items. If it is more than 7 items, they should be broken down to groups of 7 or so. If long lists are needed, minimize user interaction time with these lists (scroll them out ASAP). If the lists are long by nature, provide a search box that takes partial or (even better) incremental input.

b. Besides reducing the taxation on user's working memory, it should also reduce energy spent on (selective) attention and movement. This includes making most frequently used options big (easy to see without squinting (squinting takes energy), and position them near the thumb's default positions (reduce moving distance, and muscle fatigue). The bigger something is, the less squinting energy is spent -- the outcome of this principle is the unprecedentedly large combo boxes (a half-screen pop-out) instead of an inline pain.

c. Both a and b need to be done by cutting off non-essential operations. Or create bigger umbrella operation to reduce a long procedure and to hide further details (thus minimize interaction time and again energy spent). The less energy spent, the more happy the user is -- this is the outcome of evolution. The umbrella operation idea is similar to the advent of Wizards in Windows Applications to avoid people from getting lost in big menu trees or being reluctant to try all the menu-dialog complexes. But it's a further simplification. A good example is the WiFi selector -- you either choose one of the listed, or just enter the name (SSID if it is not broadcast). You don't need to know what an SSID is (this is a headache). You don't have to worry about WEP vs WPA2, it will try it for you.

3. The last but not the least is to maximize the relevance of prior knowledge and experience. You haven't seen things immediately disappear after choosing it in your real life, so you don't see it in iPhone either. Though opening and closing views of objects (Windows) is now common, thanks to the MVC model in Mac OS and Windows, we shouldn't take it for granted, and it does take extra mental efforts/energy to understand the computer's model of its internal objects (even though we do so unconsciously). Why won't the UI use our model of the world -- things don't disappear, but they can be moved away, or we can come close to or farther from them (or scaling their appearances). This is a key principle driving iPhone UI design -- our existing model of the worlds already provides us a lot of "rules of thumb" to operate on things. If you show me something that looks like something I know and like, I know what to do with it. If you make use of what I want to do with it, you can use the idea to create a gadget that doesn't take anytime to learn. So one way of making a collection of learning-free gadgets is to exploit things we like and are used to: buttons, light switches, pieces of paper, books, films, "radio buttons" (bulleted selections), etc. The most important is the piece of paper model (attached to some rubber band because paper is too breakable and unpleasant)-- it is used to motivate almost everything that is big -- long lists, main apps menus, etc. We may think it's weird to aggressively model the physics of rubber bands or springs, but the physics is what we naturally bump into when we don't track of the sizes or boundaries of big things -- it simply will not move when you stretch too far, but you don't have to spend any energy watching for it's size to avoid breaking it. Such a design is a very good combination of a touch-and-feel, minimizing memory/attention taxation, and exploiting intuitive physics that everyone has. With this, we don't need to then learn scrollbars, the difference between scrolling by one line vs. scrolling by one page and even don't need to know where you are in the list -- it doesn't matter until you hit the boundaries -- then the physics will tell you.

The above is some very simple principles (all of them human-centered) that I strongly believe are used to motivate the designs: minimizing working memory/attention requirement, minimizing finger/eye movements, minimizing distractions and maximizing effortless long-term world knowledge and well-established habits of responses to familiar things.

The only exception of the design principles to make things easier -- is the power down operation -- you have to press the power key for a while, then carefully slide a handle held by an imaginary spring to the end position... That makes it harder to power down. Everything else is easy for you -- so enjoy.

Short-cut to the Linux kernel

These days, I begin collecting some Linux documents and information on blogs and twitter, so I can easily keep track of the information, and build up a knowledge base for later reference.

The Linux Kernel tar bar is pretty easy to obtain, compile and use. First time I did it was 10 years ago but never got a chance to seriously understand the Kernel itself, until Linux 2.6 has been out for a while, and popularly used everywhere from desktops to embedded systems. The article ( appears just too exciting to me with easy-to-understand discussions on so many advances in the new kernel in areas including O(1) scheduling, memory management, fast threading and mutexing. The author of many new updates in the new kernel, Ingo Molnar, bragged honestly in a KernelTrap interview that he started installing Linux around 1995 to see how to write a kernel, then became an Admin, and then a Linux user.

I started knowing Linux in the 90's too when someone in college compiled a system from source. I became the Admin of the system and a frequent user. When I finally got motivated to look at the kernel source -- it is already a huge tar ball (>64MiB in bz2 format)... Too much. I then googled the tar ball for Linux 0.11 written by Linus Torvalds himself for i386. Yep, this is a palatable 79K small tree, though it's enough to read for a couple of days or so. I think it may be the easiest way to understand the internals of the early Linux kernel -- boot, fs, devs, procs, etc. w/o headache.

The following are some links about the short-cut of understanding the Linux Kernel from its birth.

Linux 0.11 source:
i386 IDT:
Protected mode and paging:
How to write an OS:
An interesting experiment of using int 0x81 instead of 0x80 for syscall:

Thursday, May 6, 2010


Welcome to my new blog!

The most popular virus on the internet is blogs. Most of them are tiny, invisible - like this. Many are big, great, and got this one started.

I might use this one for technical memos for cool stuff I am working on. Or I will use it to "dig" stuff. The first post on any of my previous blogs is more boring than this one. So I think I am done. We will see.