主题 : linux-2.6.38内核移植的经验和疑惑 复制链接 | 浏览器收藏 | 打印
春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是UBUNTU好时节。。。。
级别: 侠客
UID: 24947
精华: 2
发帖: 63
金钱: 430 两
威望: 86 点
贡献值: 2 点
综合积分: 166 分
注册时间: 2010-07-16
最后登录: 2019-04-27
楼主  发表于: 2011-03-29 22:20

 linux-2.6.38内核移植的经验和疑惑

这次的内核移植确实费了我不少神,但让我对linux的启动有了更深的了解。

首先我还是把我的疑惑说出来,以便大虾不要看了就跑了:
我移植后的内核的启动参数只能通过配置boot option成为默认的启动参数,而bootloader传递的参数根本就读不到,
好像arch/arm/kernel/setup.c程序中的strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);没有作用似的。
这样的话内核的启动就很不灵活了,比如要挂载nfs根文件系统就不行咯,这甚是麻烦,而且head-armv.S程序也没有了,不知从和地方下手
希望大虾们赐教赐教。

下面小的献丑贴上自己的一些小经验:

 首先还是根据mini2440 的《linux 移植开发指南》把驱动nandflash分区表等等改好。
然后make menuconfig配置好内核之后执行 (内核的配置可参照光盘2.6.32的配置以及使用手册)
make zImage 编译

 问题一:
复制代码
  1. arch/arm/mach-s3c2440/mach-mini2440.c:189: error: array type has incomplete element type
  2. arch/arm/mach-s3c2440/mach-mini2440.c:190: error: array index in non-array initializer
  3. arch/arm/mach-s3c2440/mach-mini2440.c:190: error: (near initialization for 'smdk_default_nand_part')
  4. arch/arm/mach-s3c2440/mach-mini2440.c:191: error: field name not in record or union initializer
  5. arch/arm/mach-s3c2440/mach-mini2440.c:191: error: (near initialization for 'smdk_default_nand_part')
  6. arch/arm/mach-s3c2440/mach-mini2440.c:193: error: unknown field 'tacls' specified in initializer
  7. arch/arm/mach-s3c2440/mach-mini2440.c:193: warning: excess elements in struct initializer
  8. arch/arm/mach-s3c2440/mach-mini2440.c:193: warning: (near initialization for 'mini2440_nand_info')
  9. arch/arm/mach-s3c2440/mach-mini2440.c:194: error: unknown field 'twrph0' specified in initializer
  10. arch/arm/mach-s3c2440/mach-mini2440.c:194: warning: excess elements in struct initializer
  11. arch/arm/mach-s3c2440/mach-mini2440.c:194: warning: (near initialization for 'mini2440_nand_info')
  12. arch/arm/mach-s3c2440/mach-mini2440.c:195: error: unknown field 'twrph1' specified in initializer
  13. arch/arm/mach-s3c2440/mach-mini2440.c:195: warning: excess elements in struct initializer
  14. arch/arm/mach-s3c2440/mach-mini2440.c:195: warning: (near initialization for 'mini2440_nand_info')
  15. arch/arm/mach-s3c2440/mach-mini2440.c:196: error: unknown field 'nr_sets' specified in initializer
  16. arch/arm/mach-s3c2440/mach-mini2440.c:196: warning: type defaults to 'int' in declaration of 'type name'
  17. arch/arm/mach-s3c2440/mach-mini2440.c:196: warning: type defaults to 'int' in declaration of 'type name'
  18. arch/arm/mach-s3c2440/mach-mini2440.c:196: error: negative width in bit-field '<anonymous>'
  19. arch/arm/mach-s3c2440/mach-mini2440.c:196: warning: excess elements in struct initializer
  20. arch/arm/mach-s3c2440/mach-mini2440.c:196: warning: (near initialization for 'mini2440_nand_info')
  21. arch/arm/mach-s3c2440/mach-mini2440.c:197: error: unknown field 'sets' specified in initializer
  22. arch/arm/mach-s3c2440/mach-mini2440.c:197: warning: excess elements in struct initializer
  23. arch/arm/mach-s3c2440/mach-mini2440.c:197: warning: (near initialization for 'mini2440_nand_info')
  24. arch/arm/mach-s3c2440/mach-mini2440.c:198: error: unknown field 'ingnore_unset_ecc' specified in initializer
  25. arch/arm/mach-s3c2440/mach-mini2440.c:198: warning: excess elements in struct initializer

我想这因该是头文件缺少了的原因吧,于是拿友善之臂移植的源代码一对比发现少了不少的头文件,我用了投机取巧的方法把他的头文件全都拷贝过来覆盖掉以前的
呵呵,大家有兴趣的话可以用source insight查看一下
然后再编译,果然通过,可是问题也接踵而来:

问题二:
复制代码
  1. drivers/char/mini2440_adc.c: In function 's3c2410_adc_read':
  2. drivers/char/mini2440_adc.c:90: error: 'ADC_LOCK' undeclared (first use in this function)
  3. drivers/char/mini2440_adc.c:90: error: (Each undeclared identifier is reported only once
  4. drivers/char/mini2440_adc.c:90: error: for each function it appears in.)
  5. drivers/char/mini2440_adc.c: At top level:
  6. drivers/char/mini2440_adc.c:193: error: 'ADC_LOCK' undeclared here (not in a function)
  7. drivers/char/mini2440_adc.c:193: warning: type defaults to 'int' in declaration of 'ADC_LOCK'
  8. make[2]: *** [drivers/char/mini2440_adc.o] 错误 1
  9. make[1]: *** [drivers/char] 错误 2
  10. make: *** [drivers] 错误 2

我惊讶了,这个驱动可是在linux2.6.32下跑到好好的啊,怎么会在这里出问题呢,况且
信号量ADC_LOCK已经用宏定义:
DECLARE_MUTEX(ADC_LOCK)
定义了且初始化为1了啊;
在网上疯狂的搜索都没有办法,查看内核文档也没有细节;
我真的要抓狂了,结果一晚上都没怎么睡好,仔细想想,难道信号量的机制在linux2.6.38中改写了,
于是第二天一大早的跑到实验室用source insight搜索DECLARE_MUTEX,结果没搜到,我确实很郁闷,因为
以前我们都是利用这个宏定义简单的把定义和初始化的工作做完,现在放弃有点不方便把,心有不甘,再尝试着
搜索sema_init符号,结果在semaphore.h中找到了,令人惊讶的是就在上面
有了:
复制代码
  1. #define DEFINE_SEMAPHORE(name)    \
  2.     struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)

我接着查看__SEMAPHORE_INITIALIZER的定义:
复制代码
  1. #define __SEMAPHORE_INITIALIZER(name, n)                \
  2. {                                    \
  3.     .lock        = __SPIN_LOCK_UNLOCKED((name).lock),        \
  4.     .count        = n,                        \
  5.     .wait_list    = LIST_HEAD_INIT((name).wait_list),        \
  6. }

这不就是DECLARE_MUTEX()的功能吗?!

问题找到了于是马上动手将DECLARE改成DEFINE
一编译,通过了生成了zImage 文件
我马上下载运行结果串口界面卡在了
boot kernel......
而屏幕上显示了
VFS: Cannot open root device "<NULL>" or unknown-block(2,0)
我试着改写bootloader的传递参数,和重新制作yaffs文件系统,都不行
我怀疑中间的 "<NULL>"值,是因为内核没有拷贝到bootloader传来的参数?
于是我在配置选项的boot option 里的Default kernel command string中填上如下信息:
  noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0 rootfs=yaffs2
感谢天和地,启动了
至与Read-only file system的问题,在启动参数里加上rootfs=yaffs2 rw即:
noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0 rootfs=yaffs2 rw

至于为什么不能拷贝到bootloader传来的参数确实是需要大家的帮助。
[ 此帖被小荷尖尖在2011-03-29 22:25重新编辑 ]
级别: 侠客
UID: 57357
精华: 0
发帖: 100
金钱: 505 两
威望: 101 点
贡献值: 0 点
综合积分: 200 分
注册时间: 2011-10-23
最后登录: 2017-09-13
1楼  发表于: 2014-04-25 14:41
~~~~~~~~~~~