[WIP] Booting NST from the sd card

Search This thread

probbiethe1

Senior Member
Mar 22, 2010
320
8
This is still a work in progress but the Nook Simple Touch can now boot from the sd card. If you would like to learn how view klausef's comments in post number 27 (http://xdaforums.com/showpost.php?p=25325319&postcount=27).

I will continue to update this post when there is new information

Thanks to klausef for working on this and creating a solution to my question.
Thanks to all of those that contribute to nookdevs and thanks to everyone else that has commented on this topic.
 
Last edited:

Googie2149

Senior Member
Jan 6, 2012
291
54
I wonder what would happen if I were to write a backup of the Nook onto an SD card and put it in (with the Nook itself wiped so it can't boot from the internal flash)
 

mali100

Senior Member
Jun 3, 2007
209
140
Nothing, because the mountpoints are wrong.

It should be possible, but I never tried it:
-partition and format the sd in a similiar way like the nook,
-unpack the uRamdisk and edit the mountpoints in the init.rc from mmcblk0 to mmcblk1

Again, I'm not sure if it works, thats what I read somewhere. And even if it works, it will be slow if you don't use a really fast sd-card.
 

Googie2149

Senior Member
Jan 6, 2012
291
54
Nothing, because the mountpoints are wrong.

It should be possible, but I never tried it:
-partition and format the sd in a similiar way like the nook,
-unpack the uRamdisk and edit the mountpoints in the init.rc from mmcblk0 to mmcblk1

Again, I'm not sure if it works, thats what I read somewhere. And even if it works, it will be slow if you don't use a really fast sd-card.

Onwards to experimentation!!!!
 

probbiethe1

Senior Member
Mar 22, 2010
320
8
So it is possible thats good news. Do we know of any body thats working on it? or can someone instruct me on how to edit the files that need to be edit?
 

klausef

Senior Member
Jul 17, 2011
57
31
Raleigh
Forgive me if this explanation goes through too basic of things for you but I am trying to establish context. Basically here's the status:

When you hit the power button on the nook touch, it calls some bootloader software called UBoot, that's kind of like a BIOS for embedded systems. UBoot looks for a file called UImage and a file called URamdisk. These two files contain the kernel and the root filesystem (and maybe a few other things, I've not taken the time to learn too much about UBoot). When UBoot finds these files, it loads them to RAM and starts executing the kernel.

Now the first thing the kernel is going to do when it starts up is to run the program 'init.' Init performs all the necessary stuff to start the system as you know it. Part of what init does is run a script called 'init.rc.' This script does a lot of things, but an important part of what it does is mount all these partitions.

So all we have to do to run the device off an SD card is to get UBoot to use the UImage and URamdisk from the SD card instead of internal memory! It turns out that this has actually been done before. This method is exactly what touchNooter did to root our nooks. Of course, it was created with other things in mind.

What I did was burn an exact copy of the nook's internal memory to an SD card, but then took the files from the touchNooter image that make UBoot work, and copied them over to the boot partition of the SD card. I'm not sure that you have to copy all the files I did, but anyway here's the ones I took from touchNooter:

u-boot.bin
cfg.bin
boot.scr (This is essentially a UBoot script that tells it what to do with UImage and URamdisk to set up the rootfs and start the Kernel)

I also made all of the boot images black so I would be able to tell if the nook was using the SD card.

When I stuck the SD card in and rebooted, lo and behold, the screen went black all the way through the boot process. It worked! The only issue is, it turns out that init and init.rc are somehow loaded into the UImage or URamdisk, so when init runs, it still mounts the partitions that are on the nook's internal storage. From this, we can deduce that the only thing running from the SD card is the kernel, and everything else is as before.

The solution to this is to recompile the UImage and URamdisk using B&N's provided source with an edited init.rc to mount the SD card's partitions. Another way we could do it is to somehow edit 'boot.scr' to make UBoot to pass an argument to the kernel when it gets started to use a different, modified init. (Much like pushing `esc` on a linux bootscreen and typing init=<binary>)

The first solution is harder but more correct, while the second solution is easier but much more hackish.

I am somewhat new to UBoot so I would appreciate it if someone else could correct any inaccuracies I may have made.
 
Last edited:
  • Like
Reactions: fortunz

ApokrifX

Senior Member
May 23, 2011
468
50
The solution to this is to recompile the UImage and URamdisk using B&N's provided source with an edited init.rc to mount the SD card's partitions.
You can easily unpack/edit/pack URamdisk
mali100 explained everything and posted scripts here. I’m reposting his scripts below:
Unpack (xuramdisk)
Code:
#!/bin/bash
#if (test $# -eq 1 && -f $1)
if [ -f $1 ]; then
  dd if=$1 bs=64 skip=1 of=rdisk.gz
  # Uncompress
  gunzip rdisk.gz
  # Extract
  mkdir ramdisk
  cd ramdisk
  cpio -iv < ../rdisk
else
  echo "No Ramdisk found"
fi
pack (mkuramdisk)
Code:
#!/bin/bash
find . -regex "./.*"| cpio -ov -H newc | gzip > ../ramdisk.gz 
mkimage  -A ARM -T RAMDisk -n Image -d ../ramdisk.gz ../uRamdisk
 
  • Like
Reactions: klausef

ApokrifX

Senior Member
May 23, 2011
468
50
That's great! Even as you have it right now, this could be a great way to test new kernels!
If nook doesn’t boot, but respond to shutdown button still,
you can replace uImage or uRamdisk on nook internal SD by booting from noogie (well known fact)
or removing external SD card.

Otherwise (nook doesn't respond to shutdown button - semi-bricks)
you need to open it and disconnect battery or wait till it got discharged completely
And you may need to pop nook open to start it charging again in some cases

Either way, I don’t see how booting from external SD card helping much with kernel testing.
Am I missing something obvious? :eek:
 

klausef

Senior Member
Jul 17, 2011
57
31
Raleigh
I use my Nook to read textbooks for all my classes so I cannot afford to experiment through the internal memory.

At any rate, digging around the forum it turns out that people have known this for a while (OP even mentioned it in the first post), so I apologize for the bulk of that post.

I tried editing the init.rc to mount the SD card's partitions (replaced all /dev/block/mmcblk0 with /dev/block/mmcblk1) and it seems to just hang. ( I made sure to wait a long time to make sure it wasn't just lagging from the speed of the card reader, although I may not have waited long enough... )

This lead me to believe that the card reader is not initialized yet. To test this hypothesis I edited init.rc back to something that worked, but this time added `ls /dev/block/ > /data/blocks` right after the data partition is mounted, to find out all the block devices the Nook sees at this point. Unfortunately, after the system starts up I found no file named 'blocks' in /data/blocks.

EDIT: Found the culprit! After boot, I looked at dmesg:

Code:
 init: /init.rc: 19: invalid command 'ls'

So we can't use `ls` for this. No problemo, I'll just pack busybox into the uRamdisk and use `ls` from there.
 
Last edited:
  • Like
Reactions: fortunz

probbiethe1

Senior Member
Mar 22, 2010
320
8
I use my Nook to read textbooks for all my classes so I cannot afford to experiment through the internal memory.

At any rate, digging around the forum it turns out that people have known this for a while (OP even mentioned it in the first post), so I apologize for the bulk of that post.

I tried editing the init.rc to mount the SD card's partitions (replaced all /dev/block/mmcblk0 with /dev/block/mmcblk1) and it seems to just hang. ( I made sure to wait a long time to make sure it wasn't just lagging from the speed of the card reader, although I may not have waited long enough... )

This lead me to believe that the card reader is not initialized yet. To test this hypothesis I edited init.rc back to something that worked, but this time added `ls /dev/block/ > /data/blocks` right after the data partition is mounted, to find out all the block devices the Nook sees at this point. Unfortunately, after the system starts up I found no file named 'blocks' in /data/blocks.

EDIT: Found the culprit! After boot, I looked at dmesg:

Code:
 init: /init.rc: 19: invalid command 'ls'

So we can't use `ls` for this. No problemo, I'll just pack busybox into the uRamdisk and use `ls` from there.

Wow sounds like your really making progress. Let me know if there is anything I can do to help.
 

klausef

Senior Member
Jul 17, 2011
57
31
Raleigh
Wow sounds like your really making progress. Let me know if there is anything I can do to help.
Haha thank you but nah, most of the stuff that I have done is known. I'm mostly just trying to replicate and document what has been done as precisely as possible.

Would it be easier to use cat? (this is not a snarky remark)

I am not sure cat would work in this case since we are trying to get a directory listing of the directory /dev/block/, not concatenate or list two files.

Anyhow, it turns out that 'init.rc' is not a bash script, but instead uses the syntax described here: http://www.kandroid.org/online-pdk/guide/bring_up.html (See 'Android Init Language' section)
 
  • Like
Reactions: fortunz

klausef

Senior Member
Jul 17, 2011
57
31
Raleigh
Per the documentation I have invoked a script through init.rc. The script is very simple. I included a busybox binary in the uRamdisk at /busybox, so that's what it's based on:

Code:
#/busybox ash 
/busybox ls /dev/block/ > /data/blocks;

I have verified that the script works by first running it on an up-and-running nook and it worked properly. (That is, it created a populated file in /data/blocks and then terminated)

The script is called through the init.rc right after it finishes mounting all the partitions:
Code:
   service lsdev /lsdev.sh
   oneshot

When I start up the nook with this init.rc it hangs on boot. I also tried calling the script using `exec` instead of `service` but it still hangs.

In other news, I noticed dmesg finds mmcblk1 (the SD card) around the same time it finds the internal memory. See this dmesg snippet:

Code:
<6>[   22.080810] twl4030_rtc twl4030_rtc: setting system clock to 2012-04-15 00:48:42 UTC (1334450922)
<6>[   22.090759] mmc0: new high speed MMC card at address 0001
<6>[   22.096801] Freeing init memory: 164K
<6>[   22.106384] mmcblk0: mmc0:0001 SEM02G 1.82 GiB 
<6>[   22.111450]  mmcblk0: p1 p2 p3 p4 < p5 p6 p7 p8 >
<4>[   22.238494] EXT2-fs warning: mounting unchecked fs, running e2fsck is recommended
<4>[   22.321990] mmc1: host does not support reading read-only switch. assuming write-enable.
<6>[   22.330841] mmc1: new high speed SDHC card at address 1234
[B]<6>[   22.337280] mmcblk1: mmc1:1234 SA04G 3.67 GiB [/B]
<6>[   22.342651]  mmcblk1: p1 p2 p3 p4 < p5 p6 p7 p8 >

The Nook is failing to boot for some other reason than because it doesn't see the SD card. I previously assumed the opposite, which is why I've been going through this big init.rc exercise to verify it. (I was expecting not to see a /dev/mmcblk1p*)

It is my assumption that this has something to do with how the stock userland is set up, so I'm going to call it a day, then shift my focus to compiling a new kernel and userland instead of just aimlessly trying to get this one to run off the SD card.

Please don't let that doesn't discourage any of you from further contributing to this thread's original goal, because it would still be immensely useful to the development process.

Good day, all. Thanks for the help.
 
Last edited:
  • Like
Reactions: fortunz

Top Liked Posts

  • There are no posts matching your filters.
  • 2
    The hack for mounting a fake SD card from a booted SD card system is really fake, some programs like Opera see through it by checking an environmental var. This could be avoided if someone wrote an app to set the environmental variable
    Code:
    'EXTERNAL_STORAGE_STATE'
    to 'MEDIA_MOUNTED' or something, possibly using:
    Code:
    System.setProperty('property_name', 'value');

    Once I get time I might hash up a simple app that toggles faking the SD card by `mount -o bind` in conjunction with this. Feel free to beat me to doing this, anyone; Java is not my forte...

    I found programs saw through the bind mount as well... This worked for me, though:

    1. mount -o bind /media /sdcard
    2. setprop EXTERNAL_STORAGE_STATE mounted
    3. am broadcast -a android.intent.action.MEDIA_MOUNTED --ez read-write false -d file:///sdcard

    You could put this in your init.rc or rc.local if you'd like it to happen at start up...
    1
    Forgive me if this explanation goes through too basic of things for you but I am trying to establish context. Basically here's the status:

    When you hit the power button on the nook touch, it calls some bootloader software called UBoot, that's kind of like a BIOS for embedded systems. UBoot looks for a file called UImage and a file called URamdisk. These two files contain the kernel and the root filesystem (and maybe a few other things, I've not taken the time to learn too much about UBoot). When UBoot finds these files, it loads them to RAM and starts executing the kernel.

    Now the first thing the kernel is going to do when it starts up is to run the program 'init.' Init performs all the necessary stuff to start the system as you know it. Part of what init does is run a script called 'init.rc.' This script does a lot of things, but an important part of what it does is mount all these partitions.

    So all we have to do to run the device off an SD card is to get UBoot to use the UImage and URamdisk from the SD card instead of internal memory! It turns out that this has actually been done before. This method is exactly what touchNooter did to root our nooks. Of course, it was created with other things in mind.

    What I did was burn an exact copy of the nook's internal memory to an SD card, but then took the files from the touchNooter image that make UBoot work, and copied them over to the boot partition of the SD card. I'm not sure that you have to copy all the files I did, but anyway here's the ones I took from touchNooter:

    u-boot.bin
    cfg.bin
    boot.scr (This is essentially a UBoot script that tells it what to do with UImage and URamdisk to set up the rootfs and start the Kernel)

    I also made all of the boot images black so I would be able to tell if the nook was using the SD card.

    When I stuck the SD card in and rebooted, lo and behold, the screen went black all the way through the boot process. It worked! The only issue is, it turns out that init and init.rc are somehow loaded into the UImage or URamdisk, so when init runs, it still mounts the partitions that are on the nook's internal storage. From this, we can deduce that the only thing running from the SD card is the kernel, and everything else is as before.

    The solution to this is to recompile the UImage and URamdisk using B&N's provided source with an edited init.rc to mount the SD card's partitions. Another way we could do it is to somehow edit 'boot.scr' to make UBoot to pass an argument to the kernel when it gets started to use a different, modified init. (Much like pushing `esc` on a linux bootscreen and typing init=<binary>)

    The first solution is harder but more correct, while the second solution is easier but much more hackish.

    I am somewhat new to UBoot so I would appreciate it if someone else could correct any inaccuracies I may have made.
    1
    The solution to this is to recompile the UImage and URamdisk using B&N's provided source with an edited init.rc to mount the SD card's partitions.
    You can easily unpack/edit/pack URamdisk
    mali100 explained everything and posted scripts here. I’m reposting his scripts below:
    Unpack (xuramdisk)
    Code:
    #!/bin/bash
    #if (test $# -eq 1 && -f $1)
    if [ -f $1 ]; then
      dd if=$1 bs=64 skip=1 of=rdisk.gz
      # Uncompress
      gunzip rdisk.gz
      # Extract
      mkdir ramdisk
      cd ramdisk
      cpio -iv < ../rdisk
    else
      echo "No Ramdisk found"
    fi
    pack (mkuramdisk)
    Code:
    #!/bin/bash
    find . -regex "./.*"| cpio -ov -H newc | gzip > ../ramdisk.gz 
    mkimage  -A ARM -T RAMDisk -n Image -d ../ramdisk.gz ../uRamdisk
    1
    I use my Nook to read textbooks for all my classes so I cannot afford to experiment through the internal memory.

    At any rate, digging around the forum it turns out that people have known this for a while (OP even mentioned it in the first post), so I apologize for the bulk of that post.

    I tried editing the init.rc to mount the SD card's partitions (replaced all /dev/block/mmcblk0 with /dev/block/mmcblk1) and it seems to just hang. ( I made sure to wait a long time to make sure it wasn't just lagging from the speed of the card reader, although I may not have waited long enough... )

    This lead me to believe that the card reader is not initialized yet. To test this hypothesis I edited init.rc back to something that worked, but this time added `ls /dev/block/ > /data/blocks` right after the data partition is mounted, to find out all the block devices the Nook sees at this point. Unfortunately, after the system starts up I found no file named 'blocks' in /data/blocks.

    EDIT: Found the culprit! After boot, I looked at dmesg:

    Code:
     init: /init.rc: 19: invalid command 'ls'

    So we can't use `ls` for this. No problemo, I'll just pack busybox into the uRamdisk and use `ls` from there.
    1
    I found programs saw through the bind mount as well... This worked for me, though:

    1. mount -o bind /media /sdcard
    2. setprop EXTERNAL_STORAGE_STATE mounted
    3. am broadcast -a android.intent.action.MEDIA_MOUNTED --ez read-write false -d file:///sdcard

    You could put this in your init.rc or rc.local if you'd like it to happen at start up...

    Yumbrad, brilliant! Thanks for the posting this. For some reason I was trying to do this through modifying Android's source. It may still be possible but there is not really a need.

    If a real SD card is inserted and removed, the last two commands might need to be run again, but that is no issue. If someone has time, they could make an app to solve this. For now you could also install SManager and make a script containing these commands, put the script as a widget on your launcher, and run the script/app as needed.