[Fascinate Android Development] djp952:
HOW TO BUILD THE GEEWIZ MEDIA 3 ROM AND KERNEL

A common request I've gotten is how to build the GeeWiz Media ROM and kernel from source. I think GeeWiz Media 3 is a little less intimidating as a first step for getting into AOSP builds since it doesn't stray too far from the Android baseline, and the kernel is based on Samsung's stock model for the device rather than the enhanced MTD model. Whatever the reason, I'm happy to try and describe how I build these components and generate the packages that I post for the community. Sometimes it's normal, sometimes it's a bit wonky, but as long as I don't miss anything important it should be a workable process for anyone that would like to get into building custom Android builds.

I think GeeWiz Media 3 would be a great learning tool, it works as-is but leaves enough room for additional customizations and enhancements that it may be a better place to start than jumping into something like Cyanogenmod or AOKP as your first project. It's up to date at the moment with the latest Android code as well, so that's a definite bonus as opposed to working with something like Gingerbread where tricks you learn may not apply to the next project you take on.

BUILD ENVIRONMENT

I use Ubuntu 12.04 Desktop x64 for my Android build environment, and even though Google states that this environment is "Experimental", I've not run into any issues with it. To get started, simply follow the directions Google has provided here:

http://source.android.com/source/initializing.html

If you are running on Windows x64, I can also recommend using a Virtual Machine as your build environment. I like Oracle VirtualBox the best, but the stock Fascinate code by Samsung has major USB problems with it, you won't be able to use ADB or Heimdall. For Fascinate-specific development I recommend VMWare Player since it can work with the stock USB. Note that you need an x64 OS and a CPU with Virtualization Support to host an x64 guest OS regardless of the software you choose. The best performance and compatibility will come from installing Linux natively on your system.

DOWNLOAD GEEWIZ SOURCE TREE

Once your environment is set up, you of course need some source code. I've opted to use Google's repo tool and AOSP manifests to control the source tree, so the first thing you need is the Google repo tool. Follow the first section of this document, entitled "Installing Repo":

http://source.android.com/source/downloading.html

I have two separate "builds", or in Android terms Manifests out there. One is called DEFAULT and includes just changes to AOSP necessary to support the Fascinate. The other is called CUSTOMBUILD and adds the light OS customizations I have done. Since I never use DEFAULT and I'm not sure t even builds at the moment, we're going to use CUSTOMBUILD, or as it's called here at XDA "GeeWiz".

Open a terminal window to your home directory (~/)

mkdir android

mkdir android/platform

cd android/platform

repo init -u https://github.com/djp952/android -m custombuild.xml -b android-4.1.2_r1

What we just did was initialize the repository for AOSP, but haven't downloaded anything yet. The -u argument to repo tells it where to find the manifest XML files. In this case, my github "android" repo. The -m tells it what manifest to use. The -b tells it what branch to pull. This is important because like most folks, I have multiple branches out there. I have been indicating at the very end of the first post what the current active branch is, android-4.1.2_r1 right now.

At this point, I suggest going into the ~/android/platform/.repo/manifests directory and having a look at the manifest file. (.repo is a hidden folder). Open up custombuild.xml in GEDIT and you can see that I've taken the AOSP manifest and simply replaced portions of it to point into my own github repos for things I've changed. I'll try to include details on how I manage this below so you could do something similar if you want to.

The most time-consuming part of building Android is downloading the code. Can't go much farther without it, so get yourself a cup of coffee and a good book ...

In the terminal, at the ~/android/platform directory

repo sync

The SYNC command uses the manifest to go get all the code. Most of it is going to come from Google, but all the bits I've altered will come from my github instead. It's going to take a very long time to download.

BUILD GEEWIZ MEDIA ROM

Once downloaded, we have to choose what device to build for. GeeWiz has two target devices, "atlas" and "atlas3g". Atlas is the Wifi-only target known here as "GeeWiz Media". Atlas3G adds to that changes required to include voice/data support (mostly courtesy of Cyanogenmod!). Let's assume if you're reading this, you're interested in the Wifi-only Atlas.

In the terminal, at the ~/android/platform directory

source build/envsetup.sh

lunch

The "Lunch Menu" (haha Google) will present you with a list of device builds to choose from. You can select by number, or you can type in anything not on the menu. As of this writing, the build we want is #9, full_atlas-userdebug. userdebug generates a generally release-quality build, but doesn't odex (pre-optimize) the APKs and has some additional debugging support you wouldn't ordinarily find. You could also type in full_atlas-eng for an "Engineering" build or full_atlas-user for a "Release" build. I think you'll prefer userdebug most of the time.

Select 9 - full_atlas-userdebug

make -j4 rompackage

This will kick off the build. It will take a long time the first time through. The rompackage argument is something I added to AOSP to support the Fascinate. This will build the EDIFY update-zip that I upload for everyone and use to generate the ODIN packages (more on that later). On typical Android devices, you would use otapackage (update-zip install) or updatepackage (fastboot install) instead. Fascinate is a special needs child, so it gets a special needs build process.

Once it's done, provided I didn't forget anything important here, you'll have a full ROM/Kernel package ready to be flashed via Clockworkmod or GeeWiz Recovery in the ~/android/platform/out/target/product/atlas folder. It will be named along the lines of full_atlas-rom-YYYYMMDD.HHMMSS.zip. Making a package for ODIN involves more steps, but I'll get to that. First I have to tell you how to build a modified Kernel ...

BUILDING THE GEEWIZ KERNEL

The Atlas and Atlas3G repos have a pre-compiled kernel in them that is packaged with the ROM build. This section will describe how to build and include customized versions of that kernel. First step is, of course, to get the source code. Both ROMs share a kernel but due to differences in the ramdisk (initramfs), they are built independently.

In a Terminal, at the ~/android directory

git clone https://github.com/djp952/android-kernel-atlas.git

cd android-kernel-atlas

git branch android-2.6 remotes/origin/android-2.6

git checkout android-2.6

Now the build environment needs to be set up. I use the compiler provided with AOSP to build the kernel as this is how Google does it. If you are using a different compiler, or have put your AOSP tree into a different location, you may have to modify these commands slightly.

In a Terminal, at the ~/android/android-kernel-atlas directory

export ARCH=arm

export SUBARCH=arm

export CROSS_COMPILE=arm-eabi-

export PATH=~/android/platform/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH

NOTE: From this point forward, don't close that Terminal, otherwise you will have to execute the environment export commands again.

The kernel is built in three steps. This is necessary because the Fascinate doesn't conform to Android's models and we have to include the ramdisk (initramfs) in the kernel image. The first step is to select which device you are building the kernel for, which in this case will be "atlas_defconfig". (The other configuration for the GeeWiz 3G version is called "atlas3g_defconfig").

make atlas_defconfig

This initializes the kernel build for Atlas. Since we need to build the ramdisk as part of the kernel, the next step is to generate any loadable kernel module (.ko) files that need to be part of that ramdisk

make modules

The way I have the kernel set up, it will pull the necessary files for the ramdisk by looking at the device "initramfs.list" file, in the AOSP tree. The file that describes the atlas ramdisk, for example, is in ~/android/platform/device/samsung/atlas. If you examine this file you can see that it lists where all the files should come from, relative to the kernel source root directory. This explains why I went through how to build the AOSP tree before the kernel, the kernel depends on the AOSP build. Provided everything is in the right place, it's time to build the kernel

make

This executes the main kernel build. Should any ramdisk files be missing, it will error out early on and let you know what the problem is. Assuming everything goes well, your kernel will be in the ~/android/android-kernel-atlas/arch/arm/boot directory. It's named zImage and it's the combined kernel/ramdisk required for the Fascinate.

This zImage file can now be flashed directly to the device with Heimdall, packaged up for ODIN, etc. However in order to make it part of your AOSP build and corresponding EDIFY update-zip, we have to copy it into the AOSP tree and rebuild the ROM. It's a bit tedious, and other folks have different and more streamlined ways of accomplishing this, but this method has worked for me.

cp ~/android/android-kernel-atlas/arch/arm/boot/zImage ~/android/platform/device/samsung/atlas/kernel

cd ~/android/platform

source build/envsetup.sh

lunch full_atlas-userdebug

make installclean

make -j4 rompackage

This set of commands will clean out and rebuild your ROM package with the updated kernel.

CREATING ODIN PACKAGES

While not the most popular way for people to install your ROM, no guide would be complete without describing how to generate the ODIN-based installation packages. I like to provide a "Full Wipe" ODIN package that will take care of resetting the device while flashing the new ROM/Kernel, it's an easy way for people that are comfortable with ODIN to just completely replace the contents of their phone with your stuff. For this section, I'm going to assume that you are using GeeWiz Recovery, version 2.8 or later. Other recoveries will work, but as you may expect I'm most familiar with the one I made and I know for certain it has all the necessary features in place.

The ODIN factoryfs.rfs file must be generated by formatting the SYSTEM volume with RFS and then installing your ROM:

Copy your generated EDIFY update-zip to the SDCARD

Reboot into GeeWiz Recovery

Wipe the device data by selecting Wipe Device Data and then Wipe all User Data (Factory Reset)

Press the HOME key to return to the main menu

Format the SYSTEM volume with RFS by selecting Manage Volumes / Format Volumes / Format SYSTEM / Format SYSTEM [rfs]

Press the HOME key to return to the main menu

Select Install Update Package, and choose your EDIFY update-zip to install

After the installation is complete, reboot the phone by selecting Exit from the main menu. Not rebooting the device after the flash will result in a bad ODIN file more often than not. Trust me on this one.

After the device has fully booted, reboot it back into GeeWiz Recovery. The next step will be to generate a backup of the RFS-formatted SYSTEM volume to ultimately use with ODIN. GeeWiz Recovery can create these by choosing to execute a "raw dump" of the volume:

Select Manage Volumes / Backup Volumes / Backup SYSTEM / Backup SYSTEM [raw dump]

GeeWiz Recovery tries to keep volumes unmounted after it's done working, so the SDCARD must be mounted before the contents can be accessed with ADB:

Press the HOME key to return to the main menu

Select Manage Volumes / Mount Volumes / Mount SDCARD

GeeWiz Recovery will store the backup as /sdcard/backup/volume/SYSTEM-YYYYMMDD.img.gz, so as an example, I might pull it to my home folder with this command:

adb pull /sdcard/backup/volume/SYSTEM-20121022.img.gz ~/

The .gz file will contain a compressed copy of the backup, just open it up, extract the file, and then rename it to factoryfs.rfs. This is the SYSTEM volume for ODIN. There are also a number of other files you can include in your ODIN package to perform various other flash or wipe operations (I'll tell you where to get them, too)

boot.bin - Will replace the primary bootloader. VERY DANGEROUS to include, I strongly recommend against including it.

cache.rfs - Will wipe the CACHE volume; necessary if you want the device to boot into recovery automatically and run a command

dbdata.rfs - Will wipe the DBDATA volume

factoryfs.rfs - Will replace the SYSTEM volume

modem.bin - Will replace the CDMA modem

movinand.bin - Will wipe the DATA, PREINSTALL and FOTA volumes

param.lfs - Will replace the parameter block. Semi-dangerous to include, but required to ensure an initial boot into recovery mode

recovery.bin - Will replace the RECOVERY kernel and ramdisk

Sbl.bin - Will replace the secondary bootloader. VERY DANGEROUS to include, I strongly recommend against including it.

zImage - Will replace the BOOT kernel and ramdisk

To generate an ODIN-compatible tarball, gather the files you want to include and execute the following commands from a Terminal. Replace tarfilename.tar with the name you want to give the tarball, and replace file file file file with the names of the files from the table above you want to include:

tar --format=ustar -cf tarfilename.tar file file file file

md5sum -t tarfilename.tar >> tarfilename.tar

mv tarfilename.tar tarfilename.tar.md5

NOTE: If you rename the .TAR file, it will invalidate the MD5 checksum and you will have to md5sum it again.

OK, where to get the files. You can access a "full stock" ODIN package for the Fascinate, like the EH03 version that is available here on XDA to get copies of all the stock versions of these files. Or, you can use the ones from my ODIN "Full Wipe" package if you'd like as well. My ODIN tarball has a gimmick that you may find useful. If you include my copies of cache.rfs, param.lfs and recovery.bin, the device will initially reboot into recovery and automatically format the CACHE, DATA and DBDATA volumes with the EXT4 file system. It's a relatively simple trick, but an effective one to help improve the performance of your ROM. I also like to provide a "syskernel" tarball that includes only factoryfs.rfs and zImage. The benefit of this is that it will not wipe out any of your user's data. The downside is that the user may be responsible for going into Recovery on their own and executing any steps your EDIFY update-zip would have typically taken care of, like clearing the Dalvik-cache.