Linux移植遇到的一些问题及解决方法(arm开发板)

1. 前言
   自上次研究嵌入式系统以后,已经过了12年了,这期间,linux内核和硬件都发生了非常大的变化,加这方面的开发人员相对较少,碰到一些问题,需要耗费比较多的时间和精力来搜索资料和自己研究,对于没于耐心和基础的人来说,确实不容易坚持下去。这方面的网上资料,有很多是培训机构或者爱好者发的,其正确性也需要验证才能知道,也有很多是以诈传诈,或者语焉不详,要处之处一笔跳过,或者语焉不详,要处之处一笔跳过,或干脆不写。另外,linux开发的问题,就是搭建环境比较麻烦,
库版本的兼容性有差别,经常遇到库不兼容,缺这个库少那个库的问题。 泛此种种,就需要靠自己,不断的尝试工,不断的测试和探索,反反复复做测试,其辛苦只有做过的人才知道,但是走过一遍之后,对底层技术和相关开发知识就有了更深入的认识了,付出也是值得的,同志们共勉吧。

2. 编译linux内核遇到的一些问题及对策

2.1 错误信息:
include/linux/if_pppox.h:24: included file 'linux/if_pppolac.h' is not exported
include/linux/if_pppox.h:25: included file 'linux/if_pppopns.h' is not exported
linux/kernel.h:65: userspace cannot reference function or variable defined in the kernel
include/linux/kernel.h:97: userspace cannot reference function or variable defined in the kernel
include/linux/quota.h:175: userspace cannot reference function or variable defined in the kernel
include/linux/soundcard.h:1054: userspace cannot reference function or variable defined in the kernel

解决方法:
编辑:include/linux/Kbuild
找到这一行:header-y += if_pppox.h 
在其下面加入如下两行:
header-y += if_pppolac.h
header-y += if_pppopns.h

2.2 错误信息:
Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl
解决方法:
打开 kernel/timeconst.pl

定位到以下内容:
@val = @{$canned_values{$hz}}; 
if (defined(@val)) { 
@val = compute_values($hz); 

output($hz, @val); 
将if (defined(@val)) 改为if (@val),再次编译就可以通过了。

2.3 错误信息:
openssl/opensslv.h: No such file or directory错误的解决办法
解决方法:
缺少openssl库,找到相应库安装,比如,centos-7中,
yum install openssl-devel 

2.4 错误信息:
"mkimage" command not found - U-Boot images will not be built

解决方法:
这是生成uImage时,要用于u-boot下的一个工具,这是安装u-boot时的会
生成的工具,对u-boot编译后,uboot的tools目录下有这个工具。

2.5 错误信息:
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)

原因分析及对策:这是一个让新手或者没见识过的人非常头痛的问题,很长时间没办法下手,根本不知道原因是什么。但是看信息,好像又是和文件系统相关,挂不上root 文件系统,unknown-block(0,0)又似乎和flash块相关,经过反复对比和测试,发现有2个原因:
(1) 对于支持设备树的linux内核而言,没有将emmmc的相关配置加进设备树,内核启动的时候都看不到emmc相关信息,或者是设备树配置不正确,这个需要寻求硬件厂家支持,给到相应的资料和电路原理路;
(2) linux内核启动参数问题,这也是一个很容易忽略的地方,这个坑也是隐藏的比较深,一不小心就错过了,比如以下配置
就会出现这个问题:
Kernel command line: 
root=/dev/mmcblk1p2 rw console=ttySAC2,115200 init=/linuxrc earlyprintk
而正确的配置是:
root=/dev/mmcblk1p2 rw console=ttySAC2,115200 init=/linuxrc rootwait
即加上这个rootwait,至于为什么,可以参看内核代码。这也太坑了,这个问题足
以让你折腾3天3夜。

2.6 关于烧写程序fastboot的问题
在有些烧写程序启动时,如果不在串口输入fastboot命令,pc是识别不到otg区动的,而扯蛋的是有些版本的烧写程序输入fastboot回车即可,而有的版本输入fastboot会提示:
fastboot <USB_controller>
    - run as a fastboot usb device
要输入:fastboot 0 回车,才会影响命令。

2.7 错误信息:
drivers/scsi/osd/osd_initiator.c: In function ‘build_test’:
drivers/scsi/osd/osd_initiator.c:67:2: error: size of unnamed array is negative
  BUILD_BUG_ON(sizeof(struct osdv2_cdb) != OSD_TOTAL_CDB_LEN);
  ^
drivers/scsi/osd/osd_initiator.c:68:2: error: size of unnamed array is negative
  BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN);
  ^
make[3]: *** [drivers/scsi/osd/osd_initiator.o] Error 1
make[2]: *** [drivers/scsi/osd] Error 2
make[1]: *** [drivers/scsi] Error 2
make: *** [drivers] Error 2

解决方法:具体原因先没时间分析,打开文件:drivers/scsi/osd/osd_initiator.c

//注释掉67,68两行
     63 static inline void build_test(void)
     64 {
     65         /* structures were not packed */
     66         BUILD_BUG_ON(sizeof(struct osd_capability) != OSD_CAP_LEN);
     67         //BUILD_BUG_ON(sizeof(struct osdv2_cdb) != OSD_TOTAL_CDB_LEN);
     68         //BUILD_BUG_ON(sizeof(struct osdv1_cdb) != OSDv1_TOTAL_CDB_LEN);
     69 }

2.8 错误信息:
missing bus glue for ehci-hcd
解决方法:
如果你的硬件不支持这个特性,就在内核配置中去掉这一项:
make menuconfig
Device Drivers -> USB support -> EHCI HCD(usb 2.0 support) 去掉,硬件不支持

2.9 错误信息:
arch/arm/plat-samsung/dev-i2c0.c:69: undefined reference to `s3c_i2c0_cfg_gpio'
解决方法:
对于s5pv210的核片,在内核中没有选中smdkv210,编译就会出现这个莫名奇妙的错误。

2.10 错误信息:
hival/rpm.c: In function ‘fileaction_setowngrp’:
archival/rpm.c:385:2: warning: ignoring return value of ‘chown’, declared with attribute warn_unused_result [-Wunused-result]
  chown(filename, uid, gid);
  ^
In file included from /usr/include/bits/byteswap.h:35:0,
                 from /usr/include/byteswap.h:24,
                 from include/platform.h:107,
                 from include/libbb.h:13,
                 from archival/rpm.c:10:
archival/rpm.c: In function ‘rpm_getint’:
archival/rpm.c:351:10: error: invalid 'asm': invalid operand for code 'w'
   return ntohs(*(int16_t*)tmpint);
          ^
make[1]: *** [archival/rpm.o] Error 1
make: *** [archival] Error 2

错误信息分析:以上看起来是因为ntohs的问题,特别是这一句:
invalid 'asm': invalid operand for code 'w'
其根本原因,是交叉编译工具跑到主机的头文件搜索中去了,而交叉编译工具应在交叉编译工具的配置头文件中去搜索。看看这路径:In file included from /usr/include/bits/byteswap.h:35:0,应将/etc/profile中的C_INCLUDE_PATH先去掉,不要让交叉工具跑去主机目录下去搜。修改后,再将查看搜索路径:查看头文件搜索路径
arm-linux-gnueabihf-gcc -E -v -

/usr/local/arm-linux/lib/gcc/arm-linux-gnueabihf/4.9.1/include
这样显示就对了。

2.11 错误信息:
In file included from /usr/local/arm-linux/arm-linux-gnueabihf/include/stdlib.h:959:0,
                 from include/libbb.h:24,
                 from libbb/login.c:14:
/usr/local/arm-linux/arm-linux-gnueabihf/include/bits/stdlib.h: In function ‘wctomb’:
/usr/local/arm-linux/arm-linux-gnueabihf/include/bits/stdlib.h:90:3: error: #error "Assumed value of MB_LEN_MAX wrong"
 # error "Assumed value of MB_LEN_MAX wrong"
 
原因分析及对策:在网上查到以下几句:

By default the limits.h file is not properly configured, so you need to patch it.To fix the problem you have to go inside GCC's source directory and type the command:

cd $GCC_VERSION
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
`dirname $(${TARGET}-gcc -print-libgcc-file-name)`/include-fixed/limits.h

cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
`dirname $(${TARGET}-gcc -print-libgcc-file-name)`/include-fixed/limits.h


This adds a #include_next <limits.h> to the bottom which eventually picks up the right header
   ^
   
    88 #define __STDLIB_MB_LEN_MAX     16
     89 #if defined MB_LEN_MAX && MB_LEN_MAX != __STDLIB_MB_LEN_MAX
     90 # error "Assumed value of MB_LEN_MAX wrong"
     91 #endif

glimits.h 中有这么一句
/* Maximum length of a multibyte character.  */
#ifndef MB_LEN_MAX
#define MB_LEN_MAX 1
#endif
这里怎么定义为1呢,改为16试试?也就是两个地方定义不一致

多字节字符最大长度,改大是最好的。

2.12 错误信息:
Error: unrecognized/unsupported machine ID (r1 = 0x00000d8a).

Available machine support:

ID (hex)        NAME
ffffffff        Generic DT based system
ffffffff        Samsung S5PC110/S5PV210-based board

Please check your kernel config and/or bootloader.

原因分析:对于s5pv210的板子,这是硬件厂家的u-boot中将machine ID设置为0x00000d8a,而内核编译配置时,没有选中SMDKV210这个固件编译,还有是应将arch/arm/tools/mach-types 这个文件中定义的smdkv210 的值改为3466(0x00000d8a),强烈鄙视这些无良开发板厂家,埋了这么多坑,在文档中只字不提,你问他他还不愿意说清楚。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值