First off, I know that' I've been working on CWMR for the DX2 also. During this work though I found myself looking back at the CM7 source for hijacking and found myself getting a lot farther than I have in the past with the Motorola common hijack. CM7 is not booting yet, but this is the closest we've ever been. Special thanks to MoonShadow-NM, StringCheeseCR and balltongue for being my guinea pigs, mastafunk for helping get 2nd-init isssues worked out with our phone, and hashcode for helping me port the final steps of the hijack. I'm going to try to make this a lot shorter than my last one.
I had a few issues starting to port over the common hijack. These include (but not limited to):
- no logwrapper usage
- starting the hijack too late due to no logwrapper usage
- unmounting things in use once hijacking (ties in with the top two)
- starting ADB (still WIP)
- getting the hijack to flash a new root directory
- starting 2nd-init once the new root was flashed
Which Binary To Hijack (COMPLETED)
To resolve the first 3 issues was the first step. How would I call the common hijack while keeping the code from being completely modified? I first considered using mot_boot_mode as we have in the past. But this would require a lot of work trying to determine when it was already hijacked and when it wasn't. So I actually tried to hijack using logwrapper. I found that it was called around the touchpad setup service. This was called immediately after mot_boot_mode so it shouldn't have caused any more issues that mot_boot_mode was. After a few tests with that I found that I couldn't get things properly unmounted because too many things were set up and running by then. And because it was a service, others were starting up by then which it couldn't kill. It was getting worse and worse.
Then I remembered about another binary named "remountpds." I have played around with it in the past, but never actually used it in the hijack yet. I changed it intercept remountpds and after testing found that it was being called properly.
Starting ADB (COMPLETED)
Next step was to get ADB started. The hijack normally uses persist.service.adb.enable to get the system ready to run ADB. Normally I would use persist.service.adb.enable_NV_DISABLED (the prop I found that got adb working at boot) for the other hijacks. After trying the NV_DISABLED prop I found that it was not being set. After digging through the source that would set the props (setprop, etc.) I found that the maximum length that AOSP props can be is only 32 characters. Our prop is too long to be set with CM7's binaries. I decided to change the prop length to 40 but this only caused the binaries to crash and the hijack to not even go anywhere. This basically moved me backwards. Because of this I moved back to the old prop and reset the max prop length back to 32.
Later after I finally got the root directory flashed (next section) we almost got adb working. It recognizes that a device is connected, but won't actually get us into a shell.
UPDATE 2: I now have 2nd-init working by basically forcing all of the props that would start adbd (the service on the phone that allows us to connect through adb) to be 1. We now have a working ADB at boot with a CM7 system.
Flashing the New Root Directory (COMPLETED)
The moto common hijack basically works as our other hijacks do only with one major difference: it flashes a new root directory (like recovery does) and then moves everything to it's proper place. (With our current hijacks, we just do a lot of copy commands.) But whenever I tried to get it to flash my new zip, it would always fail and therefore everything beneath that in the code would fail also because of the dependency on what was inside the zip. After checking it out (with help from hashcode) I found that the hijack kept trying to flash the wrong zip name. And after numerous attempts at trying to get it to automate the name (through defines and such) I finally got it to find the correct zip to flash.
Firing 2nd-init (COMPLETED)
After the zip gets flashed it does everything it can to get the system back to as clean as a slate as it can. This is the killall script that we had been working with and tweaking to get working with our phones. BUT! Because of calling it earlier with remountpds and following the steps through the common hijack as they are supposed to be done, the standard kill all script worked and created a (essentially) clean slate for our system to restart itself.
The problem was that it wasn't calling 2nd-init and restarting the init process. After talking more to hashcode, we found that I had forgot to call tasket on 2nd-init and that the 2nd-init binary was dynamic and not static (dynamic means it looks for libraries to do it's instructions, static means they're all built in). As this was really late at night, I decided to start coding these changes and start a new build, but not test yet. Right now as I'm finishing this, I'm waiting on more logs to continue my efforts.
UPDATE: 2nd-init is now working and we are yet another step closer to getting CM7 working.
Getting /init Working (COMPLETED)
Now that we have 2nd-int working I'm now working on getting our new init binary that comes with CM7 to work with our init.rc. This is a challenge in itself but with the help of hashcode, I hope to have this working soon.
Our stock /init binary is programmed to work with certain users as it parses through the init.rc script. When it hits a user it doesn't know, it freaks out and stops the init process. My first thought was to go the way of the ATRIX and just rename all of the users to system but this posed another problem. Some of the services we are going to need are dependent on those Motorola users which our new init.rc has no clue about. Cue hashcode. He has helped me by pointing me to the D3 system core (aka init, adb, logcat, etc.) edits that's he's worked on. This includes changes to the /init binary that will include the motorola users needed to get our init.rc working. As I'm writing this, I'm currently building the source for it and haven't tested, but I assure you that this will help us get another step closer to CM7.
NOTE: Now before you go "That's for the D3, and we're the X2" remember that pretty much all of the code that we're compiling will work with any Android phone but certain changes are set up in our device configuration. Therefore although I'm taking the changes made to the D3, they will still work for us.
BIG UPDATE: We now have a working init binary that has the correct users so that it doesn't freak out when it tries to set permission up. This has let us to our first official bootloop of CM7. This is REALLY good news because that means that our init is trying to do what it's supposed to do and keep setting up our device and trying to actually start CM7. After looking at some of the logs, we had some issues dealing with the services trying to access the devices. I have since (hopefully) fixed the problem and am awaiting results as we speak.
UPDATE AGAIN: We have now started the boot animation! This means we're really close to getting it working!
Getting Into CM7 (WIP)
I have now managed to start the CM7 boot animation and I'm now currently trying to work out the problems with the installation of the apks.
After working some more with hashcode I found that there were audio decoders (take audio information and turn them into usable information) that weren't being loaded, but were being enabled. With his help i found two of these decoders that Motorola uses, but CM7 doesn't. So I disabled them and that's the first time we started getting places.
But then I learned that the dalvik-caches (the files on our phone that make it run faster) weren't being set up properly. Normally (in a lot of phones) the dalvik-caches are located in /data/dalvik-cache. This is not the case for CM7 as they are located in /cache/dalvik-cache. Once I got this set up we still were not able to get into the boot animation yet until looking at more logs. I found (silly me again) that the zygote process (basically the main system process) was trying to also load the framework (the base system files) that Motorola use. Since we obviously don't have those, it won't find them and it won't load. After fixing that, I sent it out for testing to MoonShadow-NM where he informed me (rather enthusiastically) that we were at the boot animation and made the video above.
Now the problem that I'm running into involves the permissions of those caches and having the other programs access those caches. This has been the hardest obstacle that I've had to face so far as I'm having problems figuring it out. Normally they are supposed to be owned by the system. This allows anything with system (or higher) privileges to access and use these caches for themselves. Normally when an apk is installed they have a user with App_## and belong to the system group. This why they can access the caches and use them. But my problem right now isn't the apps being able to access the caches, it's the installation of those apps.
There is a daemon (service) called installd that checks for newly installed apps and such and starts all of the work needed to get the caches set up and ready for application uses. This is where I'm currently stuck. The framework caches (as I mentioned above) are being created with root (the superuser) as their owner and not system. This means that the installd service (although being ran as root) can't have the processes it starts (which are being ran as system)
access these files and continue on. I'm currently trying to work this problem out.
Conclusion (aka "You Don't Have CM7 Yet Why Should We Bother?")
From a standard reader's perspective you have every reason to think that. From a dev's point of view we're the closest we've ever been to getting CM7 (and eventually AOSP, MIUI and CM9/ICS). CM7 is the first step to that. We're almost there. I haven't given up on getting this ported over and any readers shouldn't either. I'm not making any ETAs or predictions on any outcomes from all of this work, so please don't ask me. I hope you guys found this informative and continue to be supportive throughout this process.
For more information regarding development of CM7 or AOSP please join us on the Freenode IRC on the #x2-aosp channel using your favorite IRC client or at http://webchat.freenode.net. Please keep the conversation on topic as much as possible. We will get off topic sometimes, but when a dev says back on topic, please try to remain so. Or else I will lay down the fits of +v and +m. (If you know what that means, good. if not, don't worry about it.) There will be times that we are quiet, but when we talk we talk A LOT. So don't sign in, wait 5 minutes, then sign out. When we get somewhere, we'll let you slowly know.