一、linux-2.6.28.7内核配置过程
1,新编译好的内核下载到FLASH中,启动linux以后报错,说找不到rootfs入口,解决方法是内核编译选项中选中“file system->yaffs2 fs support”,以及"let yaffs to its ecc".
2,烧写好内核及文件系统后,发现无论怎么点击触摸屏,系统都没有反应,可是开发板自带的kernel烧上去后就没有问题,所以,判断问题还是出于内核配置的问题。解决办法是内核配置“device drivers->input device->(*)touchscreen interface并且(*)touchscreen event”, 以及“device drivers->input device->touchscreen->enable s3c2410 touchscreen”。配置完成以后,启动linux以后触屏功能正常,正常进入到屏幕校准的程序。但是屏幕校准很多次都有问题,判断有可能是x和y的坐标颠倒了,下面进行修改。(其实起初我也不能肯定是哪里有问题,只是命令行能打印出touchscreen点击的坐标信息,但是系统界面就是没有反应,所以我才想驱动应该没问题,问题可能出在和qtopia沟通的问题,然而文件系统又没有问题,因此,我只能抱着试试的态度把内核当中的touchscreen interface选上,再把event功能选上,没想到还真的行了,其实就是猜出来的。现在真是汗颜呀。。。以后开发要是靠猜的话,那活就没法干了。。。)
3,现在出现屏幕校准总是无法通过的问题,看开发板的说明文档上说,应该是x和y坐标颠倒了。因此想办法修改代码。我确定是/drivers/input/touchscreen/s3c2410_ts.c这个文件操作touchscreen,但是不应该修改驱动代码(因为代码没有错),只能修改与板相关的定义文档,因此修改了/arch/arm/plat-s3c/include/plat/regs-adc.h,这些都是与板相关的寄存器值的定义,我修改了:
#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C)
#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
修改为
#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x0C)
#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x10)
然后重新编译内核,烧入后就解决了这个问题,触摸屏成功校准,然后一切正常。
考虑这次修改,把x和y的数据寄存器交换了,我觉得这样改有可能在以后会出现问题,比如可能影响到AD转换时的某些功能。但是目前真想不出什么更好的办法,先这样吧。
4.为开发板配置LED流水灯驱动和功能
需要首先配置内核,“device drivers->leds driver->(M)led class”以及“device drivers->leds driver->(M)s3c24xx led drivers”总共选择了两项,并且都选择编译为模块的形式。保存,
在重新编译内核之前,需要修改一下内核当中的板级文件,这里主要需要修改/arch/arm/plat-s3c24xx/common-smdk.c文件,里面定义了led设备的led-platform-device和led-platdata,在这个文件中,需要根据开发板硬件电路图分析出led接在哪个GPIO口上了,然后进行相应修改,文件中原来是GPF4,改为GPB5,改了四个灯。然后修改文件中的设备结构数组,修改设备初始化函数。这些地方都需要修改,修改内容根据修改后的led-platform-device和led-platdata。
修改完后,重新编译内核,结果在/drivers/leds/目录下生成了两个文件:leds-class.ko以及s3c24xx-leds.ko. 其中,s3c24xx-leds.ko模块依赖于leds-class.ko文件,insmod的时候,需要先insmod leds-class.ko文件。
在开发板上成功insmod s3c24xx-leds.ko后,可以发现在/sys/devices/platform/下面多了led灯的设备,让灯点亮和熄灭的方法是:
cd /sys/devices/platform/s3c24xx-led.0/s3c24xx-led.0
echo 1 > brightness(开灯)
echo 0 > brightness(关灯)
5,配置网络文件系统(NFS)
之前按照开发板手册进行NFS挂载,结果怎么也挂不上。今天(20110603)才终于发现,原来是内核配置有问题,最后配置的时候经过这样配置,就成功挂载了:file system->network file system->
--- Network File Systems │ │
│ │ <*> NFS client support │ │
│ │ [*] NFS client support for NFS version 3 │ │
│ │ [ ] NFS client support for the NFSv3 ACL protocol extension│ │
│ │ [ ] NFS client support for NFS version 4 (EXPERIMENTAL) │ │
│ │ [ ] Root file system on NFS
6,内核突然出现不能insmod模块的问题及解决。
今天(20110611)希望给内核上insmod一个驱动,结果insmod出错,不能insmod这个驱动,然后我就觉得奇怪,为什么突然不能insmod了?然后我就把以前曾经测试没问题的流水灯的驱动模块试着加载一下,结果也加载不上,insmod leds-class.ko的时候,出现“unknown relocation:40”。真是太奇怪了!以前明明都行的!后来到网上一查,据说是因为binutil这个工具被我升级了,才会导致的,是内核的一个bug,需要打个patch,没办法,只好去找patch了。但是我记得我好像没升级过呀,网上有网友说他从binutils2.8升级到2.9就出现这个问题,但是我怎么也不记得自己升级过,算了,只好打补丁了。找到一个arm_R_ARM_V4BX_fix.patch的包,然后打上:patch -p1 arm_R_ARM_V4BX_fix.patch
然后重新编译内核。
结果这回终于可以把模块insmod上了。
7,为内核添加USB闪存的支持功能
这个功能需要配置如下地方:
--- USB support │ │
│ │ <*> Support for Host-side USB │ │
│ │ [ ] USB verbose debug messages │ │
│ │ [ ] USB announce new devices │ │
│ │ *** Miscellaneous USB options *** │ │
│ │ [*] USB device filesystem │ │
│ │ [*] USB device class-devices (DEPRECATED) │ │
│ │ [ ] Dynamic USB minor allocation │ │
│ │ [*] USB Monitor │ │
│ │ < > Enable Wireless USB extensions (EXPERIMENTAL) │ │
│ │ < > Support WUSB Cable Based Association (CBA)
*** USB Host Controller Drivers *** │ │
│ │ < > Cypress C67x00 HCD support │ │
│ │ < > ISP116X HCD support │ │
│ │ <*> OHCI HCD support │ │
│ │ < > SL811HS HCD support │ │
│ │ < > R8A66597 HCD support │ │
│ │ < > Host Wire Adapter (HWA) driver (EXPERIMENTAL) │ │
│ │ < > Inventra Highspeed Dual Role Controller (TI, ...)
*** NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may al│ │
│ │ *** see USB_STORAGE Help for more information *** │ │
│ │ <M> USB Mass Storage support │ │
│ │ [ ] USB Mass Storage verbose debug │ │
│ │ [ ] Datafab Compact Flash Reader support │ │
│ │ [ ] Freecom USB/ATAPI Bridge support │ │
│ │ [ ] ISD-200 USB/ATA Bridge support │ │
│ │ [ ] Microtech/ZiO! CompactFlash/SmartMedia support │ │
│ │ [ ] USBAT/USBAT02-based storage support │ │
│ │ [ ] SanDisk SDDR-09 (and other SmartMedia) support │ │
│ │ [ ] SanDisk SDDR-55 SmartMedia support
以上将USB的host端以及usb mass storage support都加上了。但是配置文件还提到需要加上SCSI支持,配置如下:
< > RAID Transport Class │ │
│ │ <*> SCSI device support │ │
│ │ <M> SCSI target support │ │
│ │ [*] legacy /proc/scsi/ support │ │
│ │ *** SCSI support type (disk, tape, CD-ROM) *** │ │
│ │ <*> SCSI disk support │ │
│ │ <M> SCSI tape support │ │
│ │ < > SCSI OnStream SC-x0 tape support │ │
│ │ <M> SCSI CDROM support │ │
│ │ [*] Enable vendor-specific extensions (for SCSI CDROM) │ │
│ │ <*> SCSI generic support
需要选上scsi disk support。
编译完后,把usb-storage.ko文件拷贝到文件系统中,然后insmod,就会打印出usb闪存的相关信息,这时在/dev目录中就会出现sda和sda1了,如果没出现的话,输入命令mdev -s然后就会出现了,当然前提是你已经mount sys proc了。这时执行命令mount /dev/sda1 /mnt就可以把U盘加入系统中了。
利用同样的方法,可以把USB鼠标等设备在内核配置完成,主要就是开启ohci hcd support, usb human interface device(full HID) support,就可以添加usb1.1主机和HID设备,见linux设备驱动开发详解第二版518页。
8, 需要为我的板子加上摄像头驱动。
具体方法是:
1>找到smdk2440官方板级支持包BSP,该BSP的下载方式见我的另外一篇博客。在SMDK2440的BSP中,有linux下的摄像头驱动源代码,也有适合ADS下运行的无操作系统时的摄像头应用的程序。ADS下的摄像头应用程序应该需要修改一下才能正常跑起来,因为我的摄像头硬件是OV9650的,但是代码里的硬件应该不是这个的。最后我没有用这个ADS下的摄像头程序,而是使用的FL2440开发板自带的那套ADS下的实验程序代码,那里面也有摄像头的应用程序,而且是可以正常运行的,运行了一下,发现可以正常进行preview的操作,因此可以参照这个ADS的摄像头程序,来修改linux下的摄像头驱动源代码。官方提供的SMDK2440的linux摄像头驱动,也不是针对ov9650的,但是应该可以修改得到。
2>进行linux下摄像头驱动的代码修改和移植。这套代码编译的时候报了很多的错误,我是费了很大的劲才把所有的error都改没了,为了图快,有些error随便改了一下,就为了先编译通过,可能以后会出问题,但是先这样吧。然后可以将编译出来的几个ko文件insmod到我的内核上了。主要是insmod videodev.ko insmod videodrv.ko insmod imgsensor.ko,然后insmod都是成功的,而且在执行mdev -s以后,会在/dev目录下生成preview和codec两个文件,但是执行cat preview的时候,内核报错,说是空指针错误。检查代码以后发现,应该是imgsensor在insmod以后并没有调用驱动中的probe函数。
3>解决不调用probe函数的问题。检查以前看到的led驱动,它的那个probe函数就会自动调用,发现原来是在common-smdk2410中,创建了几个platform_device类型的led设备,这些设备的.name参数的名称与我的led驱动的platform_driver类型的驱动的.name参数的名称一致,结果就会自动调用probe。我的imgsensor驱动是i2c设备驱动,但是我找遍plat-s3c24xx文件夹也找不到i2c设备的设备声明,所以也就没有.name参数可以匹配,因此我的probe函数才不会被调用。最后的解决办法是,对内核进行配置,发现内核原来并没有配置i2c设备的驱动和i2c适配器的驱动,配置上了以后,发现在代码没有修改的情况下,probe函数被成功调用。原来,i2c的驱动可以不需要与i2c设备的.name参数名称一致才调用probe函数,i2c_client结构会在i2c的驱动里自己进行设置。
4>我后来还是放弃移植SMDK2440的摄像头驱动了,因为移植成功了以后,insmod也成功了,但是就是认不出摄像头,可能是某些地方的配置不同吧,毕竟我的摄像头是ov9650的,而驱动上的是别的型号的。最后我尝试的方法是把开发板裸机跑起来没有问题的摄像头程序,移植到linux系统中,我觉得这种方式肯定会成功,因为我有了可以参照的版本,而且人家已经验证成功了,所以开始了裸机程序的移植工作。
5>裸机程序已经成功移植到linux系统的驱动上了,可是在运行的时候,并不能实现预想的摄像头preview的功能,而是满屏的雪花,乱到一比那啥。看来不了解摄像头原理,完全靠移植别人的代码,是很难办成事的。所以找到了官方提供的摄像头芯片手册和操作文档,之前手里的文档非常少,都是开发板自带的,手册上写的那个简单呀,啥也看不懂。现在有了文档,应该好办事多了吧。现在准备根据文档重新研读和修改我的代码。另外,又在网上找到了两篇比较好的相关文章可以参考,具体是:
http://blog.simophin.net/?p=642
http://www.docin.com/p-105965008.html
一个关于linux摄像头驱动原理的文章:http://www.docin.com/p-59858494.html
二、文件系统配置过程
1,擦除板子上原有文件系统,建立新的yaffs文件系统。详细建立方法见我的博客u-boot-2010.12移植到2440(六,yaffs2文件系统移植)
2,(这步有问题,需要略过)烧写上制作好的yaffs文件系统,启动开发板,成功登入命令行。下一步,进行界面的移植,使用qtopia,进行qtopia文件系统的移植。
(20110528)首先,下载qtopia的原代码,qtopia-core-opensource-src-4.2.0.tar.gz,下载地址请见我的另一篇博客。
第二,解压缩qtopia-core-opensource-src-4.2.0.tar.gz包到本地。
第三,进入解压后目录,然后进行代码的配置,我需要为S3C2440配置用户界面文件系统,因此配置命令为:./configure -release -embedded arm -depths 16,32 -qt-zlib -qt-gif -qt-libpng -qt-libmng -qt-libjpeg -little-endian
配置的时候,我开始多加了一个配置参数:-xplatform linux-g++ 加上这个配置参数以后,我在make的时候报错了,错误是“Error: no such instruction: `swp ......”, 然后我把这个配置参数去掉以后,就编译通过了。
第四,make
第五,make install
3,(20110529)不好意思,后来在我把qtopia-core编译完成后才发现,原来我下载的qtopia-core-opensource-src-4.2.0.tar.gz这个包不是包含用户窗口界面的那个qtopia,正如它的名字一样,它只是qtopia的core,因此我虽然编译完了,但是不能用,惨呀。。。需要重新下载qtopia-opensource-src-4.2.0.tar.gz,然后重新编译,找了半天,才在网上找到一个官方下载,只找到4.2.5的,qtopia-opensource-src-4.2.5-snapshot-20070915.tar.gz, 具体下载地址,见我的另一篇博客。下一步,进行配置和编译。
第一:tar -zxvf qtopia-opensource-src-4.2.5-snapshot-20070915.tar.gz
mv qtopia-opensource-src-4.2.5-snapshot-20070915 qtopia-src-4.2.5
mkdir qtopia-build
mkdir qtopia-image
cd qtopia-build
../qtopia-src-4.2.5/configure -release -image /media/work/workspaces/workspace2/fs-2.6.28/qtopia/qtopia-opensource-src-4.2.5-snapshot-20070915/qtopia-image -prefix /media/work/workspaces/workspace2/fs-2.6.28/qtopia/qtopia-opensource-src-4.2.5-snapshot-20070915/qtopia-image -xplatform linux-arm-g++ -arch arm -displaysize 320x240 -extra-qtopiacore-config "-release -xplatform qws/linux-arm-g++ -embedded arm -depths 16,32 -qt-zlib -qt-gif -qt-libpng -qt-libmng -qt-libjpeg -little-endian" -extra-qt-config "-little-endian"
注意,上面的这个配置有 问题,-prefix是在运行时路径,我就是设错了这个路径,结果必须重新编译。
../qtopia-src-4.2.5/configure -release -image /media/work/workspaces/workspace2/fs-2.6.28/qtopia/qtopia-opensource-src-4.2.5-snapshot-20070915/qtopia-image -prefix / -xplatform linux-arm-g++ -arch arm -displaysize 320x240 -extra-qtopiacore-config "-release -xplatform qws/linux-arm-g++ -embedded arm -depths 16,32 -qt-zlib -qt-gif -qt-libpng -qt-libmng -qt-libjpeg -little-endian" -extra-qt-config "-little-endian"
注意, -image 这两个选项在配置的时候一定要输入绝对路径,我就是开始输入相对路径,在make的时候是成功了,但是make install的时候却出了错误,害得我查错查了半天,最后还必须重新配置和编译,浪费了很多个小时。
由于烧写到板子上一运行,总是报错说找不到帧缓冲的文件,因此把帧缓冲给关了,然后按照我的另外一篇博客上介绍qtopia移植的方法,修改了几个参数,如下:
../qtopia-src-4.2.5/configure -release -image /media/work/workspaces/workspace2/fs-2.6.28/qtopia/qtopia-opensource-src-4.2.5-snapshot-20070915/qtopia-image -prefix /qtopia -xplatform linux-arm-g++ -arch arm -displaysize 320x240 -no-qvfb -no-modem -quicklaunch -no-bluetooth -no-drm -extra-qtopiacore-config "-release -xplatform qws/linux-arm-g++ -embedded arm -depths 16,32 -no-mouse-linuxtp -qt-zlib -qt-gif -qt-libpng -qt-libmng -qt-libjpeg -little-endian" -extra-qt-config "-embedded arm -little-endian"(这个命令经过测试,可以正常编译和运行qtopia,并进入界面)
第二:make
出错了,解决方法是:
1># cd src/libraries/qtopiabase/
# cp custom-linux-cassiopeia-g++.h custom-linux-arm-g++.h
# cp custom-linux-cassiopeia-g++.cpp custom-linux-arm-g++.cpp
2>vim qtopiacore/qt/tools/qvfb/qvfbshmem.cpp
注释掉asm/page.h
//#include <asm/page.h>
3>vim src/libraries/qtopiabase/qmemoryfile_unix.cpp +128
修改
f = ::open(tmpFile.toLatin1(), O_CREAT | O_WRONLY);
为:
f = ::open(tmpFile.toLatin1(), O_CREAT | O_WRONLY ,0777);
第三:make install 总算成功了。
第四:cp source/etc/zoneinfo /Qtopia/ -a
第五:cp qtopia-image/* ../../rootfs/ -a 把生成的目录里的所有内容拷贝到之前做好的yaffs文件系统上
第六:在rootfs/etc下建立qtopia.sh,内容如下:
#!/bin/sh
export QWS_SIZE=320x240
export POINTERCAL_FILE=/etc/pointercal
export LD_LIBRARY_PATH=/lib:$LD_LIBRARY_PATH
export QWS_SW_CURSOR
export set HOME=/root
export set QPEDIR=/
第七:./mkyaffs2image rootfs rootfs.img
第八:烧到s3c2440文件系统分区
第九:进入开发板命令行,输入
#/etc/qtopia.sh
#/bin/qpe启动qtopia界面。
但是,运行qpe后出错。以下是出错情况和解决办法:
1>,cannot read framebuffer, 并且一直打印出错信息,解决办法是:mknod /dev/fb0 c 29 0
2>, cannot open keyboard: no such file or directory. 解决办法是:mknod /dev/tty0 c 4 0
3>, segmentation fault. 在网上查到有人说是交叉编译器版本的问题。然后将arm-linux-4.3.2换成3.4.1,然后编译。编译时出错:V4L2_PIX_FMT_SBGGR8' undeclared
解决办法是:修改3.4.1版的arm编译器的文件
# cd /usr/local/arm/3.4.1/
# vi arm-linux/include/linux/videodev2.h
在其中添加如下内容:
#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */
保存退出。
# vi arm-linux/sys_include/linux/videodev2.h
在其中添加如下内容:
#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */
保存退出。
第十:在将编译器由arm-linux4.3.2替换为3.4.1以后,终于不再出现segmentation fault的错误了,并且运行qpe后,终于在屏幕上出现了qtopia的界面,时区表等等,原来就是编译器版本的问题!然后我又发现一个问题,我把3.4.1里面的库文件考到/usr/lib下,运行qpe就不行,错误是说找不到qpe,其实就是找不到库,环境变量也设了,可是就是找不到。最后只能把库放到/lib下,这时一切就正常了。
3,手动挂载/sys /proc /dev 文件系统:
mount -t proc none /proc
mount -t sysfs sysfs /sys
mount -t tmpfs mdev /dev
mdev -s //这句的意思是扫描/sys,并更新/dev
然后我把这几句加入到了/etc/init.d/rcS里面。
4,挂载NFS网络文件系统:
插上网线以后,发现网口的灯并不亮,然后输入ifconfig,发现没有任何输出,也就是输出为空。然后输入ifconfig eth0,然后会打印出网卡的信息等,信息输出很正常,但就是没有IP地址和MASK地址。我以为是没有配置DHCP什么的呢。然后查了半天。最后发现开发板自带文件系统在rcS文件里手动指定了ip,命令为ifconfig eth0 192.168.1.15 up。原来被写死了。然后我到开发板上输入这个命令,结果发现网口灯果然亮了,一切全都正常了。
然后挂载NFS: mount -t nfs -o nolock 192.168.1.3:/ /mnt
然后提示成功。
5,从NFS网络上挂载qtopia
1>将不带qtopia的linux文件系统做成yaffs image,烧写到开发板中。
2>挂载nfs文件系统,然后用chroot将根目录切换到nfs上的qtopia文件系统中。命令是:chroot /mnt/workspaces/qtopia/rootfs
3>这时候命令行已经变为qtopia新文件系统的命令行了,这时需要执行几个命令。
mount -t proc none /proc
mount -t sysfs sysfs /sys
mount -t tmpfs mdev /dev
echo /bin/mdev > /proc/sys/kernel/hotplug
mdev -s
//这时候,可以看到新进入的文件系统里面拥有了所有资源,包括设备和驱动。
//具体讲解请见linux设备驱动开发详解第二版113页,创建和配置mdev一节。
4>这时就可以启动qtopia了,命令是:/usr/bin/qpe, 然后就看到屏幕上显示qtopia的图像了。