Nov 24

After a huge amount of effort and in-situ experimentation with iBoot (basically a binary massive binary search through the code, disabling some functions to see if I could figure out why my LCD driver wasn't working properly), I managed to get it fully working. The problem was two-fold: first, I forgot to write the first and last bytes of my gamma tables: oops, but easily fixed. The second problem was that apparently iBoot changes the SDIV of the clock in the middle of the initialization process. I'm not even sure yet how many devices the change in clock frequency affects. It certainly affected the LCD, because before there was all sorts of flickering scanline weirdness as one would expect from a misconfigured clock.

Anyway, I reversed the routine that changed the SDIV and implemented it. Seems to work fine now. It's been ages since I looked into the clock speed stuff (pretty much right when I first started this) so I can't say for certain, but I'm pretty sure doing this increases the clock speed (which would make sense).

The LCD driver worked after those fixes and I went onto write a simple framebuffer in a couple of hours, so we can finally get text-mode output on the iPhone screen. It was pretty important to me to get the screen working because even if we can boot a kernel, I wanted the layman to feel like a full-fledged OS was running on the device, and that means display and I/O of some sort.

For a final hurrah, I also wrote some code that lets us detect when the physical buttons (Home, Hold, etc.) were being pressed down. From these pieces, it will be possible to construct a graphical boot menu controlled by those buttons. You could have one option to boot into the iPhone OS, and one option to go into openiboot command-line mode with that text-mode display.

The photo I posted is the current development snapshot running on a first generation iPhone, with oibc (openiboot client) connected and running on my desktop computer. If you have a 2G iPhone or a first-gen iPod touch, you can try it out yourself by checking out the code from Github and compiling it (It's only designed to be built on a Linux machine. You'll be missing some Linux headers otherwise). I wrote some basic notes on how to get it running inside the source tree, but this is not something you're expected to work with unless you're a fairly experience programmer yourself.

Tagi: command line mode, development snapshot, clock frequency, clock speed, lcd driver, coue, boot menu, ipod touch, binary search, current development, would make sense, framebuffer, text mode, opti, weirdness, layman, iphe, desktop computer, iboot, butts

Nov 24

Well, that was quick. See, I can actually get things done pretty quickly when it doesn't consisting of banging my head against machine code until it starts making sense. When I actually have the drivers, things like this are easy.

You can use the Hold button to toggle between the menu items (and the option will be highlighted). You can choose the home button to select it. The "openiboot console" option takes you to the command-line interface similar to the one I demonstrated in the last post (you do have to be plugged in via USB and using the openiboot client to talk to it). The "iPhone OS" option chainloads a copy of iBoot stored in NOR under another identifier ('ibot' becomes openiboot and 'ibox' becomes the actual iBoot). I got that set up with a slightly modified version of the QuickPwn ramdisk, but in the future an installer made from a modified version of LogoMe can be run from userland to install openiboot. It's also possible to get openiboot to install openiboot (much like the way GRUB can do it); I'll probably work on that next.

So if anyone likes living on the bleeding edge, they could do that. =P

Most of the hard part was me failing at GIMP putting together the boot menu graphics. I appealed to you blog readers for graphics before, but basically no one responded. Now that there is a working model of what I sort of want, I hope there will be more of a response.

So, please please please redesign the boot menu for me. And possibly come up with a logo for the project we can stick on there. If you're good at this sort of thing, or know someone who is, please put them in touch. This stuff will obviously get a lot of attention in the future and we need nice eye-candy. Thanks!

Tagi: command line interface, candy thanks, boot menu, menu graphics, somee, eye candy, banging my head, working model, opti, bleeding edge, iboot, userland, gimp, grub, ibot, butt

Nov 24
I've been getting a lot of questions from people that seem to reflect a basic misunderstanding of what it takes to port an operating system onto a new platform. People seem to think that just by writing, say, a boot menu, means that we can stick Android or Windows or whatever onto a device because we can have a menu option for it.

Here's what it takes for an operating system to run on a device:
  • The code must be designed for the right CPU. (x86, ARM, PPC)
  • The code must be able to interact with the hardware in the way it expects.
Now, there are versions of Linux compiled in ARM (which the iPhone uses), there are even versions of Windows Mobile that are compiled in ARM. Why can't I, then, just stick Windows Mobile or Android (or another flavor of Linux) onto the iPhone and give it a whirl?

Because the code cannot interact with the hardware! That is, there are no Linux drivers or Windows Mobile drivers for the hardware that's on the iPhone. We're not even talking about things like the wi-fi won't work or anything silly like that. We're talking about big things, like not being able to start because it doesn't uncompress itself into RAM properly. We're talking about freezing the first time it has to wait for something to happen because it doesn't know how to run the hardware clocks and timers (which is CRITICAL for computers) and doesn't know when to start again.

Thus , if I tried to take some distribution of Linux or Windows or whatever, stick it in memory and start it, absolutely nothing will happen. That's right: nothing. There will be no output because it doesn't know how to run the display, or the USB, or serial. It probably won't even get to the first line of code that tells it to output something because so many things are broken.

So how can we get Linux to boot on the iPhone?

By teaching it how to run the hardware. We take the knowledge gained from getting that boot menu to display and graft it into the Linux kernel. It took an unbelievable amount of devices just to get the boot menu display: clock, timer, vic, mmu, spi, i2c, gpio, system controller, pmu, nor, uart, usb, lcd, buttons. Some of those may seem obvious to you, some work in the background to support the other devices. But all of those had to be reverse engineered and all of them will have to transplanted into the Linux kernel to even get something half-assed booting.

If all of those devices were required to get something as simple as boot menu up, can you imagine what would happen if you tried to boot an operating system that did not know how to run ANY of those devices?

We cannot modify the Windows Mobile kernel because it's closed source, and so there's no way to get it to run on the iPhone.

The critical misunderstanding, I think, is that people think somehow that the OS "sits on top" of the boot menu, and talks to the hardware through the boot menu. Therefore, you can have an "emulation layer" that lets Windows or Linux or whatever talk to the hardware, without having to alter Windows or Linux itself. This is completely false. An operating system, by definition, has direct access to the hardware. Nothing sits between it and the hardware. Once iBoot has loaded the iPhone OS, you can go ahead and wipe it clean from the NOR and the OS will keep running as usual. It's not "running", it's not used or loaded in any way except during the boot process.

The iPhone will never run Windows Mobile directly (virtualization would be possible albeit it would crawl on the iPhone). It will run Linux once we write the drivers for it based on our knowledge of the hardware. Android uses the Linux kernel, though they do modify it to a certain extent. Since the only really hardware dependent parts of an OS is in the kernel, presumably once we install the necessary drivers, Android will run just as well as Linux runs. However, not having even looked at Android's source yet, I really don't have a truly educated opinion at the moment, but let's just say that it's one of this project's primary goals.

Sorry this is so long, but intelligent explanations tend to be long.

P.S. Another question people ask a lot is how long will it take. I can't truly give a good answer to that, because it's sort of dependent on the schedules of the people who work on it, and it also depends on how fast it'll take to write the Linux drivers, and how many unexpected problems crop up. It could go really unexpectedly fast, or we could hit a roadblock. I think outside observers, just reading the commit logs and reading the blog has as much information as I do on how fast things are progressing, so you're free to come up with your own conclusions on how long it will take.

Tagi: clock timer, iphe, day clock, versis, linux kernel, cpu x86, boot menu, linux drivers, mmu, android, opti, whirl, wi fi, graft, spi, knowledge gained from, many things, timers, vic, clocks

Nov 24
While I was waiting for CPICH to finish the first bits of the NAND FTL reverse engineering work, I've been trying to fill in some of the gaps we had in other places, such as the PMU. As promised, there is also now an easy way to install openiboot onto the iPhone. This is great because it will eventually lead to an even leaner and easier QuickPwn in the future.

One of the annoying parts about iBoot in recovery mode is that the thing refuses to charge the iPhone while sitting in recovery mode. The battery just eventually entirely drains. With the new PMU code, openiboot now recharges the battery, so programmers using it (read: me) can just have it sit on the console screen indefinitely. You can also do neat things like check the current battery voltage and check the power supply type the phone is charging from.

The "installation code" consists of porting over my knowledge of reading and modifying img3 files from working on the jailbreaks. I was too lazy to port over the entire xpwn framework, but I wrote up a "diet" version that is sufficient to read and modify img3 files in a limited fashion. img3 files are sort of the new native format of the main part of the NOR (just a bunch of img3 files concatenated together). The upshot is that you can load openiboot as an img3 through iBoot (just like sending an iBEC image) and then type "install" at the console and openiboot will be a permanent stage in your bootloader chain. =P

You can, of course, keep booting up to the iPhone OS as you always do by selecting the option in the boot menu. Installing openiboot isn't very useful except for hackers wanting to hack openiboot.

I also figured out how to parse and modify the NVRAM banks (storing environment variables like "auto-boot", etc.), which was actually pointless complicated (in my opinion). They have two banks consisting of a bunch of partitions with these headers that Apple uses a pointless one-byte custom checksum on. The entire bank is also checksumed with adler32. When NVRAM is modified, the oldest bank is overwritten with the data and becomes the newest bank (which is tracked by an epoch number on each bank). This is so if one bank becomes corrupted, the other can be used as a backup. However, NVRAM hardly contains anything high value so the value of all this trouble is doubtful. Being able to write to NVRAM, though, makes it possible to set auto-boot on and off within openiboot so that we can easily control whether or not to enter iBoot's recovery mode.

Someone asked me how "safe" it was to do the installation, etc. Well, I've been doing it every time I make an update these days, so it's fairly safe. The worst that can happen in the usual case is that you may be forced into a DFU mode restore. Everything will be undone with a restore. Early on, I did have bugs that really screwed things up so that a DFU mode restore was no longer possible, but even that was recoverable. I'll just go over how briefly:

The important thing is to have a backup of the NOR. As I described in a previous posting, it's possible to really screw things up if you erase the SysCfg section of the NOR. If you do that, the iPhone OS will refuse to boot at all since iBoot cannot properly populate the device tree for the kernel. Since restore ramdisks rely on XNU booting, this is Bad News Bears. In addition, the SysCfg section is device specific, so if you do not have a backup, it will be difficult to ever completely recover from erasing it.

Therefore, before you proceed, MAKE A BACKUP OF YOUR NOR. openiboot can do this for you (and subsequently restore your backup if things go wrong).

Load openiboot via loadibec and select the console. Connect with the oibc client. Type in: nor_read 0x09000000 0x0 0x100000

This will read all of NOR into memory. Then type: ~nordump.bin:0x100000

This will transfer the dump over USB onto your computer and save it as nordump.bin.

Supposing you filled the entire NOR with garbage somehow and are unable to boot. You have to get into openiboot to restore the NOR. The problem is that openiboot is only designed to operate in a post-LLB or post-Recovery Mode context, so it cannot be directly booted from DFU mode. Basically, you've got to load a pwned WTF, then a pwned iBSS, and then a pwned iBEC (all of which is available from a custom IPSW). After that, you can use loadibec to load openiboot. Then, you can restore the NOR thus:

!nordump.bin
nor_write 0x09000000 0x0 0x100000

After that, you can reboot and everything should be normal.

Also, I received a few responses for people volunteering to do the art. I'm not sure what the best thing would be, since I don't want anyone putting in effort for nothing, but we do want the best possible results. So, I'll be getting back to you guys about that.

Tagi: recovery mode, csts, fashi, boot menu, auto boot, battery voltage, promed, pmu, iphe, nand, iboot, phe, upshot, opti, aces, gaps, programmers, hackers, variables, banks

Dec 1
I think the best way to handle this is for anyone interested to submit a proposal via e-mail to me about the boot menu. Then, I can put up the pictures on the blog for people to comment and have an opinion about. We can then figure out which one to use or maybe some combination of proposals or in any case, figure it out in a collaborative community style process.

I don't really have an opinion on what the logo should look like, whether it should be cartoony or not. I only think it should look good. =P

There are very few technical constraints on the boot menu. I'm willing to figure out whatever technical solution there needs be in order to get things to display properly. One thing to keep in mind is that space on the NOR is at a significant premium, and raw pixel data is expensive but procedurally generated stuff like gradients are possible. The only two current menu options are the iPhone OS and the openiboot console, but eventually a Linux option will be added. I can try animation as well, but again, you'd have to have an idea of how it can be done without using up a lot of NOR space.

But yeah, make us pretty!

Some progress on the NAND: Thanks to a huge amount of initial grunt work by CPICH, the NAND project is off the ground. We already have enough to get the proper drive geometries, and I've written and tested the DMA routines that are near the heart of the problem today. Hopefully, we can dump the raw NAND soon and take a peek at what kind of wear leveling data structures we're dealing with.

Tagi: grunt work, community style, boot menu, heart of the problem, optis, pixel data, collaborative community, geometries, e mail, gradients, opti, data structures, peek, proposals, peoe, proposal, linux, blog

next >