S3C2440ARM芯片+linux2.6.30.4内核平台的学习过程
原文地址链接请点击
最近这段时间一直在持续的学习linux,主要是基于S3C2440ARM芯片,linux的内核是2.6.30.4;目前总体上来说进展比较顺利,经过NandFlash驱动移植、yaffs文件系统移植、BusyBox(我用的1.16.0,1.13.0版本没有编译成功,编译器版本是4.4.3)工具移植、构建文件系统这几个步骤编译出来的内核zImage映像和root根文件系统都能够顺利的运行起来;然后接着进行了串口驱动的完善、DM9000网卡的移植、USB驱动移植、LCD驱动移植,其中遇到的问题是USB无线wifi的驱动移植没有成功,USB摄像头驱动的移植和测试成功,能够在LCD液晶屏上看到摄像头采集的图像。
问题一:USB无线wifi用的是TL-WN823N 2.0,识别出来的USB信息如下:
usb 1-1: new full speed USB device using s3c2410-ohci and address 2
usb 1-1: New USB device found, idVendor=0bda, idProduct=818b
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 1-1: Manufacturer: Realtek
usb 1-1: configuration #1 chosen from 1 choice
通过查询http://www.linux-usb.org/usb.ids发现并没有idVendor=0bda, idProduct=818b的信息,同时在www.realtek.com网站上也没有找到对应的芯片驱动,倒是从网站上下来好几个驱动来但都没有移植成功,打算先暂时放弃进行后续的学习。
前段时间usb wifi驱动的移植一直没有成功,现在移植成功了,关键是找到818b的芯片驱动程序,下载驱动包Realtek-RTL8192EU-driver.tar.gz,驱动下载地址:RTL8192EU-driver.tar.gz,提取码:uz4w。解压后发现有一个driver目录,将driver目录中的文件夹rtl8192EU_linux_v4.2.2_7585.20130524拷贝到内核源码的driver/usb/目录下重命名为rtl8192,配置内核usb目录下面的kconfig和Makefile文件,将8192驱动添加进去,如下:
在kconfig中添加:
source "drivers/usb/rtl8192/Kconfig"
在Makefile中添加:
obj-$(CONFIG_RTL8192EU) += rtl8192/
同时要修改驱动makefile中的几个配置选项,否则编译出来的.ko模块在insmod的时候会提示错误insmod: can't insert '/lib/modules/8192eu.ko': invalid module format,具体修改如下:
修改为CONFIG_PLATFORM_I386_PC = n,修改为CONFIG_PLATFORM_ARM_S3C2K4 = y,根据自己实际的编译环境修改,原来为:
ifeq ($(CONFIG_PLATFORM_ARM_S3C2K4), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE := arm-linux-
KVER := 2.6.24.7_$(ARCH)
KSRC := /usr/src/kernels/linux-$(KVER)
endif
修改后为:
ifeq ($(CONFIG_PLATFORM_ARM_S3C2K4), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE := arm-linux-
KVER := 2.6.30.4
KSRC := /mnt/mywork/linux-$(KVER) #这个地方要跟自己实际的内核源代码路径一致
endif
然后在make menuconfig中选中RTL8192EU为模块,保存,编译后就得到8192eu.ko模块,将几个模块拷贝到文件系统/lib/modules下面,在/etc/init.d/rcS中加载这几个模块,
插入usb wifi模块可以看到如下信息:
表明驱动成功,在命令行输入ifconfig -a可以看到wlan0网口:
在调试wn823无线网卡的时候遇到两个问题:
一、8192芯片默认进入休眠模式,导致wifi连接不上,通过修改驱动的makefile文件设置CONFIG_POWER_SAVING = n,重新编译后加载驱动,插入无线网卡就可以看到网卡电源指示灯一直亮,否则电源指示灯过以后就熄灭。
二、在连接无线路由器的时候,总是连接不上,由于我的无线路由器是采用wpa的加密方式,因此采用wpa_supplicant的方式连接,最开始配置的脚步看起来很全,但是连接不上,后来修改为只有ssid和psk这两项就可以连接上了。
最开始的配置:network={
ssid="znsb01"
scan_ssid=1
key_mgmt=WPA-PSK
proto=WPA
pairwise=TKIP
group=TKIP
psk="123abcdef"
},这个配置看起来比较完善,但连接不上,不知道怎么回事,精简后的配置:network={
ssid="znsb01"
psk="123abcdef"
},这样就可以了。wpa_supplicant.conf配置文件的全部内容如下:
fast_reauth=1
ctrl_interface=wlan0
update_config=1
ap_scan=1
network={
ssid="znsb01"
psk="znsb2015"
}
可以看到有线和无线网络都支持了。
一点心得,linux的资源虽然网上可以收索到很多,作为快速的解决问题和了解还是可以的,但要更深入的需要还是要多度linux内核的Documentation文件夹下面的内容。
今天在做另外一个版本的linux无线网卡移植的时候,发现通过wpa_supplicant配置无线网卡后,通过udhcpc能够获取到自动分配的ip地址,但不能自动对wlan0口进行配置,刚开始以为是wpa_supplicant的脚本配置有问题,折腾了很久还是没有搞定,后面仔细进行分析觉得动态ip地址都获取到了,应该跟wpa的脚本没有什么问题,可能跟udhcpc有关系,于是在网上找到了一篇关于“udhcpc无法自动设置IP的问题”的帖子,根据解释:“udhcpc是一个面向嵌入式系统的非常小的DHCP客户端,字母的缩写微- DHCP -客户端(μDHCPc)。
1.udhcpc -i eth0
udhcpc只是获取一个IP,我们需要把\busybox-1.1.2\examples\udhcp下的脚本simple.script改名为default.script,放在开发板上的/usr/share/dhcpc/目录下,才能将获取的IP写到指定的网卡中。”,在我的板子中做如下两步就可以将udhcpc获得的ip地址自动设置到wlan0接口中:
1. busybox\examples\udhcp\simple.script
拷贝到开发板
/usr/share/udhcpc/default.script
2. 要添加可执行权限
# chmod 755 /usr/share/udhcpc/default.script
我的路由器设置如下:
wpa_supplicant脚本配置如下:
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="PHICOMM_420594"
psk="your password"
key_mgmt=WPA-PSK
proto=RSN WPA
pairwise=CCMP TKIP
group=CCMP TKIP
}
如果有多个wifi网络可以添加多个network选项,如下:
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="PHICOMM_420594"
psk="your password"
key_mgmt=WPA-PSK
proto=RSN WPA
pairwise=CCMP TKIP
group=CCMP TKIP
}
network={
ssid="TP-LINK_48AB"
psk="your password"
key_mgmt=WPA-PSK
proto=RSN WPA
pairwise=CCMP TKIP
group=CCMP TKIP
}
wpa_supplicant脚本配置的详细文档可以参考:wpa_supplicant脚本详解
问题二:在进行linux qt2.2移植的时候,直接用的别人编译好的qt程序,在启动qtopia&后界面能够处理,触摸屏也可以使用,鼠标指针也能够出来,但不能移动鼠标,在网上查询了很多资料也没有解决问题,后来我在控制台中又重新启动了一次qtopia程序,触摸屏和鼠标都可以使用了,还是没有找到根本问题,先放到后面自己再重新编译移植过。还有一种情况就是如果在系统启动的时候插上了USB鼠标,qt也能够识别并能移动,但拔出后在插入又不行了。
在rmmod的时候总是提示:“rmmod: chdir(2.6.30.4-EmbedSky): No such file or directory”,通过在网上查询类似的问题,根据提示在lib/modules/目录下创建了2.6.30.4-EmbedSky目录后就可以rmmod模块了,后续生成的.ko模块准备都放到这个目录下。
后续声卡驱动、RTC驱动、看门狗、SD卡驱动、IIC驱动的移植都比较顺利,做了几个DIY驱动到系统中,分别是:GPIO驱动、中断处理的驱动、PWM控制蜂鸣器的驱动、NFS文件系统。
在boa+cgic web服务器的移植过程中,首先遇到的一个问题就是在编译boa的过程中提示没有yacc和lex工具,在网上收索了一下安装方法感觉都不是很好,后来想到fedora linux里面有添加和删除软件的功能,就试了试,还真安装上了,安装界面和方法如下:先搜索->选择->最后apply
SQLite数据库的移植,在移植中遇到的第一个问题就是在解压缩文件sqlite-src-3090200.zip的时候提示:“gzip: stdin has more than one entry--rest ignored”,通过网络查询的到的解决办法如下:
最后终于发现一例http://lists.gnu.org/archive/html/bug-tar/2008-09/msg00014.html
原来tar也是间接调用了gzip,而gzip的使用是有限制的:Files created by zip can be uncompressed by gzip only if they have a single member compressed with the 'deflation' method.
也就是说单文件用deflation压缩的包才可以用gzip解压,好在有workaround ---- unzip
unzip用法也非常简单,直接敲unzip 就有提示,最后一句命令搞定:
unzip sqlite-src-3090200.zip -d /home/administrator/work/adt2/
-d为指定输出文件夹,不制定貌似就放到pwd,当前文件夹了。
SQLite编译过程如下:
根据README文件中的描述,首先创建一个编译目录sqlite_bld,
1、mkdir sqlite_bld;2、cd sqlite_bld/;3、../sqlite-src-3090200/configure --host=arm-linux --prefix=`pwd`/_install --disable-tcl ;4、mkdir _install; 5、make;6、 make install;7、cd _install/lib/
arm-linux-strip libsqlite3.so.0.8.6
在移植usb驱动的时候遗留一个问题就是在自动挂载usb或者sd卡的时候提示“FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!”,查看了/etc/mdev.conf的配置如下:
sd[a-z]*[0-9] 0:0 0660 @(mount -t vfat -o iocharset=utf8 /dev/$MDEV /udisk)
sd[a-z]*[0-9] 0:0 0660 *(umount /udisk)
mmcblk[0-9]*p[0-9] 0:0 0660 @(mount -t vfat -o iocharset=utf8 /dev/$MDEV /sddisk)
mmcblk[0-9]*p[0-9] 0:0 0660 *(umount /sddisk)
按照网络上的解决方法将 iocharset=utf8设置为 iocharset=cp936后又提示“FAT: IO charset not found”,又继续查找解决方法,最后终于找到了,原来是linux的内核没有配置好,将cp936配置为了模块方式,修改为编译到内核就可以了,如图:
完整配置如下:
File systems --->
Native Language Support --->
(utf8) Default NLS Option ///此括号内为utf8
<*> Simplified Chinese charset (CP936, GB2312)
<*> NLS ISO 8859-1 (Latin 1; Western European Languages)
<*> NLS UTF-8
DOS/FAT/NT Filesystems --->
(936) Default codepage for FAT
(utf8) Default iocharset for FAT
在测试ov9650 cmos摄像头的时候,在编译的时候遇到一个错误如下:
drivers/built-in.o: In function `camif_open':
hid-quirks.c:(.text+0xd9c94): undefined reference to `kmalloc_caches'
错误原因主要是在内核的配置上可能跟cmos的驱动中内存分配有区别,kmalloc_caches主要是在slub.c中定义,猜测可能是slub的配置不对,如下重新配置内核就可以了:
特别注意:开发板自带的ov9650.c驱动不能用,今天将在个驱动添加到内核,在drivers\media\video的makefile中添加obj-$(CONFIG_TQ2440_camera) += tq2440/ 这个可以用,但用的是厂家自带的模块tq2440_camera.module
#obj-$(CONFIG_VIDEO_OV9650) += tq2440/ 这个是编译的ov9650.c,虽然可以看到/dev/camera但不能用而且会烧坏ov9650摄像头
Qtopia-2.2.0的移植首先遇到的就是编译环境的问题,提示缺少一些系统工具,要解决这个问题就是要对编译环境进行完全安装。我用的是fendro10,我就直接使用fedora10的add和remove工具将Programming项的全部包都安装,然后再编译Qtopia-2.2.0就可以了。
Qtopia本身是一个基于QTE库的应用程序,这个程序启动的时候本身是一个选项卡的界面,如下图:
EmbedSky这样的选项卡位于qtopia的安装目录下面/opt/EmbedSky/myqt_test/arm-qtopia-2.2.0/qtopia/image/opt/Qtopia/apps有跟其同名的目录,EmbedSky是用英文还是汉字显示是由其目录下面的一个隐含配置文件决定的,如下所示:
如果Name[]=后面是汉字,则选项卡上的EmbedSky就用相应的汉字显示。 在编译konqueror浏览器的时候遇到浏览器的中文名不能显示的情况,后来在qtopia自带的settings选项卡中选择Appearence程序,然后将字体选择为unicode就可以正常显示汉字了。我移植的qtopia中的Appearence程序只有在刚烧写根文件系统的时候可以运行和设置,后面再运行的时候就会出错,不能再运行了,出现:
Warning: ASSERT: "parent() && parent()->isWidgetType()" in kernel/qabstractlayout.cpp (884)
Warning: ASSERT: "parent() && parent()->isWidgetType()" in kernel/qabstractlayout.cpp (884)
Warning: ASSERT: "parent() && parent()->isWidgetType()" in kernel/qabstractlayout.cpp (884)
Warning: Cannot load small icon: icons/16x16/dialup
Warning: QPixmap::convertToImage: Cannot convert a null pixmap
Warning: Cannot load small icon: dialup/icons/16x16/dialup
Warning: QPixmap::convertToImage: Cannot convert a null pixmap
Warning: ASSERT: "parent() && parent()->isWidgetType()" in kernel/qabstractlayout.cpp (884)
Warning: ASSERT: "parent() && parent()->isWidgetType()" in kernel/qabstractlayout.cpp (884)
Warning: ASSERT: "parent() && parent()->isWidgetType()" in kernel/qabstractlayout.cpp (884)
这样的错误提示,估计还是在qtopia移植过程中的问题。
在qt4.5的移植和测试过程中遇到的一个问题就是在x86电脑上仿真qt4.5的测试程序,首先要启动qvfb,如下命令:qvfb -width 1028 -height 760 -depth 16,然后再用-qws参数启动测试程序。