An Overview of the iPhone Architecture

The iPhone architecture, although generally out of the scope of application development, is a very simplistic design in terms of operating system theory. A decent understanding of it is necessary for a detailed overview of the iPhone’s functionality, and this article may help to satisfy the curiosity of those interested in how it works (i.e. geeks) but whom lack an available document describing it.

First off, the following (hastily-made) diagram provides a graphical overview of the entire process of how hardware interaction is provided to and from the iPhone software:

strongDiagram of the iPhones Archicture/strong

Diagram of the iPhone's Archicture

 

This layered (and color-coded, for the non-colorblind) diagram will serve as a graphical overview of the iPhone’s entire input/output process. Computer engineers should probably start at the bottom, and computer scientists should start at the top :) .

(you may notice that we have both a hardware layer AND a processor layer, and the reason is this: the hardware refers to the actual chips of the device’s peripherals, e.g. gyros or display, whereas the processor deals more with the ARM instruction set at the assembly level – just to clear up any resulting confusion. For more of an overview of the diagram, see the layers section below.)

Example 1: Hardware to Application: Gyros

Now, the easiest way to break this down is via example, so we’ll use the gyros (the thingies that detect when you turn the iPhone to the side, A.K.A. Accelerometers), starting from the hardware:

  1. Physical gyros detect a movement change, raise a bit (or modify a register) to indicate the change
  2. Firmware detects the change, notes that the value indicates that the state of the iPhone is now different (as opposed to an erroneous value), and sends a processor interrupt through the system bus for attention.
  3. The iPhone’s ARM processor receives the interrupt, and calls an in-memory interrupt service routine (ISR) that the iPhone operating system set up during driver initialization.
  4. The ISR, a function (subroutine) located within the code for the iPhone OS, acknowledges the interrupt and begins to process it via the corresponding driver. The OS itself sends a signal to the current active application (if any) in the form of a Unix-style signal.
  5. This signal is handled according to the specifications of the C/Objective-C runtimes, since the iPhone application compiler and linker constructs the application specifically to do this rather than handle the signal directly. The Objective-C runtime forwards the signal as a framework-specific message to the application, first checking whether the current application has been designed to handle said message.
  6. If the message is able to be processed via a method (subroutine) within the application, then the message is received and processed. In the case of our gyro example, the application will adjust it’s interface to display in widescreen (landscape) format for the display. Depending on the message type, the framework may also check whether or not the application indicates an error in the processing of message, and may perform additional actions in this case.

This example shows an overview of the process in which a hardware action is processed by software. This same process is used for touchscreen input, sound input, and camera input. The buttons on the top and bottom of the iPhone are more OS-specific, however: the menu button merely sends a termination signal to the application so it can perform any closing tasks (such as file writing, etc.), whereas the topmost button triggers a power management/scheduler routine that simply suspends the current application and turns off the touchscreen to conserve battery life.

Example 2: Application to Hardware: Display

Now that we’ve provided an example of how the iPhone application receives hardware-caused messages, lets now look at how the application requests an action of the hardware. For this example, we’ll use graphical display:

  1. The application, now loaded into memory and starting its execution, wishes to display an image for a splash screen. We’ll assume that the process of loading the image from storage is complete, and we now simply have to display the image on the touchscreen hardware for the user to see.
  2. The application makes an API (framework) call, something along the lines of -(void)setBackgroundImage, passing a reference to the image within the call (which is, at the lowest level, the starting memory address or hard drive reference of where the image is stored, the type of the image, and the length of the image).
  3. The API/framework receives the function call, and does the dirty work of translating the higher-level image processing interface into a collection of calls to the Objective-C runtime, which will then make the appropriate calls to the C library.
  4. The (dynamically-linked) C library, having received a series of function calls from the Objective-C runtime and corresponding frameworks and APIs, will further refine the functions into assembly-level system calls (via a software interrupt) which the iPhone OS kernel can process.
  5. The iPhone OS kernel, having received the system calls in assembly format from the C library, will then call upon the appropriate drivers (the touchscreen display drivers, in this case) to interact with the hardware. The drivers will, at the lowest level, set the registers of the touchscreen display’s chips in order to display the right colors at the appropriate coordinates in order to display the image as requested by the application.
  6. Now we’ve reached the hardware level, where the physical display screen is being changed so as to display the image for user’s eyes to see.

Whew! Still with us? You may be wondering why there are three different API/framework/library calls needed just to tell the kernel to start mucking with the hardware. This, my friend, is one of the joys of working with an underlying Unix operating system: providing a high-level, developer-friendly interface to an almost 40 year-old operating system architecture (recall that XNU is based upon the Mach kernel, and uses the olde Unix system call convention for kernel requests).

The frameworks/API is the set of functions the developer wants to see in order to make his/her application interact with the device and underlying iPhone OS. Well the framework, which is part of the overall Objective-C runtime, is really just a series of upper-level function calls (and C extensions, in the case of the Obj-C runtime) in order to allow a more developer-friendly interface to the grimy, obfuscated (and undocumented) C library.

The C library lies underneath the Objective-C runtime, and in fact makes up the Obj-C runtime, providing true object oriented dynamic-typing extensions to the C language (unlike C++, which just looks object-oriented). The C library is dynamically linked to from the Objective-C runtime to “translate” messages requiring lower-level intervention into UNIX system calls, where the iPhone OS can process them as needed.

This process can be seen using GDB on an iPhone application mostly in the default “thread 2″ of a given application, with the lower-level calls resulting in dyld_* (dynamic linkage) system calls or even processor interrupts shown in the assembly language itself.

Some immediately learn this and think, “Gee, why don’t developers just use the C library or system calls directly?”, and the answer is this: it’s both unnecessarily hard to do, and largely undocumented. Why would you want to take over twice the time to develop an app using the C library when the much easier to use Objective-C API and frameworks are staring you in the face? And, Apple has their own private functions within the C library that they don’t document, and you probably don’t want to use them anyways for app development (and the compiler/linker generally keeps you from doing so).

 

strongDiagram of the iPhones Archicture/strong

Diagram of the iPhone's Archicture

The diagram we showed above is meant to provide an overview of the iPhone OS architecture, but just to clear up what each of the layers cover, here is a description of each layer:

  • Application: This is the currently-running iPhone application, purchased through the app store (unless jailbroken firmware is used). This application was compiled to native code by the Apple-distributed iPhone compiler, and linked with the Objective-C runtime and C library by the linker. This application also runs entirely within the userspace environment set up by the iPhone OS.
  • Frameworks/API: Cocoa Touch, upper-level OpenGL calls, its all in here. These API calls are simply Apple-distributed headers with the iPhone SDK, with some dynamic linking occuring at runtime. These reside on top of the Objective-C runtime, as many of these are written in Objective-C.
  • Objective-C runtime: This layer is comprised of both the Objective-C dynamically-linked runtime libraries, as well as the underlying C libraries. The C library sets up the environment for the Objective-C runtime so much that I simply included them both within the same layer (although I should have probably called it “runtime libraries” instead).
  • iPhone OS: This is the kernel, drivers, and services that comprise of the iPhone Operating System. This is sometimes called iPhone OS, iPhone OS X, or just OS X, but it all refers to the same deal: it sits between the userspace and hardware.
  • Processor: Not so much the physical ARM chip (that’s contained within the hardware layer), but instead referring to the ARM instruction set and the interrupt descriptor table as set up by the iPhone OS during boot and driver initialization.
  • Firmware: Although we refer to the entire OS as “firmware” sometimes (especially in respect to jailbreaking), this layer instead references the chip-specific code that is either contained with memory in/around the peripheral itself, or within the driver for said peripheral (example: touch screen or gyroscope)
  • Hardware: Pretty obvious, but refers to the physical chips soldered to the iPhone’s circuitry. If you can feel/see it, it’s under this layer. The actual processor falls under this layer, but the instruction set and in-memory descriptor tables are contained within the “processor” layer.

Last notes

As a final detail, I want to say something about the iPhone OS scheduler and how it works closely with the iPhone’s power management. I mentioned earlier how the button atop the iPhone/iPod suspends the currently running app in order to enter a low-power state, and this demonstrates both the special power management features built in to the iPhone to conserve battery life, as well as the scheduler’s ability to halt a currently-running program and resume it later.

The scheduler itself is capable of running a full iPhone process (app) in the background, but up until the 3.0 beta this has been restricted to Apple applications such as the Mail application. The scheduler/kernel apparently keeps track of which process ID is currently the “active one”, in order to send signals (received as messages via the libraries) to the right process, instead of telling the background-running mail app that the iPhone was just tilted instead of Safari.

Jailbroken iPhone/iPod apps are able to currently run background apps on the current OS version, so there is either an undocumented system call for doing so, or else the jailbreakers are modifying the iPhone scheduler to enable the functionality. I’d lean more towards the undocumented feature, however, since it seems more logical and jailbreaking gives access to the C runtimes for disassembly and inspection for these undocumented routines.

That said, I’m glad Apple finally allows official apps to run in the background, and allowing this functionality will not only benefit more developers but also leave one less reason (amongst plenty) to jailbreak the iPhone/iPod.

The iPhone/iPod operating system has a very simplistic architecture although things get a little muchy when it comes to how signals are passed to and from the different libraries and the kernel. This is expected, however, when you consider the Unix-style system call convention we’ve been using since the stone ages (and copied by other systems). A good book for a more detailed overview of this is The UNIX-Haters Handbook, available online.

With that, I hope everyone is “enlightened” as far as how the iPhone works.



About Anthony:



Anthony Cargile is the founder and former editor-in-chief of The Coffee Desk. He is currently employed by a private company as an e-commerce web designer, and has extensive experience in many programming languages, networking technologies and operating system theory and design. He currently develops for several open source projects in his free time from school and work.

Comments (8)

 

  1. Vagrant says:

    Ah, I understand now. When you said, “but up until the 3.0 beta” I thought you meant that the 3.0 beta finally allowed it, but I misunderstood.

    Thank you for your very educational article and feedback. It’s quite refreshing!

  2. Anthony says:

    @Vagrant

    It is _possible_ via jailbreaking, which I’m pretty sure I either referenced or hinted at in the article.

    http://thecoffeedesk.com/news/index.php/2009/07/20/iphone-firmware-definition/ – as Mark said in another article, iPhone OS is just Darwin Unix, allowing daemons to run in the background etc.

    I wouldn’t recommend this, but you could conceivably write an app that inspects the value of a text file on a webserver. Once the app passes Apple review, you could change the value of the text and have the app download some precompiled ARM code to run as a daemon in the background.

    I might write this in an article (think I will), but its just one way to achieve daemon programming until Apple allows it “officially”.

    But, all the more reason, jailbreaking prevails as the way to do what you really want to do with the iPhone.

  3. Vagrant says:

    Anthony, you indicated that in OS 3.0 the iPhone could run non-Apple apps in the background, but I have not found a way to do this. In fact, most reports say it is still not possible. I am trying to write an alarm app that sends an alert to the user at random times during the day. Obviously not a battery hog, but seemingly not possible.

  4. nilges says:

    Getting it to stream to a real AirTunes server (i.e. an Airport Express) is all I really had in mind. Just one of those things that one assumes should be possible right out of the box, but isn’t. The program that makes this possible on Macs for sources other than iTunes is called Airfoil, by Rogue Amoeba, who has the most extensive discussion of doing this for iPhone in a blog entry here:
    http://www.rogueamoeba.com/utm/2008/12/12/thoughts-on-airfoil-for-iphone/

  5. Anthony says:

    I haven’t read the O’Reilly book on iPhone development, but as far as having “Open” iPhone development, it really depends on how “open” you’re trying to be without jailbreaking. A pulseaudio-like application for the iPhone would be difficult without direct hardware access for the reasons you suggested: DRM, and Apple hardware trade secrecy.

    You might have better luck convincing an iPhone to stream to a computer/device “pretending” to be AirTunes, although some handshaking research is needed. After capturing the stream, you could then manipulate it like you’d want or route it to another device (such as a pulseaudio node). I hope that helps, because there’s not much to be done to circumvent Apple’s hefty restrictions on iPhone development.

  6. nilges says:

    I knew it was unsupported now, and probably will be forever, since access to raw audio data circumvents DRM. Only thing I’ve heard about in 3.0 that remotely applies to this is allowing apps to access the iTunes library, but almost certainly just for API-managed playback. Macs even need a third-party app to output anything besides iTunes to Apple’s AirTunes. The jailbreakers have done some amazing things. Can you suggest any resources for what’s currently known about iPhone Open Application Development? There’s an O’Reilly book by that title written by someone in that community. Any good?

  7. Anthony says:

    @nilges: This is currently (as far as I know) not supported by the iPhone’s APIs and frameworks, but jailbreaking offers the functionality you are suggesting via currently experimental kernel modification via hotpatching and/or loadable drivers. You can probably experiment with this until Apple releases a sort of global sound redirection feature to its API, to get pulseaudio-style remote streaming.

  8. nilges says:

    Great article. So given how much Apple would like the iPhone to remain a closed system, what do you think would be the best approach to coding something (app? device driver?) that could intercept any audio being played by other apps and DO THINGS with it, like, oh, say, stream it to a music server over WiFi?

Leave a Reply