概述
Android预移植到tiny4412
kernel for tiny4412
前面的文章已经把uboot给弄好了,下面就可以用自己移植的uboot来启动内核了。对于内核的移植,一开始选择的是linux4.4的内核,为什么选4.4,因为开始的时候是想在tiny4412上面跑Android 7.0的,而Android 7.0用4.4的内核比较合适,但是折腾了一段时间后发现,是我想太多了,Android 7.0上的改动还是有点打,平时在公司也比较少接触Android 7.0,所以后来还是改回移植Android 6.0了,但是内核已经能跑起来啦就不换了
首先是下载内核,内核的下载可以通过下面的指令下载:
git clone https://aosp.tuna.tsinghua.edu.cn/kernel/common.git
下载完后可以通过git branch -a来查看现有的Android可用的kernel版本,接着通过指令:
git checkout remotes/origin/android-4.4-n-release
来获得Android N支持的kernel 4.4,接下来就是将kernel适配到tiny4412上了,这一部分我也是参照网上的资料来进行的,我使用的Blog教程是这个:
http://www.cnblogs.com/pengdonglin137/tag/TINY4412/default.html?page=1
目前我只移植到MMC部分
相信各位都了解过,Android使用的Linux kernel和标准的linux kernel是有区别的,例如:标准的Linux kernel可没有binder驱动,为了让我们移植的kernel支持Android的特性,需要执行下面一条执行,将Android的特性写道.config文件中,然后再全编就好了
ARCH=arm scripts/kconfig/merge_config.sh arch/arm/configs/tiny4412_defconfig android/configs/android-base.cfg android/configs/android-recommended.cfg
如果大家觉得麻烦也可以直接到我的Github上面下载:
https://github.com/xiaojimmychen/linux-4.4
Android源码编译
Android M的代码下载可以通过下面的指令:
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r79
使用的是清华大学提供的镜像源,下载速度还是可以的,只是中间容易出现网络断开问题,要一直执行repo sync指令来同步代码而已,所以我写了一个脚本来自动执行这个步骤,下面是代码,大家可以按照自己计算机的cpu核心数改一改数值,当然还是推荐大家按照清华大学镜像源网站上说的,使用4个核心好点;接下来将下面的执行代码保存为start_repo.sh就好了,当然别忘了给start_repo.sh加上执行权限
#!/bin/bash
echo "======start repo sync======"
repo sync -j4
while [ $? = 1 ]; do
echo "======sync failed, re-sync again======"
sleep 3
repo sync -j4
done
OK,代码下载完成了,下面可以使用下面的指令来添加对应的板子代码
./device/common/populate-new-device.sh samsung tiny4412
同时在./device/samsung/tiny4412/BoardConfig.mk中添加下面一行
TARGET_CPU_VARIANT := cortex-a9
否则在编译一开始就会出错的。
然后执行
source build/envsetup.sh
lunch
lunch后选择tiny4412开发板就可以了
最后就是执行编译指令了,make -j24 2>&1 | tee build.log
一段时间后,会报错,因为我使用的是Ubuntu16.04下面的错误貌似在高版本的Ubuntu上会出现问题:
out/host/linux-x86/obj32/SHARED_LIBRARIES/libart_intermediates/arch/x86/quick_entrypoints_x86.o:function art_quick_instrumentation_entry: error: unsupported reloc 43
out/host/linux-x86/obj32/SHARED_LIBRARIES/libart_intermediates/arch/x86/quick_entrypoints_x86.o:function art_quick_instrumentation_entry: error: unsupported reloc 43
out/host/linux-x86/obj32/SHARED_LIBRARIES/libart_intermediates/arch/x86/quick_entrypoints_x86.o:function art_quick_instrumentation_exit: error: unsupported reloc 43
不过网上也有解决办法,我的解决办法如下:
It works to me:
in file /art/build/Android.common_build.mk, find out:
ART_HOST_CLANG := false
ifneq ($(WITHOUT_HOST_CLANG),true)
# By default, host builds use clang for better warnings.
ART_HOST_CLANG := true
endif
change to :
ART_HOST_CLANG := false
ifeq ($(WITHOUT_HOST_CLANG),false)
# By default, host builds use clang for better warnings.
ART_HOST_CLANG := true
endif
If it still not works,try this in your android root path:
cp /usr/bin/ld.gold prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.6/x86_64-linux/bin/ld
这里需要注意的是,在拷贝ld.gold的时候要注意,不同Android版本,编译后可能会有两个x86_64-linux-glibc*目录,如果存在两个的话就要将ld.gold拷贝到两个目录下的x86_64/bin/ld,否则还是会继续报错的
解决完这个问题继续编译,编译一段时间后会报出如下错误:
mkyaffs2image -f out/target/product/tiny4412/data out/target/product/tiny4412/userdata.img out/target/product/tiny4412/root/file_contexts data
Traceback (most recent call last):
File “./build/tools/releasetools/build_image.py”, line 516, in
main(sys.argv[1:])
File “./build/tools/releasetools/build_image.py”, line 509, in main
if not BuildImage(in_dir, image_properties, out_file, target_out):
File “./build/tools/releasetools/build_image.py”, line 326, in BuildImage
(_, exit_code) = RunCommand(build_command)
File “./build/tools/releasetools/build_image.py”, line 46, in RunCommand
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
File “/usr/lib/python2.7/subprocess.py”, line 711, in init
errread, errwrite)
File “/usr/lib/python2.7/subprocess.py”, line 1343, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
build/core/Makefile:1188: recipe for target ‘out/target/product/tiny4412/userdata.img’ failed
一开始,我以为是Ubuntu版本太高,Python版本不同导致,后来细致一看,实在编译userdata.img的时候出现问题的,后来执行mkyaffs2image的时候缺少了参数,解决办法是,在./device/samsung/tiny4412/BoardConfig.mk文件中,添加下面的内容:
TARGET_USERIMAGES_USE_EXT4 := true
BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1073741824
# BOARD_USERDATAIMAGE_PARTITION_SIZE := 13287555072
BOARD_CACHEIMAGE_PARTITION_SIZE := 268435456
BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE := ext4
BOARD_FLASH_BLOCK_SIZE := 4096
大家定义的变量的名字应该就知道是干什么用的了,这里我就不多说了,继续编译,这次应该就能编译ok了。
后续修改
编译OK后,要怎么放到SD卡上来启动开发板呢,这个问题我也是废了不少时间才搞明白的。
第一步我们想将SD卡进行分区,分区表如下:
第二步,根据启动流程,uboot到kernel再到init进程,uboot和kernel都没问题了,那么init进程要怎么设置才行呢?我们可以看到Android源码编译后,out目录下会有个root文件夹,init进程就在里面,init进程也有了,后续的system、data分区怎么挂上区呢,这个就是问题所在了,所以接下来我们要修改一下Android的源码。
在device/samsung/tiny4412目录下添加两个文件,分别是:fstab.tiny4412 和 init.tiny4412.rc
init.tiny4412.rc的内容如下:
on early-init
mount debugfs debugfs /sys/kernel/debug
on fs
mount_all /fstab.tiny4412
fstab.tiny4412的内容如下:
# Android fstab file.
#<src>
<mnt_point>
<type>
<mnt_flags and options>
<fs_mgr_flags>
# The filesystem that contains the filesystem checker binary (typically /system) cannot
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK
/dev/block/mmcblk0p3
/system
ext4
ro,barrier=1
wait
/dev/block/mmcblk0p5
/data
ext4
noatime,nosuid,nodev,barrier=1,nomblk_io_submit
wait,check
/dev/block/mmcblk0p6
/cache
ext4
noatime,nosuid,nodev
wait,check
有了这两个文件,还要修改一下device.mk文件:
LOCAL_FSTAB := $(LOCAL_PATH)/fstab.tiny4412
PRODUCT_COPY_FILES :=
$(LOCAL_KERNEL):kernel
$(LOCAL_FSTAB):root/fstab.tiny4412
$(LOCAL_PATH)/init.tiny4412.rc:root/init.tiny4412.rc
同时还要修改system/core/rootdir文件夹下的init.rc文件,将init.tiny4412.rc文件给import进去
import /init.tiny4412.rc
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
......
上面的内容一看应该就能明白了,我就不多解释了
然后执行make -24编译一下
接下来就是将编译出来的内容拷贝到SD卡了,将root目录下的内容拷贝到SD卡的init分区,但是system分区的内容就没有那么简单了,首先我们要通过下面的指令将system.img弄成ext4格式的,然后再将其挂载在一个tmp目录下,再将其拷贝到sd卡的system分区,所用指令如下:
simg2img system.img system-ext4.img
mkdir tmp
sudo mount system-ext4.img tmp/
cd tmp
cp * /media/jimmy/system -rpf
拷贝完之后将SD卡插到开发板上,上电,进入uboot命令行模式,设置一下uboot的bootcmd和bootargs的指令如下:
setenv bootargs "rootwait console=ttySAC0,115200n8 root=/dev/mmcblk0p2 rw init=/init vmalloc=400M androidboot.console=ttySAC0 androidboot.selinux=permissive"
setenv bootcmd "load mmc 0 0x40007000 uImage; load mmc 0 0x48000000 exynos4412-tiny4412.dtb; bootm 0x40007000 - 0x48000000"
saveenv
然后就可以启动开发板了,发现并不能启动,留意到下面一条log
[ 3.113314] init: skipping insecure file ‘/init.rc’
init.rc insecure file,百度说不应该赋予其写的权限,看来还得修改一下init分区下的内容:
在sd卡init分区下执行下面三条指令:
chmod a-w init.*
chmod a-w ueventd.rc
chmod a-w fstab.tiny4412
执行完后再启动开发板
启动之后以为就可以了吗?其实只是刚刚开始,你会发现有很多log,其中主要的log如下:
[
9.814258] init: Service 'surfaceflinger' (pid 1649) killed by signal 6
[
9.814342] init: Service 'surfaceflinger' (pid 1649) killing any children in process group
[
14.820593] init: Warning!
Service vold needs a SELinux domain defined; please fix!
[
14.820762] init: Starting service 'vold'...
[
14.823152] init: Warning!
Service surfaceflinger needs a SELinux domain defined; please fix!
[
14.823384] init: Starting service 'surfaceflinger'...
[
14.827299] init: Warning!
Service media needs a SELinux domain defined; please fix!
[
14.832057] init: Starting service 'media'...
[
14.881607] init: Service 'vold' (pid 1672) exited with status 1
[
14.881845] init: Service 'vold' (pid 1672) killing any children in process group
[
14.962791] init: Service 'media' (pid 1674) exited with status 1
[
14.963030] init: Service 'media' (pid 1674) killing any children in process group
[
15.263813] init: Service 'surfaceflinger' (pid 1673) killed by signal 6
[
15.263901] init: Service 'surfaceflinger' (pid 1673) killing any children in process group
[
19.269313] init: Warning!
Service vold needs a SELinux domain defined; please fix!
[
19.269528] init: Starting service 'vold'...
[
19.273084] init: Warning!
Service surfaceflinger needs a SELinux domain defined; please fix!
[
19.273356] init: Starting service 'surfaceflinger'...
[
19.276680] init: Warning!
Service media needs a SELinux domain defined; please fix!
[
19.280775] init: Starting service 'media'...
[
19.323515] init: Service 'vold' (pid 1680) exited with status 1
[
19.323631] init: Service 'vold' (pid 1680) killing any children in process group
[
19.352518] init: Service 'media' (pid 1682) exited with status 1
[
19.352635] init: Service 'media' (pid 1682) killing any children in process group
[
19.668469] init: Service 'surfaceflinger' (pid 1681) killed by signal 6
[
19.668576] init: Service 'surfaceflinger' (pid 1681) killing any children in process group
就是surfaceflinger灯service不断的重启,我想应该因为我还没有移植LCD驱动,导致surfacefliger无法执行,surfaceflinger无法正常启动,导致后续同一个class的service也无法启动
接下来,我会花一段时间来阅读LDD3,写一下Linux的驱动,同时也看看怎么解决这个surfaceflnger不断重启的问题,但愿可以解决吧
最后
以上就是殷勤世界为你收集整理的Linux 4.4内核移植以及Android系统编译 Android预移植到tiny4412 的全部内容,希望文章能够帮你解决Linux 4.4内核移植以及Android系统编译 Android预移植到tiny4412 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复