ubuntu12.04下编译Linux tina 2.1/android经验

时间:2023-03-08 16:18:03
ubuntu12.04下编译Linux tina 2.1/android经验

用的是osboxes下的vdi。

编译Linux

1. 不能在root用户下操作

2. 执行 make kernel_menuconfig 报错,需要

apt-get install zlib1g zlib1g-dev -y
apt-get -y install libncurses5-dev libssl-dev gawk
apt-get install gcc-arm-linux-gnueabi -y

3. 编译uboot的时候报错,说是
/bin/bash: /work/tinaV2.1/lichee/brandy/u-boot-2011.09/../gcc-linaro/bin/arm-linux-gnueabi-gcc: No such file or directory

ls下,结果这个是存在的。干脆grep -r CROSS_COMPILE .,找到关键地方。 修改

tangjian@osboxes:/work/tinaV2.1/lichee/brandy/u-boot-2011.09$ grep -r CROSS_COMPILE .|grep CURDIR
./arch/arm/config.mk:CROSS_COMPILE ?= $(CURDIR)/../gcc-linaro/bin/arm-linux-gnueabi-

把 $(CURDIR)/../gcc-linaro/bin/全部取出,就用apt-get安装好的工具。

发现arm-linux-gnueabihf-gcc,是32位的,内核版本和apt-get安装的不一样。

安装linaro最新版的,版本是7.3.1的比系统自带的4.6.3高了不少。编译报错。(检查更严格)还没法纠正。下载4.6.3的无法下载,系统只提供4.9.4的。

用4.9.4的,结果编译报错

./drivers/mmc/mmc.c:347:24: error: ‘mmc_ext_csd.hc_erase_timeout’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
mmc->erase_timeout = mmc_ext_csd.hc_erase_timeout;
^
mmc.c:346:7: error: ‘mmc_ext_csd.erase_group_def’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
if (mmc_ext_csd.erase_group_def && mmc_ext_csd.hc_erase_timeout)

代码确实问题大,纠正这个。

//struct mmc_ext_csd mmc_ext_csd; //tj modify for compile error

struct mmc_ext_csd mmc_ext_csd = {0};

错误2:

./arch/arm/cpu/armv7/sun8iw5/clock.c 里面也有个错误:

682 for(i=0; i<0x400; i++);
683 //µ÷ÕûʱÖÓƵÂÊ
684 clk_get_pll_para(&pll_factor, frequency);
685 //»ØдPLL1
686 reg_val = readl(CCM_PLL1_CPUX_CTRL);

for循环用“;”结尾,高版本的编译器报错。

又发现另一个错误:

/work/tinaV2.1/lichee/brandy/u-boot-2011.09/nand_sunxi/sun8iw5/lib-nand/nand_phy.c中 -Werror=strict-aliasing,在这个文件中加一行:

#pragma GCC diagnostic ignored "-Wstrict-aliasing" //tangjian add

于是解决问题!

最后发现其实不用更新arm-linux-gnueabihf-gcc,是原来的文件(供应商给的),供应商管理混乱。给的文件中一个Makefile文件中有错误。

#PLATFORM_LIBGCC = -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc
PLATFORM_LIBGCC = -L $(shell dirname `$(CC) $(CFLAGS) --print-libgcc-file-name`) -lgcc

上面注释掉的是原来Makefile中的,纠正的是我改的。当然我没有仔细看这个。提示的错误是dirname无法找到参数,grep -r dirname Makefile就找到了问题所在。
但是让人抓狂的是,第二天,经过一系列别的操作后,发现 -print... 又可以了。

发现没有pack命令,搜索google也没法找到答案。从供应商好不容易拿到答案。

apt-get -y install liballegro4.2-dev

不知何故,之前安装过的包,有时会丢失,难道是后面编译android需要安装一些东西,导致一些包丢失。
编译tina,make kernel_menuconfig,提示出错。发现libncurses-dev需要重新安装

编译android

除了pdf文档提到的以外,还需要安装libgl1-mesa-glx ia32-libs libgl1-mesa-dri
apt-get -y install g++-multilib gcc-multilib

oracle-java因为证书的原因,必须去官网下载才行。找到链接,通过chrome找到链接的引用页,把这个用axel下载就行了。http://download.oracle.com/otn/java/jdk/6u45-b06/jdk-6u45-linux-x64.bin

make -j12 时,

make: *** Waiting for unfinished jobs....

然后改为 make -j8 再编译一次试试看。

编译报错,virtual memory exhausted: Cannot allocate memory,用着个方法解决。原来的swap是2G,不够。用4G的。

dd if=/dev/zero of=/var/swap bs=1024 count=4096000
mkswap /var/swap
swapon /var/swap
free -m
如果经常需要编译android程序,需要在fstab中添加一行:
/var/swap   none    swap    sw    0   0

其实空间反正也够,不如把ubuntu缺省给的2G的swap分区扩展为4G。这样最省事。

最后编译出来,在这里了:out/target/product/astar-evb30/system.img

编译android的Linux内核时,出现奇怪的错误:
make[2]: *** [silentoldconfig] Error 1
make[1]: *** [silentoldconfig] Error 2
make: *** No rule to make target `include/config/auto.conf', needed by `include/config/uboot.release'.  Stop.

google很艰难的才找到答案。
我这么解决:
sudo chown -R <name> .

烧录

为了烧录方便,用samba。ubuntu下 apt-get -y install samba
进入 /etc/samba/,修改smb.conf

path = /work
valid users = <name>
read only = no

# adduser <name>
# smbpasswd -a <name>
# service smbd start

安装PhoenixSuit_CN windows应用程序时,应该用其默认的目录,否则无法安装。

总结

把编译过程加多核编译的东西合并起来。

tina:
cd tinaV2.1
source build/envsetup.sh
lunch astar_parrot-tina
make kernel_menuconfig -j10 || exit
cd lichee/brandy/u-boot-2011.09
make distclean || exit
make sun8iw5p1_config -j10 || exit
make || exit
cd - 
pack

make kernel_menuconfig 出现人机对话时,退出就行了。一般之前kernel_menuconfig已经配置好了,所以这个编入脚本时可以注释掉。
可以把这些放到一个脚本里。机子一共6核,每核2个线程,一共12个。但需要给windows和Linux其它任务留两个核。

修改驱动支持对SPI的支持

对android:
$cd lichee/linux-3.4
$make ARCH=arm menuconfig

选中Device Drivers->SPI Support->User mode SPI device driver support

lichee/tools/pack/chips/sun8iw5p1/configs/evb-30/sys_config.fex
[spi_board0]
;modalias = "at25df641"
modalias = "spidev"

做完这个操作后,估计至少要:

1. 编译内核  2. 编译android系统
之前无法看到/dev/spidev0.0,就是因为只编译了内核。

pdf文档提到的android下的编译打包过程

一、环境搭建

1. 建议用户使用 64bit 的 ubuntu12.04 的操作系统, 已经真机编译验证过。

2. 安装Java6

下载 jdk-6u45-linux-x64.bin 文件并安装,不能通过apt-get方式安装,因为oracle需要验证身份
cd /usr
sudo mkdir java
cd java
sudo cp ~ /jdk-6u45-linux-x64.bin ./
sudo chmod 777 ./jdk-6u45-linux-x64.bin
sudo ./jdk-6u45-linux-x64.bin

打开 profile 文件并添加环境变量
运行 sudo gedit /etc/profile

export JAVA_HOME=/usr/java/jdk1.6.0_45
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$PATH:$JRE_HOME/bin

运行 source /etc/profile

二、安装编译 Android 系统需要的库

sudo apt-get install git gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
g++-multilib mingw32 tofrodos gcc-multilib ia32-libs \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386 \
lzop libssl1.0.0 libssl-dev uboot-mkimage

三、下载源码并解压

下载 android.tar.bz2.0 ,android.tar.bz2.1 ,android.tar.bz2.2 三个文件。 并用
如下的命令解压
cat android.tar.bz2.* | tar -jxv --exclude=.repo --exclude=.git

四、编译内核与 Uboot

1. 配置平台信息

cd /work/android/R16/android
source build/envsetup.sh
lunch astar_evb30-eng

2. 编译内核

cd /work/android/R16/lichee/

如果需要做配置,需要

make ARCH=arm menuconfig  每次make distclean后,需要重新运行这个命令
./build.sh config  分别选 0,0,0,3,分别对应sun8iw5p1,android,linux-3.4和evb 30(boards)
./build.sh

以后再重新编译的时候,./build.sh config就不用执行了。

3. 编译Uboot

cd /work/android/R16/lichee/brandy/u-boot-2011.09/
make distclean
make sun8iw5p1_config
make -j11

五、编译android系统

cd /work/android/R16/android/
extract-bsp
make -j11

六、打包

cd /work/android/R16/android
pack

这个打包的目录安排的有问题,我是这么认为的,虽然打完以后可以work。明显设计不合理。似乎把 ../lichee里面的东西打包进来了。

extract-bsp是个shell函数,看其内容,有:

device/softwinner/polaris-common/vendorsetup.sh:function extract-bsp()
LINUXOUT_DIR=$LICHEE_DIR/out/sun8iw5p1/android/common
LINUXOUT_MODULE_DIR=$LINUXOUT_DIR/lib/modules/*/*

cp $LINUXOUT_DIR/bImage kernel
cp -rf $LINUXOUT_MODULE_DIR modules/modules

把东西拷贝过来了。

为方便起见,不想一行一行拷贝执行,修改完内核后,可以执行脚本adk.sh,其内容是:

#!/bin/bash

. r16p.sh
cd /work/android/R16/lichee/
./build.sh
cd /work/android/R16/android/
extract-bsp
make -j11
pack

其中r16p.sh的内容是:

#!/bin/bash

cd /work/android/R16/android
source build/envsetup.sh
lunch astar_evb30-eng

修改设备/dev/spidev0.0和/sys/class/gpio的权限

内核中选中GPIO:

[*]   /sys/class/gpio/... (sysfs interface)

在源码R16/android/system/core/rootdir/ueventd.rc中增加
/dev/spidev0.0          0666    root    root

root权限太高了,有的建议system权限。

网上还有这样的介绍 https://blog.csdn.net/HarryWeasley/article/details/42083395,可能觉得给设备system的权限可能还是不合适。还可以参考这个
https://blog.csdn.net/jfleecumt/article/details/51155000

但似乎只更改ueventd.rc就行了。实际测试,发现gpio修改这个文件不行。需要:

lichee/linux-3.4/drivers/gpio/gpiolib.c,里

//__ATTR(export, 0200, NULL, export_store),
__ATTR(export, 0666, NULL, export_store),
//__ATTR(unexport, 0200, NULL, unexport_store),
__ATTR(unexport, 0666, NULL, unexport_store),
把权限从0200修改为0666。direction和value的权限也需要修改,搜索“direction,”和“value,”就行了。

取消wifi功能,只使用LAN

原来是这样的:

| | --- Wireless | |
| | <*> cfg80211 - wireless configuration API | |
| | [*] nl80211 testmode command | |
| | [ ] enable developer warnings | |
| | [ ] cfg80211 regulatory debugging | |
| | [*] enable powersave by default | |
| | [ ] cfg80211 DebugFS entries | |
| | [ ] use statically compiled regulatory rules database | |
| | [*] cfg80211 wireless extensions compatibility | |
| | [*] Wireless extensions sysfs files | |
| | < > Common routines for IEEE802.11 drivers | |
| | [*] Allow reconnect while already connected | |
| | <*> Generic IEEE 802.11 Networking Stack (mac80211) | |
| | [ ] PID controller based rate control algorithm | |
| | [ ] Minstrel | |
| | *** Some wireless drivers require a rate control algorithm *** | |
| | [ ] Enable mac80211 mesh networking (pre-802.11s) support | |
| | [ ] Enable LED triggers | |
| | [ ] Export mac80211 internals in DebugFS | |
| | [ ] Select mac80211 debugging features --->

都给取消掉。

在USB network adaptors里,需要打开对LAN的支持:

位置在:

| -> Device Drivers |
| -> Network device support (NETDEVICES [=n]) |
| -> USB Network Adapters |
| -> Multi-purpose USB Networking Framework (USB_USBNET [=n])

| | <*> Multi-purpose USB Networking Framework | |
| | < > ASIX AX88xxx Based USB 2.0 Ethernet Adapters | |
| | < > QF9700 Base USB 2.0 Ethernet Adapters | |
| | < > CDC Ethernet support (smart devices such as cable modems) | |
| | < > CDC EEM support (NEW) | |
| | < > CDC NCM support | |
| | < > Davicom DM9601 based USB 1.1 10/100 ethernet devices (NEW) | |
| | < > SMSC LAN75XX based USB 2.0 gigabit ethernet devices (NEW) | |
| | <*> SMSC LAN95XX based USB 2.0 10/100 ethernet devices

重点是这个:SMSC LAN95XX based USB 2.0 10/100 ethernet devices

实际操作时,提示这个错误,undefined reference to `snd_pcm_lib_free_vmalloc_buffer',解决起来比较麻烦。最后还是解决了。

需要打开 device drivers/sound:

<*>   OSS PCM (digital audio) API

把这个选上,并且必须是“*”,选为“M”是不可以的。(注:实际操作中不用这么做,这不过是探索过程中的一个困难)

配置以后,编译不过,可以:

make ARCH=arm sun8iw5p1smp_android_defconfig

这样就恢复原状了,可以再重新配置,打开有线网络。

为了让编译快点,lichee/buildroot/scripts/build.sh中在函数build_buildroot中的make ...语句最后加上 -j7,用7个核编译。我的机器虽然12个核,但是担心把别的任务和windows给弄得不能干活,所以就分配7个核去编译。

烧录。发现还需要:netcfg eth0 dhcp

写到/init.rc,没有权限,于是更改android/out/target/product/astar-evb30/root/init.rc,加入:

service myshell /system/bin/busybox sh /system/bin/myshell.sh
user root
group root
disabled
oneshot

on property:sys.boot_completed=1
start preinstall
start myshell

android/out/target/product/astar-evb30/system/bin/myshell.sh中的内容是:

#!/system/bin/busybox sh
BUSYBOX="/system/bin/busybox"

mount -o remount,rw rootfs /
#mount -o remount,rw /dev/block/mtdblock0 /system
mount -o remount,rw /dev/block/by-name/system /system

$BUSYBOX ifconfig eth0 up
netcfg eth0 dhcp

然后只编译android和打包。

extract-bsp
make -j7 || exit
pack

adb shell下 注意权限设置:

mount -o remount,rw rootfs /
mount -o remount,rw /dev/block/mtdblock0 /system

实际发现设备是: mmcblk0,但是执行 mount ... -w /system是失败的。最后用 busybox df -h, 确认设备,改用:
mount -o remount,rw /dev/block/by-name/system /system

解决问题。

cmd下 chcp 65001 (转换为用utf-8编码),但是vi下面仍然有乱码。

到目前为止,解决了开机给分配动态IP地址的问题,仍然不能上网。还需要:(参见:https://blog.csdn.net/qq_35406991/article/details/72798145)

1.在frameworks/base/packages/SettingsProvider/res/values/defaults.xml
<bool name="def_ethernet_on">true</bool> 改成true
<bool name="def_ethernet_mode">true</bool>
添加这两句
<bool name="def_ethernet_conf">true</bool>
<string name="def_ethernet_ifname" translatable="false">eth0</string>

2.在frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java添加

loadBooleanSetting(stmt, Settings.Global.ETHERNET_CONF, R.bool.def_ethernet_conf);
loadStringSetting(stmt, Settings.Global.ETHERNET_IFNAME, R.string.def_ethernet_ifname);

经过测试,这样做是可行的。虽然技术支持商说不需要开机启动 netcfg eth0 dhcp,但实际操作,偶尔需要:

$BUSYBOX ifconfig eth0 up
netcfg eth0 dhcp

为什么是偶尔需要呢,原因还未查明。

可以参考:Android 4.2 Ethernet启动流程,知道关于ethernet的流程。

让开机就用dhcp上网,还有另一种不用修改配置的方法,参见 关于Android系统在开机后无法自动连接以太网的问题,这个是针对Android 4.4的版本,我们的R16似乎是4.3版本的。

最后结论,就是,用不着修改init.rc,但为了开发方便,init.rc加入myshell,还是很方便的,就是目前只需要在myshell.sh中加入remount的部分。

Android 4.4 Kitkat 使能有线网络 Ethernet,提出了更简单的方案,单独尝试后,发现还是不行。

SVN忽略编译产生的中间文件

不这样做,将会增加大概15~16G的中间文件,所以必须这么做。

做distclean后,重新编译,提交时或者查看时间更改的情况,就会分辨出那些是中间文件。但有个问题需要注意。有些是在做 config时产生的中间文件,这些还是用版本工具管理起来。
因为配置一经稳定,后来就变动很少。

lichee/linux-3.4/drivers/gpio/gpiolib.c
lichee/linux-3.4/mm/page_alloc.c

这两个就是需要纳入到版本控制中的。

android/out/target/product/astar-evb30/root/init.rc, 这个我加了东西,但不知道为啥,每次编译该文件要变动时间。所以这个也需要保留。

经过这么整理,不算.svn的空间,整个是12.1G,.svn的空间是18G。

把所有的 *.pyc和*.pyo从版本库中清除。

另外,不做任何改动,make clean后,编译完check in时发现有一批.ko需要重新check in,这些是编译中间生成的文件。可以 记录下来,存成文件

cat ignore.log |xargs svn rm,然后提交。