最近从淘宝收了一台三星的 Series 3 ARM Chromebook,平时当作上网本用起来还是可以的,可以运行一些 Chrome packaged 原生 App,Chrome OS 的运行速度也还凑合,主要电池续航比一般的笔记本要给力多了,这篇博文的编辑及实际 kernel 编译操作我都是在 Chromebook 上完成的。
由于 Chromebook 底层使用的还是 Linux 内核,装了 Crouton 插件之后可以在 Chromebook 里以 chroot 的方式跑另外的 Ubuntu 系统,只不过 Chromebook 自带的内核模块有些缺失,比如我需要的 binfmt_misc 和 cifs 模块都是没有的,特别是很有用的 cifs 模块用于挂载 Windows 机器上的共享目录。因此想自己编译 Chromebook 的 kernel 加入需要的内核模块。
三星 Series 3 ARM Chromebook 自带的 16GB SSD 毕竟有点小,ARM 系统里装一堆开发环境还是嫌麻烦,还有比较重要的一点是国内的网络环境 git clone 出 Google Source 上的 kernel 源代码速度实在是太慢了,于是就想着用之前注册的 Koding 云端开发平台上跑交叉编译器来编译 Chromebook 的 kernel。
Koding 云端开发平台默认自带了 Node.js、Python、Ruby、Go 等开发环境支持,Koding 默认给了一个很强大的 Web IDE 编辑工具,可以在 Web 上直接登录 Shell 操作,而且 Koding 提供的 Linux 虚拟环境默认就安装了 gcc、Makefile 等工具,其免费套餐提供的 1GB RAM、3GB 硬盘空间用来编译 kernel 也勉强够用了。
先在 Chromebook 里按 Ctrl +Alt + T 键切换到 crosh Shell 里确认当前 kernel 版本:
chronos@localhost / $ cat /proc/version Linux version 3.8.11 (chrome-bot@build44-m2) (gcc version 4.9.x-google 20140827 (prerelease) (4.9.1_cos_gg_2f9796c_4.9.1-r82) ) #1 SMP Sat Mar 7 06:47:35 PST 2015
可以看到现在用的是最新 Linux 3.8.11 版本,从 Google 官方提供的 kernel 版本库里确认需要使用的 kernel 分支:
https://chromium.googlesource.com/chromiumos/third_party/kernel/
我需要的 3.8.11 版本就可以直接使用 chromeos-3.8 分支,现在可以 SSH 远程登录到 Koding Linux 系统上,幸运的是我们还可以在 Chromebook 安装 Secure Shell 这一牛叉 App 直接进行 SSH 登录,Secure Shell 支持 Koding 的 SSH 证书(需要自己登录到 Koding 的 Web Shell 里生成哈)形式,不过选择证书时需要注意把公钥和私钥文件同时选上。
Koding 云端开发平台默认使用的是 Ubuntu 14.04 LTS 64 位系统,这样也比较好,ARM 交叉编译器安装起来也很方便了,先 clone 出 kernel 源代码:
git clone https://chromium.googlesource.com/chromiumos/third_party/kernel -b chromeos-3.8
然后运行 sudo apt-get install gcc-arm-linux-gnueabi 安装交叉编译器,Ubuntu 提供的 ARM gcc 编译器是 4.7.2 版本。
接着需要把 Chromebook 当前的 kernel 配置导出来,在 Chromebook 上切换到 Shell,运行 sudo modprobe configs 命令,然后拷贝 /proc/config.gz 文件并解压缩,通过 scp 命令将解压缩出来的 config 文件拷贝到 Koding Linux 系统中。
在 Koding Linux 系统中进入刚才 clone 出来的 Linux kernel 源代码目录,将 Chromebook 上拷贝过来的 config 文件重命名为 .config,然后运行下面的命令进行 kernel 配置:
cd ~/kernel make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
我们可以在 Network Filesystem 中启用 cifs 模块,同时可以启用 binfmt_misc 模块,保存 kernel 配置,运行下面的命令直接开始内核编译:
cd ~/kernel make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
如果你不想编译完整的 Chromebook kernel,也可以使用这两个命令只编译需要的 binfmt_misc 和 cifs 模块,这样可以节省时间:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- M=fs/cifs make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- fs/binfmt_misc.ko
需要注意的是这样编译出来的 cifs.ko 模块文件还是依赖 md4.ko 文件(会自动编译出来)的。
下面就是通过 scp 把编译出来的 cifs.ko、md4.ko、binfmt_misc.ko 文件拷贝到 Chromebook 系统中,我们可以将这 3 个文件放到 Linux 内核模块目录中(不过这一步需要在 Chromebook 的开发模式中禁用 Chrome OS 的 rootfs 分区锁定功能):
mkdir /lib/modules/3.8.11/kernel/fs/cifs mv cifs.ko /lib/modules/3.8.11/kernel/fs/cifs mv binfmt_misc.ko /lib/modules/3.8.11/kernel/fs mv md4.ko /lib/modules/3.8.11/kernel/crypto
然后可以运行 sudo depmod -a 命令让系统自动生成内核模块依赖关系。
需要注意的是如果你把新编译出来的 ko 模块文件放在不是 rootfs 分区里(未禁用 Chrome OS 的 rootfs 分区保护等情况),这样 insmod binfmt_misc.ko 等命令加载模块会报错失败:
Chromium OS LSM: init_module denied module="/home/chronos/user/Downloads/binfmt_misc.ko" pid=12499 cmdline="insmod binfmt_misc.ko"
这是由于 Chrome OS 默认做了限制即不允许加载放在 rootfs 分区以外的文件系统上的内核模块文件,我们也可以运行下面的命令解除这个限制:
echo 0 > /proc/sys/kernel/chromiumos/module_locking
当然如果你将模块拷贝到上面提到的标准内核模块目录中的话就不会有这个问题了。
经过测试这样的方法编译的模块使用起来还是没有问题的,当然还是有一个不爽之处就是如果 Chrome OS 升级之后内核版本也升级了,但这些模块也需要重新编译了,文中有任何问题还是欢迎提出指正哦,祝玩的开心 ^_^