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

  • Post author:
  • Post category:linux



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),强烈鄙视这些无良开发板厂家,埋了这么多坑,在文档中只字不提,你问他他还不愿意说清楚。



版权声明:本文为ComputerInBook原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。