The user space software links with the standard GNU C library interface. The GNU C library comes with all major Linux distributions except some minimalistic embedded systems which use some other size-optimized C library (like uClibc). The GNU C library aims at POSIX compatibility, and maemo aims at being compatible with mainstream Linux systems as much as possible to minimize the effort of porting applications and application engines, and to bring in the best open source solutions for mobile computers.
The package management framework, the file system hierarchy, and general design policies come from the Debian distribution. Maemo aims at following Debian policies as much as possible. The Debian distribution has by far the largest development community; in September 2007 Debian supported about a dozen different hardware architectures, and it had more than 18,000 software components available.
The user interface architecture is based on GNOME framework, especially the GTK+ widget set. GNOME is a leading application framework for desktop Linux systems. From the GNOME project, maemo has inherited many central components, including for instance GTK+, GStreamer multimedia framework, GConf configuration management, and XML library. Maemo extends GTK+/GNOME by providing the Hildon extensions for a mobile desktop.
Official maemo APIs are provided for the C language. Maemo also has C++ and Python bindings for its core APIs. Other unofficial bindings for other languages and environments exist.
Applications on the InitFS are linked with uClibc, a minimal version of the C library in order to reduce space. The Device State Management Entity (dsme) is also located in the InitFS. The existence of the dsme daemon is vital, so it is used to ping the hardware watchdog as well.
The Linux kernel is the central software component of the system. It provides the hardware abstraction layer for the system devices, memory management, process management, networking services including link and transport layer protocols like TCP/IP, file management including file systems and various other services.
Parts of the kernel functionality can be implemented as dynamically-loadable kernel modules. A kernel module can be loaded or removed during runtime. Kernel functionality, such as device drivers, network protocols, or file systems can be implemented as kernel modules.
The ARM/OMAP-based Linux kernel on maemo devices implements several hardware-specific device drivers and bus drivers on top of the core kernel's virtual services. The device drivers include USB, LCD, WLAN, Camera, and Audio, for instance. The bus drivers include Flash bus, SPI, I2C, and serial bus, for instance.
For hardware abstraction, maemo provides HAL (Hardware Abstraction Layer). It provides a shared library that has an API for device objects. A device object has properties, and it is up to an actual device driver, which properties it supports. HAL is thus capable of loading the right device driver, when a new device is detected, creating and maintaining /dev files, tracking the status of devices and providing a means to uses each device.
The system provides an SQL database, SQLite 3, that can be used to store user application data. SQLite database is accessed through a library interface; there is no centralized server process to connect.
Hildon framework provides components on top of the GNOME components to support control panel, status bar, task navigator, and home applets. Hildon framework also provides backup/restore framework, help framework, and an application manager.
|5.3.1 Connectivity||5.3.1 System UI||5.3.1 Search||5.3.1 Text Input||5.3.1 MIME Types|
|5.3.1 Home Applets||5.3.1 Control Panel||5.3.1 Task Navigator||5.3.1 Status Bar|
|5.3.1 Backup||5.3.1 Installer||5.3.1 Alarm||5.3.1 Help||5.3.1 Launcher|
|5.3.1 Sapwood||5.3.1 Hildon Widgets||5.3.1 Hildon File UI||HTML Widget|
|Samba||GPS||Obex||5.3.1 ConIC||UPnP||JPEG PNG TIFF SVG||Matchbox|
|D-BUS||HAL||SQLite||curl HTTP||5.3.1 Clipboard|
|SSL||5.3.1 System SW||5.3.1 Cert. mgnt||5.3.1 libosso||X|
|Libstd C++||5.3.1 Compression||dpkg||apt||Freetype||Fontconfig|
|Sysvinit||5.3.1 Base Files||Busybox||GNU C Library||Core Libs||Core Utils||5.3.1 Core Daemons|
|BlueZ||5.3.1 Power mgnt||WLAN security||ALSA||Video4-Linux|
|Bootloader||Linux kernel including JFFS2, TCP/IP||InitFS including uClibc dsme|
The components marked with yellow color are in general provided as binary only (some subcomponents in them may be provided with source code, though), others come with source code as well. Some specific applications, however, are provided with source code. Some maemo-specific components are described in more detail below.
The backup application must not to be disrupted by other applications writing or reading during a backup or restore operation. For restore process, backup will therefore, if the user approves, ask the application killer to close all applications, and then wait until it has been done. For backing up, the backup_start and backup_finish D-BUS signals will be emitted on the session bus, indicating to applications that they should not write to disk.
Packages included in the subsystem are:
The maemo-invoker asks the maemo-launcher to start the actual application. Use of maemo launcher requires that the application is compiled as a shared library. There is a set of helper Debian package rules that make an application to "automatically" use maemo-invoker, when given suitable build options. As a result, the application binary name is linked to maemo-invoker and the application (library) binary name has .launch extension. By default, the invoker will wait until the maemo-launcher tells it that the application has exited, so that it can return the correct return value for the caller.
The maemo-launcher is a server process that has initialized most of the data used by the applications, such as Glib types, Gtk theme and some Gtk widget classes. When it is asked by the maemo-invoker to start an application, instead of executing the application binary, it will dl-load that as a shared library, fork and call main(). With fork, the initialized data is handled as copy-on-write, i.e. shared until it is modified. If the application exits abnormally, the maemo-launcher notifies the Desktop, so that the Desktop can inform the user about it.
Because prelinking does not work with dl-loaded libraries, the maemo Launcher cannot speed up starting of applications, where library linking has a larger effect on the start-up time than AF library initializations. It can still save memory, though.bitmaps between applications. Sapwood is also much faster, because it tiles the 16-bit images using X server, whereas the pixbuf engine scales the 24/32-bit on the client side and then converts them to 16-bit for X server for blitting.
More detailed description of the components:
OS-idle and DVFS are triggered independently of each other. DVFS is triggered based on any increase or decrease of required processing power, while OS-idle is triggered by the Linux scheduler.
Currently the suspend and resume functionality provided by Linux Driver Model is not used. Also, the kernel level power management does not get any guidance from the user space.
The maemo kernel is based on the ARM kernel branch and can be modified, recompiled and flashed by a developer. Chapter Kernel Guide11 gives the details for these procedures. Some of the modules, such as WLAN, come as binary only, which means that the module APIs should remain unchanged, if the kernel is changed by a developer.
Hildon has several additions and enhancements to GNOME/GTK+, including Hildon widget set, Sapwood theme engine and image server, task navigator, Hildon control panel and status bar. Some of the changes to standard GNOME, like Sapwood, are made to reduce memory requirements and to improve speed on a small hand-held device. In addition, Hildon framework has many features to support mobility, such as automatic state saving, touchscreen input methods, and window management on a physically small device.
The programming APIs are familiar to GNOME and GTK+ developers. The framework has GLib and GObject object management system underneath. The GTK+ widget set is provided with Hildon extensions. The interprocess communication is performed using D-BUS messages. The user files are accessed through GNOME-VFS, and multimedia applications can use GStreamer to get accelerated support for various codecs. User configurations are stored via GConf and an XML parser API is available.
The figure 5.1 illustrates the most crucial components and their dependencies that a maemo application developer must deal with. These components are explained in more detail in the next sections.9] Linux distribution. Maemo builds on GNU/Linux for operating system core and GNOME/GTK+ for user interface architecture.
Maemo uses the same component packaging system as Debian - dpkg-tool's binary packages. New packages can be installed, old ones can be removed and the whole system can be upgraded by the package management framework. The file system structure also comes from Debian.
In order to run the software on an Internet Tablet, various optimizations and enhancements have been made. These include power management related issues, touchscreen input, performance and size optimizations. In order to reduce space, maemo uses shell and command line tools from Busybox.
Also notably the maemo platform adheres closely to the GNOME Mobile Platform. At the time of writing, maemo uses all the same components as this platform, except for service discovery.Bash and coreutils with Busybox, an optimized command line tool set and shell for embedded devices. There is no bsdutils package as such, but Busybox provides logger and renice utilities (script, wall and scriptreplay are missing). Diff has also been left out, as well as e2fsprogs and ncurses packages. The size reduction just from the utilities and libraries is about 2.5MB and an additional 1.5MB from replacing Bash.
|bsdutils||logger and renice in Busybox, script, wall, scriptreplay missing||included|
|sysvinit-utils||last, mesg, pidof in Busybox, lastb, killall5, sulogin missing||included|
N.B. Busybox may not support all the command line options of the standard tool, even though the tool is included. Check out Busybox manual for more details.
To conserve memory, only single instance of an application can be running at any given time. If the application is already running, it will only receive a message about the new invocation, such as "open file 'foo'" and top itself. The user can switch to another, already running application either by using the Task Navigator UI, or by closing the topmost application.
Because the device does not have enough memory to run all the applications at the same time, the system may kill an application in the background, Background killing is done only if the application has indicated itself to be killable. Applications exit when the user closes them from the application UI, or when the system requests for it.
Applications are executed (i.e. activated) by the D-BUS session-bus daemon. If not running, an application is implicitly activated, when a message with the auto-activation flag is sent to the corresponding service. D-BUS gets the binary name to execute from the corresponding D-BUS .service file. The activation message may also contain parameters for the application, e.g. the name of a file to open in the application. D-Bus activation guarantees that at most one instance of the application is running at any given time.
If the service does not register within a given timeout, D-BUS assumes that the service (application) process start-up failed, and will kill the started process.
The maemo-launcher is a server that has initialized most of the data used by the applications, such as Glib types, Gtk theme and some Gtk widget classes. When it is asked by the maemo-invoker to start an application, instead of executing the application binary, it will dl-load that as a shared library, fork and call main(). With fork, the initialized data is handled as copy-on-write, i.e. shared until it is modified. If the application exits abnormally, the maemo-launcher notifies the Desktop, so that the Desktop can inform the user about it.
Because prelinking does not work with dl-loaded libraries, the maemo launcher cannot speed up the starting of applications where library linking has a larger effect on the start-up time than AF library initializations. It can still save memory, though.5.4.7 for more information.
Applications can also be started implicitly, when other applications send them D-BUS messages, e.g. to open a mime-type that application has registered to the MIME database.
Places where different applications get the (application) D-BUS service names:
D-BUS daemon looks into application .service file to know how to execute the application before delivering the message. Applications launched by the D-BUS daemon will only have one instance of them running, because D-BUS does not allow the same service name to be registered by more than one process. Applications should not care whether the recipient of their message on D-BUS is running, they should just send all messages with the auto-activation flag to cause automatic activation of the recipient when it is not running.
N.B. Using the auto-activation flag is not always desirable, e.g. when asking the application to shut down; thus the application framework does not force using the flag. An activated application will automatically appear on the foreground.
The Task Navigator supports also executing the application directly, if the application D-BUS service name is missing from its .desktop file. This way, the launched application does not need to know about D-BUS or Libosso at all, so any unmodified Open Source program that has a .desktop file can be launched this way. A single instance is not guaranteed for applications started like this.
An application can use the maemo launcher to speed up its start-up. Figure 5.2 shows how this happens in practice.environment variables that were defined at the time when the D-BUS session bus was started. D-BUS does not provide a way to change the environment variables passed to an application to be activated.
An application launched by the Task Navigator could inherit any environment variables, if such a feature is implemented to it. But when the Task Navigator uses D-BUS to launch the application, the situation is the same as directly launching the application using D-BUS.
An application launched by the maemo-launcher will inherit environment variables that were defined at the time when the maemo-launcher was started. To be able to give the applications correct (preloaded) theme, the maemo-launcher will listen on the theme changes.
Environment variables should not be used for dynamic configuration changes, since they require program restart, and D-BUS does not support that.
Locale and language changes are communicated through environment variables. As applications and their libraries also cache locale state (messages etc), changing this to use e.g. Gconf would not help. Therefore, changing the device locale or language requires restarting all applications and processes involved in the application invocation.
In case a use-case gets the system to run low in memory, the system can request applications to be background killed; see below. If there is not enough memory in the system to satisfy the application request, the application requesting more memory will be out-of-memory (OOM) killed by the kernel.
Background killing is implemented by the Task Navigator to transparently close an application, when the user does not see it and to restart the application when the user needs it again. This is possible, because applications are required to be able to save their user interface (UI) states, and the Task Navigator knows all running UI applications. An application is required to save its UI state when it goes to background, i.e. behind some other application's window.
Unfortunately, saving the UI state may not be feasible for the application in every situation (e.g. when there is a download in progress), that is why the application notifies the Task Navigator when it has saved the state and can be killed. Task Navigator will kill all the killable applications when the system notifies that it is low on memory. When the application is started again, it is required to rebuild the UI according to the saved state, if such exists. The Task Navigator will not try to (re-)start an application, if there is not enough memory in the system for that. Problems with background killing in maemo:
If a device is restarted, the UI states will be discarded, so that the applications will start from their default state. Each application with different version number will have its own UI state file. This means that if application is updated (its version number given in libosso initialization is changed), it will start from the default state.
N.B. The applications should call "forced autosave" libosso function, when they go to background (libosso does not know when this happens).
The X Window System is an architecture-independent client/server system that allows multiple programs to interact with a user via a graphical (pixel-based) screen, keyboard and a pointing device (traditionally a mouse).
The program that wants to display something to the user, and read input from the user is called the X client. Each X client connects to one X server, which will perform the requested graphics operations and relay keyboard and pointer events back to the client.
When speaking about clients and servers, it is easy to make the mistake of reversing the meaning of client and server. It helps to think about the roles from the standpoint of the application, not the user. When the client starts, it will connect to an X server to create a window. A window is a rectangular area, into which the client can draw. N.B. The client can ask the server to position the window at a specific screen location, but normally does not. There is a special kind of client that will handle the placement of the windows of all other clients. This client is called the window manager. The window manager usually draws some graphical elements around each client's window, so that the user can more easily tell the boundaries between the windows. It also handles all HID-events in the window decoration areas, implements window minimizing, closing, etc. The HID-events that occur within the client area of the window are passed to the client.
There are a lot of different window managers, but most work in a similar way. The "Desktop" (whatever the word means inside a computer) is normally implemented by yet another client. Also the taskbar that might be visible is yet another client. Even the screen saver is a separate client. In real world, there are some exceptions to the above arrangement, but having separate clients for all the elements is the most common case.
The protocol that clients use with the server is called X11. It is stream-based and bi-directional (for obvious reasons).
Clients can commonly connect to the server in two ways:
How does the client know where to connect? By using an environmental variable called DISPLAY. There are only a handful of applications that know how to implement the X11-protocol, because it is quite complicated to encode and decode. Normally clients will use a library called Xlib, which was developed for this purpose. Xlib also contains the logic to read the DISPLAY-variable and will get the address to connect to from the contents of the variable. It is also possible to tell the client to use a specific display via a command line parameter (display=). The parameter will be processed internally by Xlib and override the environmental variable (if any).
The content of the DISPLAY-variable consists of two parts:
So, for example: DISPLAY=remote.machine.com:0.0 would mean the first screen on the first X server running on remote.machine.com. When starting an X server, it can normally be told which screen to create and control.
What about the "similar to TCP but not quite" UNIX domain socket? Xlib will connect using a system-specific file system path when the hostname portion is empty. To try it out on the Linux desktop, type echo $DISPLAY in a terminal emulator. The graphical terminal emulator will connect to the X server knowing the DISPLAY variable. It most probably is :0.0, unless there is a more complicated system (e.g. split dual-head).
To instruct an X client to connect to another X server, it is then necessary to modify the environmental variable: export DISPLAY=:2.0 for example. Then start the X client, and it will at least try to connect to the X server specified. In the example above, the server is running on the same system as the client (the hostname part is empty). Since the screen part is optional, also export DISPLAY=:2 can be used.
This all may not seem to be related to maemo, but the connection will be explained in the following part on installing the environment and testing the applications.
It should be remembered that X11 is architecture-independent. This means that applications running on Internet Tablets (ARM-binaries) can connect to an X server running on a x86/PC Linux (or even to an X server running on Apple OS X, Windows or other operating systems).
As a side note, the Internet Tablet has an X server as well. It runs as :0.0. It is a special version of an X server that requires less memory, and has been configured to support most of the extensions used on the Linux desktop. The version on the Internet Tablet is based on the Kdrive version of the X.Org X server. However, a Linux desktop is running a regular X.Org server.
N.B. By default, most modern Linux distributions ship with the X server not listening for network connections. They will only accept local connections through the UNIX domain socket (/tmp/.X11-unix/X0, where 0 is server screen number).
For more information on X, please see the X.Org-project pages and X Window System WWW links. Also, ssh can be used to tunnel X11 connections securely over networks. Please see X Over SSH2 Tutorial for examples.
When another application sends a message to the application requesting some functionality (e.g. the File Manager tells the image viewer to show a file), it is automatically started (but not yet topped) by the D-BUS daemon (if it is not already running, and auto-activation is desired). When the application receives the message, it can raise its window, if the operation requires user interaction.
When an application is launched by the D-BUS daemon, the Task Navigator compares the WM_CLASS property of the opened application window to the StartupWMClass field in the application .desktop files to see for which application it belongs to. WM_CLASS window property is automatically set to the application binary name by Gtk. Application icons in the Task Navigator application launcher and switcher menus are also taken from the .desktop file.
If the application WM_CLASS does not match StartupWMClass of any .desktop file, there will be no icon for the application in the Task Navigator application switcher, and the user cannot switch back to the application. This is a limitation of the current Task Navigator, and hopefully fixed in later products.
At any given time, there can be visible none or any number of System-UI windows.
The topmost (active) window always performs pointer and keyboard grabs. Normal application menus do also these grabs; in OSSO they are required (modified) to close and release grabs when another window comes above them.
All of the System-UI windows are taken care of by the same process, which has a certain internal stacking order for them. I.e. same window comes always in the same position, but all of them might not be visible or even exist at the same time.
There is also a 1x1 window outside the screen, always mapped to catch Gtk theme change messages.
This pinging is performed by the Matchbox window manager when:
If a maemo-launched application terminates abnormally, maemo-launcher will send a message to the Desktop, which will inform user about it.
|glibc||The core C library API|
|Glib||Utility library, basic types, memory management, dynamic strings, linked lists, etc.|
|GObject||The object model API of GTK+ & GNOME.|
|GTK+||GTK+ graphical user interface widget set library.|
|gdk-pixbuf||GTK+ Bitmap image handling.|
|libosso||maemo base library, application initialization etc.|
|Hildon APIs||maemo Hildon APIs.|
|GStreamer||GStreamer multimedia framework.|
|libxml2||XML and HTML parser and tools.|
|libpango||Text rendering framework.|
|D-BUS||Inter-process communication framework.|
|GConf||Configration management framework.|
|libcurl||HTTP access library.|
|SQLite||SQL database library.|
|LibC++||Standard library for C++ language.|
|GnomeVFS||Filesystem Abstraction library.|
|HAL||Hardware Abstraction Layer Specification.|
|libconic||Internet Connectivity library.|
|libebook||Evolution Addressbook Library.|
CPU Architecture Differences
Whereas Debian supports multiple CPU architectures, Ubuntu's set is a bit more restricted. Compared to that, maemo is an embedded ARM EABI distribution. Maemo
is also cross-compiled, instead of natively compiled, like Debian or Ubuntu. Maemo also
uses different versions of toolchains (GCC, glibc etc.) than Ubuntu or Debian for
ARM feature support and maturity differences between architectures.
Security Model Differences
Instead of a multi-user system, such as a traditional Linux desktop, maemo is considered a single-user desktop system. The security model in maemo is focused on protecting the user from remote attacks and from themselves, not from other users. Maemo also uses suid root binaries and /etc/password, whereas Ubuntu enforces the use of sudo and shadow passwords.
Unlike Ubuntu, maemo makes use of a root account like Debian does, but has a trivial default password. The user should really change the root password before installing
e.g. OpenSSH to the device with root login.
Base System Differences
The greatest difference in the base system is that maemo uses a lightweight BusyBox  replacement for the essential GNU utilities on the device e.g. ls and sh. In maemo, kernel and initfs reside in separate partitions and cannot be updated with a package manager like with a common desktop Linux. Programs in initfs use uClibc instead of glibc. Ubuntu has Perl and Python languages as essential packages, Debian has only Perl and maemo has neither. Maemo has no debconf. Ubuntu uses Upstart for device start-up instead of SYSV init scripts used in maemo.