嵌入式成长轨迹66 【智能家居项目】【ARM 飞凌ok6410】【移植智能家居代码时环境调试问题集锦 】
推荐阅读顺序:
基本环境搭建:
【配置】在虚拟机Ubuntu下NFS网络文件系统建立
《ok6410 Qt移植百科全书》
【配置】QT&QWT&sqlite3安装配置
这中间出现问题可查阅
【调试】ARM QT 移植环境搭建问题---补充《ok6410 Qt移植百科全书》
日常使用:
【配置】将PC端QT代码修改为ARM端可用
【配置】SD卡一键烧写
这中间出现问题可查阅:
【调试】智能家居代码移植时环境调试问题集锦
Version 2012.12.6
调试者 |
郑子木 |
最初问题A描述 |
打算在PC机上先试运行智能家居代码
ui_mainwindow.h执行到第34行#include "qwt_plot.h"出错: /mnt/hgfs/share/ARM/移植/ProgramCode最新PC版/OutPut/ui_mainwindow.h:34:error: qwt_plot.h: No such file or directory
|
A原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
qwt_plot.h是qwt库中的一个文件。那么应该是没有安装qwt库。 |
A解决步骤 //简单的可以多步骤一起列在下面 |
解决:安装qwt库,参考 《【配置】QT&QWT&sqlite3安装配置》 |
A后状况B描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
交叉编译项目时出错: :-1: error: No rule to make target `/mnt/hgfs/share/ARM/移植/ProgramCode最新PC版/OutPut/ui_timedialog.h', needed by `timedialog.o'. Stop. |
B原因分析 |
因为虽然在项目的.pro文件中加入了qwt的路径,但是没有在Ubuntu中将其添加进PATH环境变量 |
B解决步骤 |
解决: 在PATH中加入qwt的路径 |
B后状况C描述 |
:-1: error: No rule to make target `/mnt/hgfs/ProgramCode最新PC版/OutPut/timedialog.ui', needed by `ui_timedialog.h'. Stop. |
C原因分析 //包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
UI界面设计好以后,需要生成对应的.h文件,才可以引用。 |
C解决步骤 //简单的可以多步骤一起列在下面 |
解决:怎么生成.h文件呢?很简单,打开命令行,转到ui文件目录下,输入uic -o ui_***.h ***.ui,执行即可在当前目录下生成名为ui_***的.h文件 |
C后状况D描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
./Database/DBData.h:4:21: error: sqlite3.h: No such file or directory |
D原因分析 |
1、需要注意: 拷贝是需要加上 –arf选项,因为libsqlite3.so,libsqlite3.so.0是链接到libsqlite3.so.0.8.6的。
2、没有将sqlite库所在位置添加到.pro文件的includepath,导致找不到sqlite库。
|
D解决步骤 |
1、 cd /home/sqlite-3.3.8/sqlite-arm-linux/lib cp –arf libsqlite3.so libsqlite3.so.0. libsqlite3.so.0.8.6 /usr/qt-sqlite/lib cd /home/sqlite-3.3.8/bin cp sqlite3 /usr/qt-sqlite 然后把sqlite3和lib下的库文件移植到ARM上
2、在pro的includepath里加上/usr/local/include(有sqlite3.h的地方) |
D后状况E描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
执行PC端代码时(非ARM端) failed QSqlError(-1, "Error opening database", "unable to open database file") QSqlQuery::exec: database not open |
E原因分析 |
1、要求全路径并且数据库文件有写权限 2、拷贝项目后,要改变项目的output路径,否则会找不到很多生成文件。 |
解决步骤E |
1、 google回答: I searched the web and Google told me I need to specify the full path (no ~ or $HOME etc.) of the database file and the web server needs the write permission to the file. Sure, I actually had done both before the exception occurred.
Having being pissed for a while, I finally figured out what was wrong here: The web server needs the write permission to not only the database file, but also the containing directory of that file. 2、拷贝项目后,要在project里边改变output的路径,使之跟自己目前的output路径一致
|
E后状况F描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
/usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: skipping incompatible /usr/local/Trolltech/qt-4.7.1-arm/lib/libqwt.so when searching for -lqwt
|
F原因分析 |
-lqwt的路径未指定或指定了错误位置,导致识别不了-lqwt
|
解决步骤F |
解决方法1、 1)、右键点击工程.pro文件—>Properties of *.pro—>选择Variables选项卡—>左侧栏点击+按钮—>QT Variables选择LIBS,
2)、点击确定,将此QT变量加入—>点击左侧栏刚添加的?LIBS—>右侧栏点击+按钮—>在弹出的文本框中输入库文件:/usr/local/qwt-5.2.1/lib/libqwt.so.5.2.1 或者 -L"/usr/local/qwt-5.2.1/lib/" -lqwt(若编译ARM版本,此库文件必须为安装的ARM版本的qwt目录中的库文件,视具体实际所在目录)—>点击确定—>点击OK,添加完成。
解决方法2、 当然也可直接在.pro文件中修改,在-lqwt前加上-L"/usr/local/qwt-5.2.1/lib/"(若编译ARM版本,此库文件必须为安装的ARM版本的qwt目录中的库文件,视具体实际所在目录)
|
F后状况G描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
/usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: cannot find -lsqlite3 collect2: ld returned 1 exit status make: *** [SmartHome] Error 1
|
G原因分析 |
这是类似的问题,应在pro文件中加入-lsqlite的路径
|
解决步骤G |
在项目的.pro中修改 LIBS += -L"/usr/local/qwt-5.2.1/lib/" -lqwt -lsqlite3 在-lsqlite3前加上-L"" -L后指向静态库sqlite3.a所在目录
|
G后状况H描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
./SmartHome: symbol lookup error: /usr/lib/libqwt.so.5: undefined symbol: _ZN7QWidget16contextMenuEventEP17QContextMenuEvent
|
H原因分析 |
1、没有设置好qwt的环境变量 2、没有在.pro中加入LIBS |
H解决步骤 //简单的可以多步骤一起列在下面 |
1、按文档重新设置。 2、 右键点击工程.pro文件—>Properties of *.pro—>选择Variables选项卡—>左侧栏点击+按钮—>QT Variables选择LIBS,点击确定,将此QT变量加入—>点击左侧栏刚添加的 LIBS—>右侧栏点击+按钮—>在弹出的文本框中输入库文件: /usr/local/qwt-5.2.1/lib/libqwt.so.5.2.1 或者 在.pro文件中加上 -L"/usr/local/qwt-5.2.1/lib/" -lqwt(若编译ARM版本,此库文件必须为安装的ARM版本的qwt目录中的库文件,视具体实际所在目录)—>点击确定—>点击OK,添加完成。
|
H后状况I描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
./SmartHome: error while loading shared libraries: libQtSql.so.4: cannot open shared object file: No such file or directory
|
I原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
Qt sql相关的库未拷贝或者环境变量没有设置好
|
I解决步骤 //简单的可以多步骤一起列在下面 |
设置好环境变量,按文档设置好PATH等。注意设置时有没有奇怪的符号或者漏了什么(不小心打漏引号也会识别不了该环境变量)
|
I后状况J描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
QWSTslibMouseHandlerPrivate: ts_open() failed with error: 'No such file or directory' Please check your tslib installation!
|
J原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
http://blog.163.com/cailing_07@126/ http://blog.163.com/cailing_07@126/blog/static/33915087201211993413287/ http://www.baidu.com/s?wd=Please+check+your+tslib+installation%21+&tn=sogouie_dg http://blog.chinaunix.net/uid-9185047-id-3169508.html http://blog.csdn.net/alan00000/article/details/7194738 http://blog.csdn.net/alan00000/article/details/7194727 http://blog.sina.com.cn/s/blog_6410b69201014mzk.html http://johnylai.i.sohu.com/blog/view/98048548.htm
|
J解决步骤 //简单的可以多步骤一起列在下面 |
1、将环境变量逐条输入 2、修改环境变量export QWS_MOUSE_PROTO=tslib:/dev/event0 3、在编译qt时要配置好tslib参数及修改源代码为tslib支持 4、如果还不行,将上面的环境变量改为: Tslib:dev/input/event0、1、2等(注意要是没用一键烧写而是用tftp 51000000来烧写的话,用bootm运行之后的内核才是新烧写的。重启之后仍会启动一键烧写写定的内核。而这可能导致tslib的文件不一样)
|
J后状况K描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
Database Error: "unable to open database file Error opening database" QSqlQuery::exec: database not open
类似的 [root@FORLINX6410]# /opt/SmartHome/SmartHome/SmartHome -qws -font wenquanyi Open database failed! Database??初??始??化??失??败??了 "show current '??温??度' data of room '??1', area '??1', date '2000-01-01' "
|
K原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
1、 当时调试pc端的时候—— 在qt的.pro中修改 LIBS += -L"/usr/local/qwt-5.2.1/lib/" -lqwt -lsqlite3 在-lsqlite3前加上-L"" -L后指向静态库sqlite3.a所在目录 编译arm端的时候: /usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/http://www.cnblogs.com/http://www.cnblogs.com/arm-none-linux-gnueabi/bin/ld: warning: library search path "/usr/local/lib" is unsafe for cross-compilation 其实arm端的sqlite3.a并不在/usr/local/lib,此时应该将库放在arm板下的此目录。
2、 可能是声明QSqlQuery query时没有与数据库连接名关联啊
3、 放置数据库文件的目录没有权限 数据库文件调用时没有使用绝对路径!!
|
K解决步骤 //简单的可以多步骤一起列在下面 |
1、 其实arm端的sqlite3.a并不在/usr/local/lib,此时应该将库放在arm板下的此目录。
2、 QSqlQuery query 改为 QSqlQuery query(数据库对象名);
3、 对放置数据库文件的目录进行权限设置(可读写,包括子目录) 数据库文件要使用绝对路径!! 1) QSqlDatabase dbconn = QSqlDatabase::addDatabase("QSQLITE"); dbconn.setDatabaseName("/opt/SmartHome/Database/SmartHomeDatabase.db");【注意这里!】 dbconn.setUserName("smartHome"); dbconn.setPassword("123456");
2) //CDatabase.cpp中 bool CDataBase::Init() { if(OpenDB("/opt/SmartHome/Database/SmartHomeDatabase.db"))//【注意这里!】
|
K后状况L描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
希望开机自动启动智能家居,但/etc/init.d/rcS不能运行带参数(-qws等)的命令
|
L原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
非shell脚本命令在初始化时无法添加参数
|
L解决步骤 //简单的可以多步骤一起列在下面 |
解决方法:使用shell脚本 1、在/etc/init.d/rcS 最后一行加上 /etc/init.d/SmartHome.sh &
2、另外在本文件夹中创建SmartHome.sh,内容如下: #! /bin/sh
/opt/SmartHome/SmartHome/SmartHome -qws -font wenquanyi &
3、运行出现错误 /opt/SmartHome/SmartHome/SmartHome: error while loading shared libraries: libQtSql.so.4: cannot oy
在SmartHome.sh中加入所有环境变量,最后内容如下: #! /bin/sh
export PATH='/usr/local/lib:/usr/lib:/opt/qt-4.7.1/lib:/sbin:/usr/sbin:/bin:/usr/bin:/opt/Qtopia4.4.3/lib:/opt/Qtopia4.4.3/bin' export QPEDIR='/opt/qt-4.7.1' export QTDIR='/opt/qt-4.7.1' export QT_QWS_FONTDIR='/opt/qt-4.7.1/lib/fonts' #:/opt/Qtopia4.4.3/lib/fonts' export QWS_DISPLAY='LinuxFb:mmWidth152:mmHeight88:1' export QWS_MOUSE_PROTO='Tslib:/dev/input/event2' #MouseMan:/dev/input/mice' #or /dev/input/event1:Tslib export TSLIB_CALIBFILE='/etc/pointercal' export TSLIB_CONFFILE='/usr/local/tslib/etc/ts.conf' export TSLIB_CONSOLEDEVICE='none' export TSLIB_FBDEVICE='/dev/fb0' export TSLIB_PLUGINDIR='/usr/local/tslib/lib/ts' export TSLIB_ROOT='/usr/local/tslib' export TSLIB_TSDEVICE='/dev/input/event2' #or /dev/input/event2or 1 export TSLIB_TSEVENTTYPE='H3600' export QT_PLUGIN_PATH='/opt/qt-4.7.1/plugins:/opt/Qtopia4.4.3/qt_plugins/' export LD_LIBRARY_PATH=$QTDIR/lib:$QTDIR/plugins/:$TSLIB_ROOT/lib:/usr/local/lib:/usr/lib:/opt/Qtopia4.4.3/qt_plugins/:$LD_LIBRARY_PATH
/opt/SmartHome/SmartHome/SmartHome -qws -font wenquanyi &
成功运行!
|
L后状况M描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
尝试将整个文件系统烧写到Nandflash,让ARM板直接从Nandflash启动,而非通过NFS。
|
M原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
参考《OK6410-A开发板LINUX3.0.1用户手册》3-6-3 烧写yaffs文件系统 (这个只有旧版的mmc能用,2012.9月之后的请参考文档 《【配置】SD卡一键烧写》)
(虽然下面的没用上也补充下) ARM 制作文件系统 http://linux.chinaunix.net/techdoc/system/2008/09/10/1031407.shtml http://www.cppblog.com/jb8164/archive/2008/02/19/42937.html http://blog.sina.com.cn/s/blog_6838b5fb0100kev6.html mkyaffs2image http://blog.csdn.net/bjutstar/article/details/7182089 http://blog.csdn.net/ydk03526203300/article/details/7486356
|
M解决步骤 //简单的可以多步骤一起列在下面 |
参考《OK6410-A开发板LINUX3.0.1用户手册》3-6-3 烧写yaffs文件系统 (这个只有旧版的mmc能用,2012.9月之后的请参考文档 《【配置】SD卡一键烧写》)
PS: 在boot下setenv bootargs "root=/dev/mtdblock3 rootfstype=yaffs2 console=ttySAC0,115200"
记得保存参数:setenv bootargs "root=dev/nfs nfsroot=192.168.0.10:/forlinx/root rw noinitrd init=/linuxrc ip=192.168.1.232:192.168.1.10:192.168.1.1:255.255.255.0 console=ttySAC0,115200"
|
M后状况N描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
/mnt/disk(而不是制作镜像并烧写)来烧写文件系统后,打开出现kernel panic
|
N原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
文件系统层次出错的话会导致kernel panic
|
N解决步骤 //简单的可以多步骤一起列在下面 |
用/mnt/disk(而不是制作镜像并烧写)来烧写文件系统时,不要直接压缩root文件夹。而要将里边的东西全选之后压缩(总之不能直接看到root在里边,而是应该打开就是一堆文件)
|
N后状况O描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
搭建好根文件系统并编译成镜像的之后,下载到开发板上去运行 Failed to execute /linuxrc. Attempting defaults... Kernel panic - not syncing: No init found. Try passing init= option to kernel. . [<c003bca8>] (unwind_backtrace+0x0/0xfc) from [<c04f4718>] (dump_stack+0x18/0x1c) [<c04f4718>] (dump_stack+0x18/0x1c) from [<c04f477c>] (panic+0x60/0x1ac) [<c04f477c>] (panic+0x60/0x1ac) from [<c00355dc>] (init_post+0xc8/0x140) [<c00355dc>] (init_post+0xc8/0x140) from [<c00084c8>] (kernel_init+0xf4/0x130) [<c00084c8>] (kernel_init+0xf4/0x130) from [<c0036a34>] (kernel_thread_exit+0x0/)
|
O原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
原因可能有三个: 1、烧写方法步骤错误 2、内核选项勾选错误,导致编译出来的内核不兼容 3、文件系统搭建出现问题
|
O解决步骤 //简单的可以多步骤一起列在下面 |
参考《【小结】 智能家居项目 ok6410 kernel panic错误小结》
1、烧写方法 1) 一键烧写 飞凌的一键烧写必须把流程整个执行完,如果中间中断必须从头开始烧,不然就算烧写的东西是对的,也会出这个错误。 参考 《【配置】SD卡一键烧写》 2)/mnt/disk烧写(飞凌2012.9以后的板子的mmc等不再支持这一功能) 用/mnt/disk(而不是制作镜像并烧写)来烧写文件系统时,不要直接压缩root文件夹。而要将里边的东西全选之后压缩(总之不能直接看到root在里边,而是压缩文件应该打开就是一堆文件)
2、关于内核编译 1)provide old way to pass kernel parameters http://blog.sina.com.cn/s/blog_69d6931501011b8j.html 在网上搜了很久,各种方法都试过,还是这个问题。 突然想起来参考的移植说明上,在内核的配置中,有一个配置选项我没有选上,或许就是这个问题导致的吧!我试了下,果然就是这个问题。但此时又出现了新的问题。真是一波刚平一波又起啊! 哎!到底该选项怎么影响到linuxrc的执行,还不清楚,先记录下来,以备后来查看!有曾经做过这方面的大牛,或是正在路上的小牛,希望能和小弟一块交流学习。 该选项就是在kernel features下provide old way to pass kernel parameters,有图有真相,呵呵...如下:
2)filesystem 内核要支持你烧写的文件系统,相应的选项也要勾上 这个如果不能保证,内核启动时会出现类似如下错误: VFS: Cannot open root device "mtdblock2" or unknown-block(2,0) Please append a correct "root=" boot option
如果 内核支持文件系统 以及 下边讲的文件系统寻址 这两点能保证,就可以挂接上文件系统,出现类似下面的字样时,革命已经成功了80%: VFS: Mounted root (cramfs filesystem) readonly. Freeing init memory: 116K
3) 在内核中,把网卡加进去就可以了
4)Verify nand page writes
Comment 1 by project member changbin.du@gmail.com, Jun 17, 2012 enable MTD "write verify" option.
Status:Fixed
5)重新配置内核 如果以上都不行,只能这样了——飞凌光盘上有内核代码,这个编译完是可以直接用的。那么,在这个配置的基础上,再勾选后来你需要添加的选项(比方说USB转串口驱动等),进行内核编译。
3、关于文件系统 引用 http://www.100ask.net/forum/showtopic-15.aspx 2楼 韦东山先生: 1)在正确的位置烧写正确的文件系统映象: (a). 正确的位置 (使用飞凌一键烧写就不担心这些,这部分可以跳过) 嵌入式开发中,常通过bootloader烧写文件系统映象,假设写在flash的地址A处。 内核启动时,显然要从地址A处读取文件系统,内核是怎么知道的呢?通过命令行参数,比如“root=/dev/mtdblock2 ”。 /dev/mtdblock2 又是怎么和地址A对应上的呢?内核将flash划分为几个分区,这是在代码中固定的。/dev/mtdblock2是第3个分区,它的开始地址必须是A。 在内核启动时,可以看到这些分区的开始地址、结束地址,比如内核启动时会有类似下面的信息: Creating 3 MTD partitions on "NAND 64MiB 3,3V 8-bit": 0x00000000-0x00030000 : "bootloader" 0x00050000-0x00250000 : "kernel" 0x00250000-0x03ffc000 : "root" 对于上面的内核信息,/dev/mtdblock2对应root分区,开始地址为0x00250000,使用bootloader写文件系统映象时,烧写的地址必须是0x00250000 所以,要保证3点: ① bootloader烧到地址A, ② 地址A是内核某个分区的开始地址, ③ 命令行参数“root=/dev/mtdblockXXX ”是这个分区
(b). 正确格式的文件系统映象 不同的bootloader支持的烧写的文件系统映象格式不同、使用的烧写命令也可能不同,请注意这点。 另外,马大哈们制作文件系统映象时,使用的工具也不要弄错了。 最后,请保证这个文件系统映象是“真的烧写了”,因为如果flash只是擦除而没有烧写,它也是“正确的、可以挂接的文件系统”──有人碰到这个问题,我和他答非所问地折腾了很久。 这个问题如果不能保证,内核启动时会出现类似如下错误: VFS: Cannot open root device "mtdblock2" or unknown-block(2,0) Please append a correct "root=" boot option 如果文件系统寻址以及内核支持文件系统这两点能保证,就可以挂接上文件系统,出现类似下面的字样时,革命已经成功了80%: VFS: Mounted root (cramfs filesystem) readonly. Freeing init memory: 116K
2)文件系统的内容要完备 (如果是在之前验证过可以烧写成功的文件系统基础上进行开发,没有删除文件或修改关键链接,那么这个部分可以跳过) 挂接文件系统后,内核就会读取、执行文件系统中的某个文件,通过它来启动应用程序。这个文件要么通过命令行参数“init=xxxx”来指定,要么取默认的文件(下面说明)。 一般制作文件系统映象时,都是在一个目录(假设目录名为rootfs)下放好各种东西:bin/,sbin/,lib/等目录,etc/fstab等文件,然后将这个目录制作为文件系统映象。 可以想象,如果这个目录中的东西不对、不全,即使制作出了文件系统映象,也只是能识别出来,挂接上去;但是启动不了──所谓启动,不就是执行文件系统中的程序嘛? 这时会有类似以下的错误: Failed to execute /linuxrc. Attempting defaults... Kernel panic - not syncing: No init found. Try passing init= option to kernel. 它说得很明显,"Failed to execute /linuxrc"──执行/linuxrc失败:它为什么要执行/linuxrc,还不是因为你在命令行中加入了“init=/linuxrc”这个参数。 它为什么会失败?原因有二: 一、你制作文件系统映象时,rootfs目录下有linuxrc这个文件吗? 二、rootfs目录的linuxrc文件是正确的吗? 请好好确定这两点,大多数是没有linuxrc文件──linuxrc是busybox自动生成的,只要配置好就可以。 如果有linuxrc,那么就是它无法执行了(解决方法在下面)。 不用linuxrc行不行?当然行!看看内核文件init/main.c,有如下字样: run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh"); panic("No init found. Try passing init= option to kernel."); 就是说,它会依次尝试执行/sbin/init、/etc/init、/bin/init、/bin/sh这些文件,都失败后才打印出错信息"No init found. Try passing init= option to kernel."。 所以,出现这个出错信息时,就表明了没有或是无法执行这些文件:命令行参数“init=xxxx”来指定的xxx文件、/sbin/init、/etc/init、/bin/init、/bin/sh。 一、请检查你的rootfs目录,看看这点些文件是否存在 二、使用file命令看看它们是什么文件类型,是否可执行。 使用busybox时,这些文件是到/bin/busybox文件的链接,那就看看busybox的文件类型,可以使用下面的命令: $ file linuxrc linuxrc: symbolic link to `bin/busybox' $ file bin/busybox bin/busybox: ELF 32-bit LSB executable, ARM, version 1, for GNU/Linux 2.4.3, dynamically linked (uses shared libs), stripped
2)换一个文件系统制作工具。
比方说飞凌的mkyaffs2image-nand2g和mkyaffs2image-nand256m可能不太能用。改用以前mkcramfs则是可以的。但这会生成cramfs文件,所以得要用回 旧的mmc (2012.9之前买的飞凌ok6410光盘附带那个)才能进行一键烧写。
http://blog.csdn.net/ayangke/article/details/6280400 我刚开始以为我的linuxrc没有执行权限,一查看,是有的。 上网一搜,发现好多兄弟都遇到类似的问题,那些回答问题的都说是linuxrc没有加执行权限啊,busybox没有选中shell选项啊,我一看,全是乱说,busybox默认就是选中shell的,除非你手动把他取消掉了,还有生成linuxrc默认就是有可执行权限的。 我把原厂的根文件系统源码拿来编译一次,下载进去还是同样的错误,于是我就朝着mkyaffs2image这个yaffs2文件系统镜像制作工具上去,一搜发现,原来我用的是这个工具不支持128M的nand,有一个哥们对其进行了修改,并使之支持了128M
|
后状况描述 //可以是文字描述、截图等。若步骤过于简单,此栏可略。若出现新问题,则必须填写。下同 |
原因分析//包括资料查找、背景材料等。也可以附上网址。必要的文档可以作附件列后。下同。 |
解决步骤 //简单的可以多步骤一起列在下面 |
以上调试结束 |
PS:QtCreator若不小心在虚拟机中按下全屏选项,只要按alt+w将该选项的勾去掉即可·
附件目录
附件一 |
系统启动挂载根文件系统时Kernel panic |
附件二 |
附件1
题目:系统启动挂载根文件系统时Kernel panic |
来源:http://www.100ask.net/forum/showtopic-15.aspx |
正文内容: |
我制作了根文件系统,在启动之后停在这里了: NET: Registered protocol family 1 NET: Registered protocol family 17 VFS: Mounted root (cramfs filesystem) readonly. Freeing init memory: 116K Failed to execute /linuxrc. Attempting defaults... Kernel panic - not syncing: No init found. Try passing init= option to kernel. 我内核boot option里面的命令行设置为:noitinrd root=/dev/mtdblock2 rootfstype=cramfs console=ttySAC0,115200 init=/linurc mem=64M 做根文件系统时linuxrc的内容如下: #!/bin/sh echo "mount /etc as ramfs" /bin/mount -n -t ramfs ramfs /etc /bin/cp -a /mnt/etc/* /etc echo "re-create the /etc/mtab entries" # re-create the /etc/mtab entries /bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 / /bin/mount -f -t ramfs ramfs /etc exec /sbin/init rcS如下: #!/bin/sh /bin/mount -a 请问大侠,这个问题怎么解决,我内核版本是2.6.19.2的!
回复: 系统启动挂载根文件系统时Kernel panic 这类问题很常见,先总体介绍一下解决思路。 能出现让人激动的的控制台,那么系统移植已经接近完成;但是不少人在最后一步出现问题。 要点如下: 1. 在正确的位置烧写正确格式的文件系统映象: 2. 内核支持这种文件系统格式 3. 文件系统的内容要完备 上面说得简单,一个个介绍。 1. 在正确的位置烧写正确的文件系统映象: (a). 正确的位置 嵌入式开发中,常通过bootloader烧写文件系统映象,假设写在flash的地址A处。 内核启动时,显然要从地址A处读取文件系统,内核是怎么知道的呢?通过命令行参数,比如“root=/dev/mtdblock2 ”。/dev/mtdblock2 又是怎么和地址A对应上的呢?内核将flash划分为 几个分区,这是在代码中固定的。/dev/mtdblock2是第3个分区,它的开始地址必须是A。 在内核启动时,可以看到这些分区的开始地址、结束地址,比如内核启动时会有类似下面的信息: Creating 3 MTD partitions on "NAND 64MiB 3,3V 8-bit": 0x00000000-0x00030000 : "bootloader" 0x00050000-0x00250000 : "kernel" 0x00250000-0x03ffc000 : "root" 对于上面的内核信息,/dev/mtdblock2对应root分区,开始地址为0x00250000,使用bootloader写文件系统映象时,烧写的地址必须是0x00250000 所以,要保证3点:① bootloader烧到地址A,② 地址A是内核某个分区的开始地址,③ 命令行参数“root=/dev/mtdblockXXX ”是这个分区 (b). 正确格式的文件系统映象 不同的bootloader支持的烧写的文件系统映象格式不同、使用的烧写命令也可能不同,请注意这点。 另外,马大哈们制作文件系统映象时,使用的工具也不要弄错了。 最后,请保证这个文件系统映象是“真的烧写了”,因为如果flash只是擦除而没有烧写,它也是“正确的、可以挂接的文件系统”──有人碰到这个问题,我和他答非所问地折腾了很久。 2. 内核支持这种文件系统格式 配置内核时选上要支持的文件系统格式 1、2这两个问题如果不能保证,内核启动时会出现类似如下错误: VFS: Cannot open root device "mtdblock2" or unknown-block(2,0) Please append a correct "root=" boot option 如果1、2能保证,就可以挂接上文件系统,出现类似下面的字样时,革命已经成功了80%: VFS: Mounted root (cramfs filesystem) readonly. Freeing init memory: 116K 3. 文件系统的内容要完备 挂接文件系统后,内核就会读取、执行文件系统中的某个文件,通过它来启动应用程序。这个文件要么通过命令行参数“init=xxxx”来指定,要么取默认的文件(下面说明)。 一般制作文件系统映象时,都是在一个目录(假设目录名为rootfs)下放好各种东西:bin/,sbin/,lib/等目录,etc/fstab等文件,然后将这个目录制作为文件系统映象。 可以想象,如果这个目录中的东西不对、不全,即使制作出了文件系统映象,也只是能识别出来,挂接上去;但是启动不了──所谓启动,不就是执行文件系统中的程序嘛? 这时会有类似以下的错误: Failed to execute /linuxrc. Attempting defaults... Kernel panic - not syncing: No init found. Try passing init= option to kernel. 它说得很明显,"Failed to execute /linuxrc"──执行/linuxrc失败: 它为什么要执行/linuxrc,还不是因为你在命令行中加入了“init=/linuxrc”这个参数。 它为什么会失败?原因有二: 一、你制作文件系统映象时,rootfs目录下有linuxrc这个文件吗? 二、rootfs目录的linuxrc文件是正确的吗? 请好好确定这两点,大多数是没有linuxrc文件──linuxrc是busybox自动生成的,只要配置好就可以。 如果有linuxrc,那么就是它无法执行了(解决方法在下面)。 不用linuxrc行不行?当然行!看看内核文件init/main.c,有如下字样: run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh"); panic("No init found. Try passing init= option to kernel."); 就是说,它会依次尝试执行/sbin/init、/etc/init、/bin/init、/bin/sh这些文件,都失败后才打印出错信息"No init found. Try passing init= option to kernel."。 所以,出现这个出错信息时,就表明了没有或是无法执行这些文件:命令行参数“init=xxxx”来指定的xxx文件、/sbin/init、/etc/init、/bin/init、/bin/sh。 一、请检查你的rootfs目录,看看这点些文件是否存在 二、使用file命令看看它们是什么文件类型,是否可执行。 使用busybox时,这些文件是到/bin/busybox文件的链接,那就看看busybox的文件类型,可以使用下面的命令: $ file linuxrc linuxrc: symbolic link to `bin/busybox' $ file bin/busybox bin/busybox: ELF 32-bit LSB executable, ARM, version 1, for GNU/Linux 2.4.3, dynamically linked (uses shared libs), stripped 注意了:如果bin/busybox 是一个动态链接的文件,还要把它用到的库复制到rootfs中。唉,越说越复杂了。这些库在交叉编译工具的相应目录下,如果不知道,查google,否则再发帖。 最后一点,文件系统中各种配置文件、dev目录也要正确。出现问题时再在这个帖子中说吧。这样写下去真是没完没了。 回到这个帖子,它的内核打印信息为: VFS: Mounted root (cramfs filesystem) readonly. Freeing init memory: 116K Failed to execute /linuxrc. Attempting defaults... Kernel panic - not syncing: No init found. Try passing init= option to kernel. 说明文件系统挂接成功(VFS: Mounted root (cramfs filesystem) readonly.); 还说明/linuxrc不存在或者不可执行(Failed to execute /linuxrc. Attempting defaults...); 但是楼主的意思是linuxrc已经有了,内容为: #!/bin/sh echo "mount /etc as ramfs" /bin/mount -n -t ramfs ramfs /etc /bin/cp -a /mnt/etc/* /etc echo "re-create the /etc/mtab entries" # re-create the /etc/mtab entries /bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 / /bin/mount -f -t ramfs ramfs /etc exec /sbin/init 它是一个脚本,它的执行依赖于/bin/sh,问题转为:/bin/sh是否存在?是否可以执行? 用file命令看看它的类型、是否需要动态库。 解决时请把经验留下。
|
附件2
题目: |
来源: |
正文内容: |