Kindle 3.2.1 Jailbreak (Update)

When I first released the Kindle 3.2.1 jailbreak, I called it “temporary.” Although confusing to use and set up, it has gotten thousands of hits and reports of success. However, it was “temporary” because the method used depended on some precise timing and I had a better method that I was saving for Kindle 3.3. Now, I realize that 3.3 will never come, but will instead be 4.0 that will come with Kindle 4, and with a new hardware, everything doesn’t matter. Serge A. Levin has independently discovered a similar bug for what I was going to use on the 3.3 jailbreak, and I’ve asked him to release it because he deserves the credit for the work. If we’re lucky, Amazon will fix the bug in a way that my similar plan for 3.3/4.0 will still work.

(If you are already jailbroken, regardless of what version you’re running, you don’t need to download this. The actual jailbreak hasn’t been updated, just the injection method.)

Also, if you think that the jailbreak didn’t work, try installing a custom package anyways. I have fixed many people’s “I can’t get it working” by telling them that it’s already jailbroken.

Link to jailbreak for all devices on all versions.

EDIT: It seems like there is some confusion so I’ll clear this up. Jailbreaking does NOT remove ads.

One more thing: custom recovery kernel for Kindle 3

I didn’t plan to do any more Kindle stuff for a while, but when I made a recovery kernel (prevents your Kindle from bricking) for the Kindle 2/DX as part of my 3.X installer, many asked for a similar protective thing on newer Kindles. Well, here it is.

For now it’s just a kernel with recovery features (export entire filesystem without password or serial port and install custom recovery packages), but maybe if I have the time, one day, I will make it a full custom kernel with additional features or something.

Kindle 3.2.1 Jailbreak

UPDATE: Serge A. Levin has kindly modified my “temporary” jailbreak into a more permanent solution. The information below is now considered old and should be disregarded. Link to jailbreak for all devices on all versions.

 

So I never intended to release a jailbreak for Kindle 3.2.1 because 1) people who got a discount for their Kindles should stick by their commitment and keep the ads and 2) this was an update made purely to disable jailbreaks, so there are no new features. However, from what I heard, more and more people are receiving 3.2.1 as stock firmware (not just ad-supported Kindles) and that people who exchanged their broken Kindles also have 3.2.1. I don’t want to reveal the exploit I found yet (I’m saving it for the next big update), but thankfully, after half an hour of digging, I’ve found another glitch that I can use. The bad news is that this isn’t an “easy one click” jailbreak, it will actually take some effort as some precise timing needs to be correct in order to work.

Technical Details

What is this new glitch you ask? It’s pretty simple and pretty stupid and I feel almost embarrassed to use it (that’s why I’m not even using the word exploit). First of all, the last bug I found was fixed by a regex name check that prevent spaces in names. Now, whenever the Kindle gets an update, before doing anything, it looks for the signature of every file in the update (minus the signature files themselves). They do this by using the “find” command to get a file list and piping the output to “read” where “read” feeds each data (separated by a whitespace) into the signature check function where the function proceeds to use OpenSSL to check the signature. Simple enough. Well, what I want to do is make the signature check ignore a file, and to do it, I make a blank file called “\” (literally a backslash). Now it’s hard to explain what happens, so I’ll show you.

Here’s the output of the find command usually:

$ find /tmp/update

/tmp/update/file.ext

/tmp/update/file2.ext

Now, when I insert my slash-file:

$ find /tmp/update

/tmp/update/file.ext

/tmp/update//tmp/update/file2.ext

What happened? The backslash is used in Linux as an escape character. Basically it says to treat the next character as not-special. Remember that “read” splits the data to be read using whitespace (in this case a new line character), so by escaping the whitespace, I can get the system to ignore /tmp/update/file2.ext, and instead get it to read /tmp/update/tmp/update/file2.ext. In that file, I will include an already signed file from an old Amazon update, and when the updater runs, it ignores the extra files and reads the unsigned file. But we’re not done yet. Amazon doesn’t extract the update to a set folder, it extracts it to /tmp/.update-tmp.$$ where $$ means the process id of the script running. This can be any number from 1 to 32768. So what’s the elegant solution to this problem? I don’t know yet. Until someone can come up with a better idea, I’m going to include PIDs 5000-7000. From my tests, if you run it immediately after a reboot, it will be 64xx, so it’s a test of how bad you want to jailbreak ;)

Installation

Since this jailbreak is time and luck based, I’ve included very detailed directions on the exact timing for doing things in the readme. I suggest reading over the directions before starting, because timing is everything. It works only in a certain window of time after startup, so if it doesn’t work you need to restart and try again. If it doesn’t work after three or more tries, it’s mostly my fault as I only tested it with a Kindle 2 so the timing might be different on the Kindle 3. If you have serial port access on your Kindle 3, send me the otaup log and I’ll change the pid set.

Download

Since this is a temporary fix, I’m not going to add this to my projects list.

Download source and binaries here

EDIT: I’ve heard from some users that you have more chance of succeeding if you don’t have any books to load. So, before doing anything, rename the documents folder to documents.bak and the system folder to system.bak, install the jailbreak, and rename everything back. This should allow more chance of succeeding.

EDIT 2: Some people report turning the wireless off before starting also increases success rates.

Kindle 3.X updater for Kindle 2 and Kindle DX released

After a month and a half of testing thanks to the community of MobileRead, I can finally release the first stable version of the Kindle 3.X software updater (help me come up with a better name, please). If you haven’t read my last few Kindle-related posts (read them if you want more technical details of this script), you should know that this allows you to use all the cool new features of the Kindle 3 on a K2 or DX device. Installation is easy and is only three steps: 1) Use “prepare-kindle” script on old Kindle to back up and flash recovery kernel, 2) Copy generated files to Kindle 3 along with “create-updater” script and run it, 3) Copy generated update package back to old Kindle and restart. If that sounds confusing, don’t worry, the readme contains very detailed directions and even how to recover in case anything goes wrong. Speaking of recovery, a “side effect” of using this is that the custom kernel that you flash in order to run the update package allows recovering without a serial cable and the installation of unsigned recovery packages.

Here it is.

Oh, and in case anyone is wondering why I’m not just distributing a full 3.X update package and making you generate it by yourself, it’s because the Kindle framework and OS are proprietary code. I believe that Amazon didn’t release 3.0 for the DX and K2 because they don’t want to lose business for the Kindle 3. So, by making you have a Kindle 3 in order to use this, I can keep Amazon happy.

Porting Kindle 3.1: Part 2 – Update encryption

Overview

So, on the topic of Kindle (I swear, it’s becoming an obsession). I am currently in the process of porting the Kindle 3.1 software to Kindle 2 and DX. I will make a series of posts describing my process while describing how various parts of the Kindle operating system works. Now I’ve tested 3.1 on my Kindle 2 and it works perfectly fine. All features work (audio, TTS, book reading), and the new features also work without major slowdowns (new PDF reader, new browser, etc).

Where’s part one you ask? Well, part one was getting the 3.1 OS to work on the Kindle 2, the rest is making an easy installer. That is a long story that involves custom partition tables, manually creating tar files (checksums are a pain), remote debugging, and more. It’s a lot of stuff and most aren’t very useful because nobody should have to repeat the process, which is why I’m creating a easy to use installer. If I have time one day, I may write it down for documentation purposes.

First of all, I will write down the game plan. What I plan to do is create an installer with the least amount of steps for the user. I’m hoping for a two part or three part installer. (Can’t be one part because you need a copy of the OS, and distributing it is most likely frowned upon by Amazon). How the installer should work is:

  1. User copies a image-creator package on a jail-broken Kindle 2. This package will backup the original OS, and generate a new ext3 image with some required files from the Kindle 2 (drivers and such). It will also update the kernel to support recovery packages.
  2. User keeps backup in a safe place and copies the image-creator package and the image generated from the K2 on a jail-broken Kindle 3 and runs the package. The image-creator will scan the filesystem making sure all files exist are are unmodified, then copies the files to the ext3 image. It will then take the ext3 image and generate a Kindle 2 recovery package with the 3.1 OS.
  3. User copies the recovery package generated from the Kindle 3 and copies it to the Kindle 2 and restarts. The Kindle will write the ext3 image to the root partition.

Update Encryption

Now, Igor Skochinsky wrote a nice post a couple of years ago on the Kindle update encryption algorithm. Basically, to encrypt an update, you take each byte of the file and shift the bits four to the left and OR it with the same bits shifted four to the right. Then you AND the result by 0xFF and XOR it by 0x7A. (Sounds like some computer dance move). Well, Igor also wrote a nice Python script that does the encrypting and decrypting, but I didn’t want to port Python to Kindle, so I decided to modify Amazon’s update decryption script “dm” and reverse it to make a encryption script “md”. I opened up IDA Pro and looked for the encryption. Here it is nicely commented by me into psudocode:

BL getchar // get byte to modify

EOR R3, R0, #0x7A // R3 = R0 ^ 0x7A

CMN R0, #1 // if !(R0 == 1), we are at the end of the file …

MOV R0, R3,LSR#4 // R0 = R3 >> 4

AND R0, R0, #0xF // R0 = R0 & 0xF

ORR R0, R0, R3,LSL#4 // R0 = R0 | R3 << 4

BNE loc_8470 // … then jump to end of program

MOV R0, #0 // clear R0 register

ADD SP, SP, #4 // don’t care

LDMFD SP!, {PC} // don’t care

It was a simple matter of reversing the instructions and registers, but like I said before, IDA Pro does not allow changing instructions directly, so I had to mess around with the machine code in the hex editor until I made the instructions I want. Here’s the modified function nicely commented by me in human.

BL getchar // get byte to modify

CMN R0, #1 // if byte is 0×01, then …

MOV R3, R0,LSR#4 // set R0 to R0 right shift 4

AND R3, R3, #0xF // set R4 to R4 logical AND 0xF

ORR R3, R3, R0,LSL#4 // set R3 to R3 logical OR ( R0 left shift 4 )

EOR R0, R3, #0x7A // set R0 to R3 logical exclusive OR 0x7A

BNE loc_8470 // … exit program

MOV R0, #0 // clear register R0

ADD SP, SP, #4 // don’t care

LDMFD SP!, {PC} // don’t care

If you want to try it out, here’s the bspatch from “dm” to “md”. MD5 of dm is 6725ac822654b97355facd138f86d438 and after patching, md should be 3b650bcf4021b41d70796d93e1aad658. You can copy md to your Kindle’s /usr/sbin and test it out:

echo ‘hello world’ | md > hello.bin # “md” encrypt ‘hello world’ and output to hello.bin

cat hello.bin | dm # “dm” decrypt hello.bin and it should output ‘hello world’

Now that we can create update packages from the Kindle, I can start working on the Kindle 2 image-creator script.

Recovering a formatted or corrupt Kindle 2

One day, while playing around with a Kindle 2, I accidentally deleted the /lib folder. Oops. Now, no command beyond “ls” and “rm” work. If this was a computer, I could have simply inserted a installation DVD and copied the files over, but this was an eBook reader, and I was in for a world of pain. This was a month ago, and I’ve finally recovered the Kindle. I’m posting what I did online to save anyone else who’s in the same boat a ton of time. This tutorial is only designed for the Kindle 2, but it MAY work for the DX. It will NOT work for the Kindle 3, but directions should be similar.

 

First

If you’ve think you “bricked” your Kindle, don’t panic yet. There could be a easy solution. Chances are, if you can see the startup progress bar loading, the solution should be easier (although I can’t tell you exactly what your problem is). I would follow Amazon’s troubleshooting directions first. Only proceed if you are absolutely sure nothing else can be done.

Overview

Here’s what you’ll need

  1. TTL to RS232 or USB connector. I used this one. For that, use the jumper on pin 1 and 2 on the side (with the three pins, pin 1 is towards the USB port). Connect Kindle Tx -> Tx, Rx -> Rx, GND -> GND, VDD -> VDD
  2. Windows with HyperTerminal (I tried Kermit on Linux, but it couldn’t send files. HyperTerminal is the only program I’ve tested that works sending files to the Kindle)
  3. Linux or Unix-based computer with “dd” and “ssh”
  4. My custom recovery kernel which allows jailbreak signed recovery packages and exporting MMC0 without a password. If you want to know how I’ve made it in technical details, see the appendix.

Here’s what we’ll be doing:

  1. Attaching the recovery port
  2. Flashing the custom patched recovery kernel
  3. Obtaining a backup of Kindle system files
  4. Restoring your Kindle

Attaching the recovery port

First open up the Kindle 2 to reveal the PCB board. You should remove both the metal casing and the white plastic with all the screws. On the top, to the left of the headphone jack, you should see four pads labeled J4. Either solder (recommended) or tape (make sure it isn’t lose!) four wires to these pads. The order of these ports (left to right, where left is towards the volume switch) are: VDD, Rx, Tx, GND. Connect these lines to your TTL adapter and connect the adapter to your computer.

Flashing the custom patched recovery kernel

Open up HyperTerminal, and connect to your adapter. Make sure to click “Configure” and fill in the settings. The settings are: BPS: 115200, Data bits: 8, Parity: none, Stop bits: 1, Flow control: none. Then, restart your Kindle either by removing & reconnecting the battery, holding the sleep switch for 30 seconds, or tapping the reset switch on the PCB. Press Enter when text pops up in HyperTerminal. You only have one second, so be quick. In uBook, type in “run prg_kernel_serial” (make sure to type fast or uBoot will timeout). Then right click on the text, and choose “Send File”. Under protocol, choose Ymodem-G and for the file, select my custom kernel. Wait a few minutes for it to upload and install, then type in “bootm 0xa0060000″ to boot the kernel. The Kindle has two kernels that it alternates on each boot, so if you want to use my recovery kernel, you need to either flash the other kernel also or type in “bootm 0xa0060000″ into uboot on startup. Hold down Enter either on your computer or on the Kindle to enter the recovery menu. The recovery menu times out in 10 seconds, so you need to be quick. First type “I” to recreate all the partitions, then type “3″ to export the MMC. Again, these can be typed from either your keyboard in HyperTerminal, or the Kindle keypad. If you do not have access to HyperTerminal because you are in Linux restoring, you can get back here by holding Enter on the Kindle keypad and pressing 3 on the recovery menu.

Obtaining a backup of Kindle system files

Let’s put your broken Kindle aside. You need a working copy of Kindle’s system files. I cannot provide this for legal reasons, but if you obtain another Kindle 2 (preferably the same model and version as your broken one, but others MAY work [not Kindle 3 though... yet]), jailbreak it and install the usbNetwork hack for SSH access. Make sure that Kindle has at least 500MB of free space on the FAT partition to store the backup image. Once you SSH’d into the working Kindle (there are tons of tutorials around on this), issue the following command:

dd if=/dev/mmcblk0p1 of=/mnt/us/rootfs.img bs=1024

Note that this will only make a copy of the OS files. All personal information, passwords, books, etc are not copied. You can tell your friend that. This may take five to fifteen minutes to run, but when the command returns with the blocks written, you can disable usbNetwork and enable USB storage again. Copy the rootfs.img file over to your recovery computer and prepare to restore.

Restoring your Kindle

Back to your broken Kindle. You need to reformat the root and copy over the backup files. I moved the Kindle over to a Linux computer because it is easier. You can also use OSX or maybe even cygwin, but I haven’t tested. In shell, type in the following commands:

sudo su # Become root, so you don’t need to sudo everything

fdisk -l # Look for your Kindle’s identifier, it should be something like /dev/sdc, it should be a 2GB drive with 4 partitions. I will use /dev/sdX to represent this drive

mkfs.ext3 /dev/sdX2 # Make a ext3 partition for /var/local

dd if=/path/to/rootfs.img of=/dev/sdX1 bs=1MiB # This will take a long time to finish

Note that an alternative method is to gzip rootfs.img and place it into a recovery package created using kindle_update_tool.py, but I’ll leave that as an exercise for the reader.

Appendix

So, what is in the magical Kindle recovery kernel? It’s actually just a regular Kindle kernel recompiled with a modified initramfs with a patched recovery script. Using the regular kernel, you’ll run into two difficulties when trying to recover. First, if you press 3 to export MMC0, you’ll get a password prompt. Good luck brute forcing it. Second, if you build a custom recovery package using kindle_update_tool.py m –k2 –sign –fb, it will not work because of signature checks. What I did was patch the two checks.

First, I extracted the recovery-utils file by gunzipping uImage (with the extra stuff stripped out), and gunzipped initramfs.cpio from that. Then I extracted initramfs.cpio and found recovery-utils under /bin.

Next, the easy part is patching the updater package signature checks. What I did is extract the updater RSA public key file from the Kindle, found under /etc/uks and used OpenSSL to extract the public key from it (n and e). Then I opened recovery-utils with a hex editor, searched for the public key, and replaced it with the jailbreak key (found in kindle_update_tool.py).

Finally, the challenging part was to patch the password check from export MMC0. First I opened recovery-utils with IDA Pro. Then I located the check_pass function. I worked backwards from that and saw it was called from loc_94A8. Here’s a snippet of the check along with my interpretation of what it does:

BL check_pass # Call the check_pass function

CMP R0, #0 # check_pass sets register R0 with the return value, we will check if R0 equals 0×0

BEQ loc_9604 # If the previous instruction is true, then password check has failed

LDR R0, =aDevMmcblk0 ; “/dev/mmcblk0″ # We did not jump out, so CMP R0, #0 is false

BL storage_export # Call this function

It’s always easy to patch the least amount of instructions with the least amount of changes, so this is what I did. (Note that IDA Pro doesn’t allow editing instructions directly, so I have to find the machine code in hex to know what to replace. Luckily, I have tons to instructions to look at and see what their corresponding machine codes are).

NOP # Instead of calling check_pass, I did MOV R0, R0 which is the same as NOP

CMN R0, R0 # Negative compare R0 with itself. Basically, always return false.

… rest is the same

Now, I saved the file and luckily, it was the same size. So I didn’t have to recreate the initramfs.cpio, I just replaced the file inside with my hex editor (note that cpio files do not have checksum checks unlike tar files). I copied this to the kernel source folder and compiled the kernel. Lucky for you, I have already done all of this so you don’t have to.

Kindle 3.1 Jailbreak

I was bored one weekend and decided to jailbreak the new Kindle firmware. It was time consuming to find bugs, but not difficult. Unlike the iPhone, the Kindle doesn’t really have security. They have a verified FS and signed updates and that’s it, but I will still call my jailbreak an “exploit” just to piss you off. Previous Kindle 3 jailbreaks worked (AFAIK, I haven’t really looked into it) by tricking the Kindle into running a custom script by redirecting a signed script using a syslink. This worked because the updater scans only “files” that do not end with “.sig” (signature files to validate the file). They fixed this now by scanning all non-directorys that do no end with “.sig”. This is the first bug I’ve exploited. Part one is getting the files into the update, which I did by conventionally renaming them to “.sig” even though they’re not signature files. Part two is harder, getting the unsigned script to run.

How the Kindle updater works is that first it gets a list of all files (including files in subfolders, excluding signature files) in the update and checks it’s signature with Amazon’s public keys. If you modify any of the scripts from a previous update, the signature is broken and the Kindle won’t run it. If you add your own scripts, you can’t sign it because you don’t have Amazon’s keys, and finding them would take more then the lifespan of the universe. (SHA256 HMAC). They also use OpenSSL to check the signatures, so trying to buffer overflow or something is out of question (or is it? I haven’t looked into it). Afterwards, when all files are matched with their signatures and checked, the updater reads a “.dat” file which contains a list of all scripts, their MD5 hash and size (to verify, I don’t see the point since they were just signature checked. Maybe a sanity check?). It finds the “.dat” file using “find update*.dat | xargs” which means all the .dat file has to be is start with update and end with .dat. They don’t care what is in between. Next, they read the file using “cat” and with each entry, verify the hash and loads the script. Well, conventionally, “cat” can read multiple files if more then one filename is given in the input. This means if the update*.dat file contains spaces, then “cat” will read every “filename” separated by a space. I took a signed .dat from one of Amazon’s update. Renamed it “update loader.sig .dat” and placed my actual .dat (containing an entry to the script jailbreak.sig, a shell script renamed) in loader.sig. jailbreak.sig untars payload.sig, a renamed tgz file which contains the new keys we want to use to allow custom updates. Amazon’s updater only signature checks “update loader.sig .dat” which is valid. Then cat tries to read the files “update”, “loader.sig”, and “.dat”, one of which exists and the others silently fail. Loader.sig points to the script jailbreak.sig which the updater happily loads thinking it’s already signature checked. Jailbreak.sig, calls tar to extract payload.sig and copies the new keys to /etc/uks and installs a init.d script to allow reverting to Amazon’s keys for installing future updates. Now we own the system again!

tl;dr:

A download to the jailbreak can be found here. Directions are provided in the readme file. Use it at your own risk (I’m not responsible if you somehow brick it) and note that it most likely will void your warranty. Make sure to uninstall all custom updates before you uninstall the jailbreak, as after uninstalling the jailbreak, you cannot run custom packages until you jailbreak again. Directions for switching between custom updates and Amazon updates can be found in the readme file.

Compiling the Linux kernel for Amazon Kindle

So, I recently bought a Kindle 2. As usual, the minute it arrived, I ripped it apart, poked every chip, and then started to reverse engineer the damn thing. Wait. I didn’t have to! I found this out days late, after messing with IDA Pro. Amazon has generously released most of the back end code for the Kindle as open source. (The front end, aka the stuff you see, is written in Java and we might get to that another day). So I decided to compile my own Kindle kernel. Why? Why not. Here’s how:

Part 1: Prerequisites

  • Get a root shell of your Kindle. If you don’t know, Google “usbNetworking”
  • A Linux computer for compiling code
  • Amazon’s sources for your version of the Kindle: http://www.amazon.com/gp/help/customer/display.html?nodeId=200203720
  • An ARM cross-compiler. You can compile Amazon’s code, or if you’re lazy, use CodeSourcery’s precompiled toolchain: http://www.codesourcery.com/sgpp/lite/arm
  • The following packages, get them from your distro’s repo: libncurses-dev (for menuconfig), uboot-mkimage (for making the kernel image), and module-init-tools (depmod)

Part 2: Compiling the kernel

  1. Extract the source to anywhere. If you can’t decide, use “~/src/kernel/” and “cd” to the source files.
  2. Now, you need to configure for the Kindle, type “make mario_mx_defconfig
  3. Edit the “.config” file and look for the line that starts with “CONFIG_INITRAMFS_SOURCE“. We don’t need that, delete that line or comment (#) it out.
  4. Here’s the part were you make all your modifications to the kernel. You might want to do “make menuconfig” and add extra drivers/modules. I’ll wait while you do that.
  5. Back? Let’s do the actual compiling. Type the following: “make ARCH=arm CROSS_COMPILE=~/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi- uImage”. This will make the kernel image. I assume you installed CodeSourcery’s cross compiler to your home folder (default). If your cross compiler is elsewhere, change the command to match it.
  6. Compile the modules into a compressed TAR archive (for easy moving to the kindle): “make ARCH=arm CROSS_COMPILE=~/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi- targz-pkg” (again, if your cross compiler is installed to a different location, change it).
  7. For some reason, depmod refuses to run with the compile script, so we’re going to do it manually. Do the following “depmod -ae -F System.map -b tar-install -r 2.6.22.19-lab126 -n > modules.dep” Change 2.6.22.19-lab126 to your compiled kernel version.
  8. Open modules.dep up with a text editor and do a search & replace. Replace all instances of “kernel/” with “/lib/modules/2.6.22.19-lab126/kernel/” (again, use your version string). I’m not sure this is needed, but better safe then brick.
  9. Now copy arch/arm/boot/uImage, linux-2.6.22.19-lab126.tar.gz (or whatever your version is), and modules.dep to an easy to access location.

Part 3: Installing on Kindle

  1. Connect the Kindle to your computer, and open up the storage device. Copy the three files you moved from the previous part to your Kindle via USB.
  2. This part is mostly commands, so get a root shell to your Kindle, and do the following commands line by line. Again, anywhere the version string “2.6.22.19-lab126” is used, change it to your kernel’s version. Explanation follows.

mv /mnt/us/linux-2.6.22.19-lab126.tar.gz /mnt/us/modules.dep /mnt/us/uImage /tmp

mv /lib/modules /lib/modules.old

cd /tmp & tar xvzf /tmp/linux-2.6.22.19-lab126.tar.gz

mv lib/modules /lib/

chmod 644 modules.dep

mv modules.dep /lib/modules/2.6.22.19-lab126/

/test/flashtools/update-kernel-both uImage

sync

shutdown -r now

Wow, that’s a lot of commands. What did that do? Well, line by line:

  1. Move the files we compiled to the temp folder. That way, we don’t have to clean up.
  2. Back up the old kernel modules
  3. Go to the temp folder and untar the modules
  4. Install the modules
  5. Correct the permissions for the modules.dep file (in case something happened after copying from your computer)
  6. Move the module dependencies list to it’s correct folder.
  7. Flash the kernel (I don’t know why it has to be flashed twice to two different partitions, but if you don’t, it won’t load, maybe sig checks?)
  8. Make sure everything is finished writing
  9. Reboot