s3c2440上linux-2.6.28.7内核配置及Qtopia文件系统移植和搭建

一、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 ***          │ │ 
  │ │       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                                          │ │ 
  │ │    SCSI target support                                          │ │ 
  │ │    [*] legacy /proc/scsi/ support                                   │ │ 
  │ │        *** SCSI support type (disk, tape, CD-ROM) ***               │ │ 
  │ │    <*> SCSI disk support                                            │ │ 
  │ │    SCSI tape support                                            │ │ 
  │ │    < > SCSI OnStream SC-x0 tape support                             │ │ 
  │ │    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

 

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的图像了。

 

 

你可能感兴趣的:(嵌入式)