Saturday, January 26, 2008

Finally got a clean way to boot from the internal MMC on the N810!

The next step for me was to get the N810 to boot from the internal MMC. Following the instructions on the wiki, I got something half working. After going through a few hoops I eventually got it right, with no side effects that I could see (besides the faster load times ;). Another problem was that the literature available so far doesn't really apply to the latest OS2000 version (2.2007.50-2). I'll write a more complete how-to later, but here's a quick outline of the steps:
  1. The first thing is to setup a boot menu. One of the problems I had here was that the initfs was seeing the internal card as mmcblk1 whilst the OS once booted sees it as mmcblk0. Well, actually once booted the kernel still sees the internal as mmcblk1:
    ~ $ cat /proc/partitions
    major minor #blocks name

    254 0 7977472 mmcblk0
    254 1 7973376 mmcblk0p1
    254 8 1966080 mmcblk1
    254 9 1441791 mmcblk1p1
    254 10 524288 mmcblk1p2
    But udev seems to swap them when creating the entries in /dev:
    ~ $ ls -l /dev/mmcblk*
    brw-rw---- 1 root floppy 254, 8 Jan 26 14:44 /dev/mmcblk0
    brw-rw---- 1 root floppy 254, 9 Jan 26 14:55 /dev/mmcblk0p1
    brw-rw---- 1 root floppy 254, 10 Jan 1 1970 /dev/mmcblk0p2
    brw-rw---- 1 root floppy 254, 0 Jan 26 14:44 /dev/mmcblk1
    brw-rw---- 1 root floppy 254, 1 Jan 26 14:56 /dev/mmcblk1p1
    It's very likely a kernel bug and seems to occur only on N810. When trying to boot from MMC, this causes two problems:

    • With no external SD card plugged in, the boot menu sees the internal one as mmcblk0, which is fine. But as soon as there's an external card plugged in, the internal one becomes mmcblk1. The obvious problem here is that the boot menu won't behave in a consistent manner depending on the card configuration.

    • Once booted, and with an external card plugged in, the root of the file system will be mounted on mmcblk1p2, which doesn't exist.

    I initially tried to fix the second problem (which seems purely cosmetic) by rewriting the mmcblk* nodes in the initfs and completely ignored the more serious issues caused by the inconsistent behaviour of the boot menu.

    Graham Cobb came up with a very elegant way to make the boot menu always boot from the internal card, regardless of the presence of an external one.

  2. Now that the boot menu is patched, let's move on to partitioning and copying the root file system. And reboot from MMC!

  3. Now we need to fix USB mounting. It'll break at some point because the system tries to unmount every mmcblk*p*, including the root filesystem (mounted on /dev/mmcblk1p2....) and bails out as soon as there's an error. The fix is to edit /usr/sbin/ so that it doesn't try to unmount "/". Changing
    if [ $? = 0 ]
    if [ $? = 0 -a "$MP" != "/" ]
    should to the trick.

  4. Alright, got the USB working but a Linux host will mount the root partition as well! This time the problem is that the whole disk is shared over USB. i.e. it shares mmcblk0 and mmcblk1, not individual partitions. This time the fix is to edit /usr/sbin/ so that it shares only the first partition of a device instead of the whole device. Basically, add something like DEVICE=${1}p1 near the beginning of the file and replace all instances of $1 with $DEVICE.
Now I can flash the N810 back to the original firmware and poke around some more :)




heelio said...

Have you stumbled across any means of triple booting yet (i.e., having two bootable partitions on an MMC (I am trying it on an N800 but no luck yet))? What is that command to list partitions you used - how does it work? I got permission denied when I tried it on N800.

Denis Bernard said...

No, I haven't tried triple booting yet as I have no need for it. But if you're still looking for a solution to the problem, may be I can help. Although I have to warn you that I haven't played with that in a while and my N810 is now back to the official kernel, single boot.

the command to list the partitions just displays the contents of the pseudo-file /proc/partitions. You may need to be root in order to have read access to this file.