首先说明一下,系统环境是 Ubuntu 15.10.

至于为什么是 Ubuntu,嘛,是因为 Vultr 的镜像没有 Gentoo.

编译内核,你需要 cross compiler, mkbootimg, cpio, 和能用的 ramdisk/rootfs.

首先安装你需要的软件:

sudo apt-get install -y build-essential kernel-package libncurses5-dev bzip2 cpio git
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9  //工具链
git clone https://github.com/osm0sis/mkbootimg.git    //mkbootimg
cd mkbootimg && make
`</pre>

然后 clone 一份你需要的内核源码, cd 进去.

<pre>`cd kernel
export ARCH=arm64
export PATH=/home/feather/aarch64-linux-android-4.9/bin/:$PATH    //这里修改为你的 cross compiler 位置
export CROSS_COMPILE=aarch64-linux-android-
make mrproper
`</pre>

接下来的部分就是取决于你的内核,手机了,例如我的是 Xperia Z5 Compact,代号是 suzuran,套用的设置是 suzuran_diffconfig.

<pre>`export KBUILD_DIFFCONFIG=suzuran_diffconfig
make msm8994-perf_defconfig
make menuconfig    //这里检查一下配置
make -j
`</pre>

接下来就是组装/封装 Kernel 了,也就是我们要刷入的 boot.img.这里要注意,**每个设备的 cmdline,base,pagesize,ramdisk_offset,tags_offset 可能不同,请再三确认.**

<pre>`mkbootimg \
  --kernel arch/arm64/boot/Image.gz-dtb \
  --ramdisk ramdisk.img \
  --cmdline "androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x237 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 boot_cpus=0-5 dwc3_msm.prop_chg_detect=Y coherent_pool=2M dwc3_msm.hvdcp_max_current=1500" \
  --base 0x00000000 \
  --pagesize 4096 \
  --ramdisk_offset 0x02000000 \
  --tags_offset 0x01E00000 \
  --output boot.img
`</pre>

PS:然后我发现啊,Image.gz-dtb 这不明写着已经有了 dtb 了么...所以不需要单独封装 dtb 了.可以直接跳至 ramdisk 部分.

<del datetime="2016-07-28T08:08:36+00:00">注:少数高通的设备需要附加 dtb,需要不同的封装方法:

首先我们需要 dtbtool.

<pre>`git clone https://github.com/ryan-andri/dtbtool
cd dtbtool
make
`</pre>

拿到 dtbtool 之后我们就可以封装了.

<pre>`dtbtool -o dt.img -s 2048 -p scripts/dtc/ arch/arm/boot/dts/    //生成 dt.img
mkbootimg \
  --kernel arch/arm64/boot/Image \
  --ramdisk ../build_suzuran/ramdisk.img \
  --cmdline "androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x237 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 boot_cpus=0-5 dwc3_msm.prop_chg_detect=Y coherent_pool=2M dwc3_msm.hvdcp_max_current=1500" \
  --base 0x00000000 \
  --pagesize 4096 \
  --ramdisk_offset 0x02000000 \
  --tags_offset 0x01E00000 \
  --dt dt.img \
  --output boot.img
`</pre>

</del>

说起来我似乎没有讲 ramdisk 是什么,是做什么的...

ramdisk,其实就是 initramfs,或者 initrd.里面包含了 init 和一堆其他的,用于引导设备的文件,在你的设备第一屏的时候其实就是 ramdisk 在引导.

那么怎么拿到 ramdisk 呢?

第一种方法是从一个已有的内核里面解出来一个,这个最简单,也最方便,因为不是所有人都存着那 40 G 多的源码的.

第二种就是自己构建了,在构建 AOSP/CM 这种第三方的 ROM 时候比较常见,因为你已经有了他们的源码.

这里说一下第一种吧,第二种等会...

前辈们已经做好了一个 Perl 脚本给我们,所以直接拿来主义:

<pre>`wget https://gist.github.com/jberkel/1087743/raw/45046f87176dfacdc22af4290f89a0d2e0df1dbb/split_bootimg.pl
chmod +x split_bootimg.pl
./split_bootimg.pl boot.img
`</pre>

然后我们就拿到了 kernel,和 ramdisk,这也就是 Linux 上比较常见的了,内核与 initrd 分离的形态.

其实这个时候就可以用了,把 boot.img-ramdisk.gz 封装进去就好,不过如果你想修改 Ramdisk 可以继续看下去.

接下来是解压 ramdisk.因为 ramdisk 是 cpio 压缩,所以我们先解压 gzip,再用 cpio.

<pre>`mkdir ramdisk &amp;&amp; cd ramdisk
gzip -dc ../boot.img-ramdisk.gz | cpio -i
`</pre>

这里我们就可以修改了,修改好了之后在打包回去:

<pre>`find . | cpio -o -H newc | gzip &gt; ../newramdisk.cpio.gz

然后又是一个崭新的 ramdisk 了 (笑


Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.