其实在此之前有一篇通过编写initscript并执行来启动现有的linux发行版文件系统的博文,这样虽然能使用但是那些现有的linux中有很多无用的组件(如果因为安卓内核问题无法使用的udev还有systemd等等)并且精简起来相当麻烦,而且通过这种方式运行起来的还是有一些问题的。
然后针对于以上情况处理了几天之后始终不能让自己满意,然后我就想到了自己编译一个busybox并用它来自制。这样确实很不错,busybox有很多工具而且体积相当的小,动态的还不到1m。更重要的是可以直接用busybox的linuxrc来启动自己制作的linux,这样的话和真机启动几乎一样,不用编写initscript。
准备
busybox源代码一份
宿主机一台。因为我使用的手机所以并不需要配置交叉编译等,如果你的宿主机与你的手机处理器架构不兼容的话,可能需要配置交叉编译的环境。
手机得安装busybox,因为需要用到chroot,而这个工具一般都没有只能安装自带的busybox。
编译busybox并制作rootfs
1.编译并安装busybox
1 | # make defconfig |
如果没有指定路径的话,busybox将会被安装在busybox源代码目录文件夹下的_install文件夹下。
把_install目录给剪切出来重命名,并完善这个rootfs
2.创建必要的文件夹并添加必要的库文件
1 | mkdir -pv etc/init.d var/log root home lib dev proc sys boot mnt media tmp share run |
因为是编译的动态的busybox,所以需要c库文件。先通过ldd命令是哪些,然后再cp过来就ok。
3.为linuxrc进程提供配置文件:(inittab)
1 | vim etc/initab |
请注意因为安卓内核问题没法使用tty等串口设备,所以没法进行本地登录,一旦强行使用tty等串口设备进行本地登录时,sh会打印tty设备无法打开的错误在屏幕上。这也是我在这里定义使用telnetd服务远程登录的原因。
4.建立系统初始化脚本
vim etc/init.d/rcS1
2
3
4
5
6
7
8
9
10
11
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t tmpfs tmpfs /dev
mdev -s
mkdir /dev/pts
mount -t devpts devpts /dev/pts
mkdir /dev/shm
mount -t tmpfs tmpfs /dev/shm
hostname -F /etc/hostname
mount -a
5.为系统准备一个“文件系统表”配置文件/etc/fstab
1 | touch /etc/fstab |
我这里什么也不添加。
6.添加登录认证功能
从宿主机复制group,passwd,shadow文件,并且只留下这些文件的root项。
7.为系统提供主机名称
1 | vim etc/hostname |
8.为系统设置输入提示信息
1 | vim etc/profile |
9.添加dns功能
为名称解析服务复制必要的库文件,把宿主机的/lib目录下以文件文件名包括libnss_files的全部拷贝过来
为目标主机建立名称解析文件nsswitch.conf1
2
3
4
5
6vim etc/nsswitch.conf
添加如下内容
passwd: files
group: files
shadow: files
hosts: files dns
设置dns服务器1
2
3
4vim etc/resolv.conf
内容如下
nameserver 111.8.14.18
nameserver 211.142.211.124
从宿主机上复制hosts文件。
10.校准系统时区
把宿主机/etc/localtime文件复制过来。
测试
做完以上操作之后就有了个能在安卓上跑的linux
使用chroot开启1
chroot . /linuxrc
然后终端就会卡着不动,这正常因为我没有在initab设置本地登录。这也不可以。关闭这个终端用telnet连接即可1
telnet 127.0.0.1:23
因为登录认证文件用的是宿主机的,所以登录密码与宿主机一致。
如果没有什么问题就成功了,但是此时目标系统还未安装各类工具软件,busybox自带dpkg可以在debian的官网上下载apt以及依赖包安装并配置好,这里就不再详述了。
…