嵌入式 Linux 入门笔记
作者:阿南
嵌入式Linux入门笔记.....................................................................................................................1
前言...........................................................................................................................................3
第一阶段 在PC机上学习熟悉Linux.......................................................................................3
一.Red Hat Linux 9 下的常用操作 ...............................................................................4
二.Minicom的使用 ........................................................................................................6
三.NFS的使用 ...............................................................................................................6
四.应用程序编程实验...................................................................................................7
五.模块编程实验...........................................................................................................7
六.简单的字符设备驱动实验.......................................................................................8
第二阶段 在开发板上学习研究Linux.................................................................................10
一.MIZI Linux SDK for S3C2410 开发环境及工具使用 ..........................................11
1. 构造软件开发环境...........................................................................................11
2. 编译嵌入式Linux生成image...........................................................................12
3. 将嵌入式Linux的image下载到目标板...........................................................14
4. 嵌入式平台测试...............................................................................................21
二.嵌入式Linux驱动开发 ...........................................................................................22
1. 模块编程实验...................................................................................................22
2. 点亮目标板的LED.............................................................................................23
3.按键中断实验...................................................................................................28
4.定时器驱动及PWM输出.....................................................................................33
5.点亮目标板LCD.................................................................................................38
6.安装触摸板.......................................................................................................41
三.构建完整的嵌入式Linux系统 ...............................................................................42
1.桌面系统的启动...............................................................................................42
2.下载可读写的文件系统Yaffs.........................................................................42
3.Yaffs文件系统移植.........................................................................................44
4.Yaffs作为根文件系统启动.............................................................................52
5.完整的嵌入式Linux系统.................................................................................53
四.嵌入式WEB服务器................................................................................................53
1.Boa移植.............................................................................................................53
2.WEB应用开发.....................................................................................................55
五.NFS的配置 .............................................................................................................57
1.主机的NFS服务器配置.....................................................................................57
2.目标机的NFS客户端配置.................................................................................58
3.出现的问题.......................................................................................................58
第三阶段 在项目中应用Linux.............................................................................................58
一. 进程间隔定时器...................................................................................................59
1.概念...................................................................................................................59
2.数据结构...........................................................................................................59
3.操作函数...........................................................................................................60
4.测试程序...........................................................................................................60
二.虚拟地址.................................................................................................................61
三.以太网控制器 —— CS8900A硬件调试 ..............................................................62
1.调试步骤...........................................................................................................62
2.出现过的问题...................................................................................................63
四.WiFi无线网络.........................................................................................................63
1.在RedHat9 上安装TL-WN210 无线网卡驱动...................................................64
2. 无线网络配置...................................................................................................67
3.RedHat9 上使用WL-110 无线网卡...................................................................71
4.无线网卡控制器PD6710 硬件测试..................................................................76
5.Linux下驱动程序及装载.................................................................................81
五.CPLD扩展外部设备...............................................................................................88
1.扩展I/O.............................................................................................................88
2.扩展串口 16C554..............................................................................................94
六.PWM驱动蜂鸣器 .................................................................................................109
1.驱动源码.........................................................................................................109
2.驱动测试程序.................................................................................................112
3.出现过的问题.................................................................................................112
七.485 网络驱动........................................................................................................113
1.硬件测试.........................................................................................................113
2.Linux驱动程序...............................................................................................118
3.驱动测试程序.................................................................................................121
4.出现的问题.....................................................................................................123
八.红外学习与发射...................................................................................................125
1.硬件测试程序.................................................................................................125
2.Linux驱动程序...............................................................................................130
3.驱动测试程序.................................................................................................135
4.出现的问题.....................................................................................................137
5.总结.................................................................................................................137
九.网络编程...............................................................................................................137
1.常用函数.........................................................................................................137
2.服务器程序.....................................................................................................146
3.测试用客户程序.............................................................................................151
4.利用IO复用替代多进程的并发服务器.........................................................152
5.用无线网络测试上述程序.............................................................................155
十.系统时间的实现...................................................................................................155
十一.关于进程的体会...............................................................................................156
1.进程间不共享变量.........................................................................................156
2.进程通信——信号的使用.............................................................................157
3.防止僵死进程.................................................................................................159
第四阶段 用户图形界面设计.............................................................................................159
一.QT应用编程 .........................................................................................................159
二.Qt/Embedded和QTOPIA......................................................................................159
1.Linuette平台.................................................................................................159
2.QTE 2.3.7 / Qtopia 1.7.0.........................................................................162
3. QTE 2.3.12 / Qtopia PDA 2.2.0...............................................................168
4.linuette的root、root_english、usr比较..........................................................172
后记.......................................................................................................................................174
前言
很多朋友(无论是单片机出身的底层软件工程师还是 PC 机的 Windows 程序员)都很想学习 Linux(觉
得只有嵌入式 Linux 才有钱途,而我觉得无论什么,只要比别人做的好,都会有前途),同时却觉得它很难,
把它神密化了(就象当初神密化 ARM 一样),还认为必须要先买个 ARM 开发板才能开始 Linux 的学习,或问
是否应先装个虚拟机等等,然后一直在徘徊着(时间就这样一天天过去了)!我讨厌徘徊,宁可花时间去尝
试失败,然后总结经验。这份笔记基本上按时间顺序记录了我刚接触 Linux 到对它有个整体认识的学习、
调试过程,出现的问题及心得总结等,也是我平时工作中不可缺少的手册。本想按内容重新整理,但后来
还是保持着原来的时间顺序,因为觉得这样更容易让初学者借鉴学习过程和方法。Linux,我还只是一个新
手,所以一定会有很多错误,很多非常不恰当的想法和问题,肯请见谅和批评指正!如果觉得它对您有帮
助,甚至非常的棒,请您写信(ccn422@hotmail.com)告诉我,以给我最大的鼓励!如果您想表示感谢,
那么请您上 21IC BBS 的 ARM 论坛,和我一起帮助那些需要帮助的朋友吧!我知道中国足球很差,但还会一
如既往的关注和支持!自己也会执着的抽出时间,千方百计的寻找踢球机会,培养激情。同样,也知道中
国的电子技术环境不好,但还会执着追求、学习下去,发表心得与大伙共勉。亲爱的工程师们,让我们象
伊拉克足球一样战斗吧!!!
第一阶段 在 PC 机上学习熟悉 Linux
刚学会 ARM 不久,就遇到很多工程师在学习和使用 Linux,当时很是好奇和羡慕!注意到几乎所有工
程师都拥有《GNU/Linux 编程指南》,故也买来收藏着,看了些介绍性的篇幅,也有了在 PC 机上装个 Linux
系统的念头。由于对 RedHat 还不了解,包括基本的操作,于是买了本《Redhat9.0 入门》,在电脑城找了
张 Readhat9.0 光盘(现在肯定找不到了,去网上下吧),还担心在原来硬盘上安装会破坏原来的数据(担
心是多佘的,后来都用 PartitionMagic 在原盘符下直接分区),于是花了 75 元买了 8.4G 的旧硬盘,就这
样回家瞎玩起来。后来又买了本《Redhat9.0 系统管理》,应付 RedHat9.0 的基本操作已经足够。熟悉一两
个星期的 Redhat9.0 基本操作与环境后,是该玩点深入的东东了,觉得自己将来应该是先以嵌入式 Linux
驱动为主,而不是应用编程,所以在还没有进一步学习《GNU/Linux 编程指南》的情况下,就买《Linux 设
备驱动程序》钻研(后来证明这是错误的,有些急功近利)。《Linux 设备驱动程序》看的比较费劲,通读
了一遍后,在 PC 机做的第二个实验就遇到了困难,编译总是出错。去书店参考其它驱动的书,上网查找等
试了很多方法都没有解决,困惑了很久。后来又开始研读《GNU/Linux 编程指南》,读了这本书,再翻《Linux
设备驱动程序》就轻松多了。问题没有解决总会有个结,会时常有针对性的去书店翻些相关的书,上网查
些资料等。在了解到了内核源码树结构,编译等之后,才知道驱动和应用程序是有区别的,是属于内核级,
在编译时要指定 Linux 内核源代码树下的头文件(–I/usr/src/linux-2.4/include),问题就这样解决,
以后的学习、实验都变得顺利了,出现问题基本都能很快排除。总结这阶段的学习顺序,我觉得应该是:
首先,在 PC 机上安装 Linux 系统,再买本相应的入门书籍,主要是熟悉 Linux 环境,学习常用的命令和操
作(不一定多,基本、常用的就可以,以后在使用过程中慢慢积累),理解各目录结构与作用等。其次,学
习在 Linux 环境下编程,《GNU/Linux 编程指南》就可,它会介绍文件描述符的概念,打开、读、写等操作
的系列基础知识,没有这些基础而直接看《Linux 设备驱动程序》会觉得累。后来研读了《UNIX 环境高级
编程》,觉得也很好,它讲了很多前者没有的细节。再次,拿本内核的书翻翻,了解一下 linux 内核源代码
树的目录结构,编译等。最后学习《Linux 设备驱动程序》,理解驱动程序的结构框架等。注:我觉得学习
不需要都直接记住,有点不现实(但应该理解,不要留下疑问,如果有,应及时的用实验去证实再记录),
在以后的应用中再查阅巩固,这阶段也不例外。
一.Red Hat Linux 9 下的常用操作
1. 如何修改在开机引导装载程序中,等待自动登录默认操作系统的时间?
答:如果引导装载程序是 GRUB,则修改/etc/grub.conf 文件中的 timeout=秒数。
如果引导装载程序是 LILO, 则修改的是/etc/lilo.conf 文件。可用 vi 等编辑器修改,下同。
2. 在字符(Text)模式下,如何关机、重启、注销?
答:关机:poweroff 或 shutdown –h now;重启:reboot 或 shutdown –r now;注销(即重新登入):logout;
其中在 shutdown 指令中的 now 是指现在就执行,也可以指定多少时间后再执行此命令。
3. U 盘的使用
答:先创建/mnt/usb 目录,再执行 mount /dev/sda1 /mnt/usb 挂载,此时/mnt/usb 就是 U 盘的目录,在
拔出 U 盘时要执行 umount /mnt/usb 进行卸载。
4. 在字符模式(Text)下,如何进入 X Window 模式(Graphic)?在 X Window 模式下,如何返回字符模式?
答:执行 startx 命令 启动 X Window 模式;鼠标点击“Main Menu(主菜单)->Log out(注销)”打开对话框
中,选择“注销”进入字符模式;或 CRTL+ALT+F1~F6 来进入不同的虚拟控制台(即文本模式下)。
5. 如何重新指定开机默认进入的执行模式(字符或 X Window 模式)?
答:修改/etc/inittab 文件中的内容(id:5:initdefault:)。
其中,5 表示以 X Window 模式(Graphic)登入,3 为字符模式(Text)登入
6. 在字符模式下,如何使用户登入时,系统不要求输入密码?如何恢复或更改用户密码?
答:取消输入密码:passwd –d 用户帐号。如要取消root登入时的密码,则执行passwd –d root。也可
以用vi打开/etc/shadow文件,删除密码的方法取消。恢复或更改密码则执行passwd 用户帐号(如果是取消
自己则不用)命令后会提示输入New password和Retype new password。
7. 字符模式下,如何新增用户帐号?
答:使用“useradd 用户帐号” 命令来增加,但在新增后还不能登入使用,还需要用 passwd 命令来设置
密码后才行。
8. 在 X Window 下,如何选择系统默认使用的语言?
答:鼠标点击“主菜单->系统设置->语言”打开选择语言对话框中选择。
9. 用 ls 等命令查看的内容太多,超过一页时,如何分页显示?
答:可用 ls | more 或 ls | less 进行分页查看。其中,在用 more 浏览时,按空格键(Space)则会显示
下一页的内容;按回车(Enter)键则会向下多显示一行;按 q 键则离开浏览模式。
在用 less 浏览时,按 h 键会出现在线使用说明;按 q 键离开浏览模式。
10.如何获得命令的使用方法?
答:可利用在线手册—man(Manual),用法是输入 man 和待查的命令名称。如要查询 ls 命令的使用方法,
则输入以下命令:man ls 。也可以 ls --help
11.搜索文件及目录和搜索包含特定字符串的文件?
答:搜索文件及目录可以用 find 命令,如要在根目录(/)上搜索 apache 文件则输入命令:find / -name
apache –print,注意:如果没有指定目录,则系统会以当前的目录为搜索的范围;搜索包含特定字符串的
文件可以用 grep 命令,如要在/etc 目录下搜索包含字符串“password”
的文件则输入:grep –n ‘password’ /etc/*.*,其中加入-n 参数会标出符合指定的字符串的列数,另
外不可指定在目录中搜索,否则会出现错误信息,如上述不能写成:grep –n ‘password’ /etc/
另外如果想停止搜索可以直接按“Ctrl + C”键结束该命令就可以。现在我常用:grep –ir password /etc
12.控制台间的切换
答:在文本模式下,用 ALT+F1~F6 来分别在 6 个虚拟控制台间切换,它们可分别用不同的用户名登入和执
行不同的命令与程序,如果已经启动了 X Window(如:在文本模式下用”startx”命令启动),则按 ALT+F7
切换到 X Window 图形模式。
在 X Window 图形模式下,用 CRTL+ALT+F1~F6 分别切换到文本模式下的 6 个虚拟控制台。CRTL + ALT +
BackSpace 结束图形模式。
因为 linux 是多任务的系统,所以可以在不同的控制台下用不同(或同一)的用户登陆来运行不同的程序。
我觉得这个功能很方便,因为有时在文本模式下,需要打开多个终端来处理显示多个的任务,如:一个终
端运行 minicom 作为目标板的控制,一个终端作为宿主机编译目标板要运行的文件,还有多个终端打开多
个源文件在浏览等等。如果习惯在 X Window 模式下就例外,因为用鼠标右键就可以打开多个终端。
13.查看 PDF 文档和浏览网页?
答:在 X Window 下打开 shell 终端,输入”xpdf filename.pdf”和“mizzo filename.html” 命令分
别查看。注:必须在 X Window 下才能运行这两个程序,文本模式不能运行。
14.查看磁盘使用情况
答:#df –h
15./proc 目录下,几个关于系统资源非常有用的文件
/proc/modules、/proc/ioports、/proc/iomen、/proc/devices、/proc/interrupts、/proc/filesystems
16.关于内核代码调试时输出打印信息的 printk 语句
如:printk(KERN_DEBUG “Here I am : %s :%i\n”,__FILE__, __LINE_&_) ;
printk(KERN_INFO “ Driver Initional \n”) ; 等 同 于 printk(“<6>” “ Driver Initional
\n”) ;
printk( “<1> Hello, World!\n”) ;
没有指定优先级的 printk 语句采用默认日志级别(DEFAULT_MESSAGE_LOGLEVEL)在 kernel/printk.c 中被指
定,根据日志级别,内核可能会把消息输出到当前控制台上。当优先级小于 console_loglevel 整数值时,
消息才会被显示出来。如果系统同时运行了 klogd 和 syslogd,则无论 console_loglevel 为何值,都将把
内核消息追加到/val/log/messages 中。console_loglevel 的初始值是 DEFAULT_CONSOLE_LOGLEVEL,可以
通过文本文件/proc/sys/kernel/printk 来读取和修改它及控制台的当前日志级别等。也可以简单的输入
下面命令使所有的内核消息得到显示:
#echo 8 > /porc/sys/kernel/printk
17.查看当前正在运行的进程
答:#ps
18.解压缩到指定目录
答:#tar xvzf linutte.tgz –C /linuette
19.当/etc/grub.conf 文件中的内容被修改或破坏时不能正常启动时,如何在 GRUB 引导时修改设置使其
正常启动
答:以修改了/etc/grub.conf 文件中的 vga 项使启动时显示器不能显示为例,在 GRUB 启动引导菜单中
windows XP 和 Red Hat Linux(2.4.20-8)两项中使用键头键选中 linux 系统,不按[Enter],而按[E]键进
入菜单项目编辑器,再使用键头键选中 kernel 项,也按[E]键进行编辑,在行的后面输入 vga=791 fb=on
后按[Enter],最后按[b]键执行命令,并引导操作系统。
20.包管理器 RPM 使用,以 tmake 为例
安装:#rpm –ivh tmake-1.7-3mz.noarch.rpm
升级:#rpm –Uvh tmake-1.7-3mz.noarch.rpm
查询:#rpm –q tmake
删除:#rpm –e tmake
二.Minicom 的使用
1. 启动 Minicom
输入minicom启动,或输入minicom –s直接进入设置模式。
2. 设置
1> 选择串口:在选择菜单中的“Serial port setup”,按回车,再按“A”以设置“Serial Device”
(如果使用串口1,则输入/dev/ttyS0,如果您使用串口2,则输入/dev/ttyS1,注意其中的S是大写),按
回车返回。
2> 设置波特率:按“E”键进入设置“bps/par/Bits”(波特率)界面,如果按“I”以设置波特率为
115200,按回车返回。
3> 数据流控制:按“F”键设置“Hardware Flow Control”为“NO”。
其它为缺省设置 ,然后按回车到串口设置主菜单,,选择“Save setup as dfl”,按回车键保存刚
才的设置(保存到“/etc/minirc.dfl),再选择“Exit”退出设置模式,回到minicom操作模式。
此时可像Windows下的超级终端一样使用了。
3. 退出 minicom
按下“Ctrl+A”键,松开后紧接着再按下“Q”键,在跳出的窗口中,选择“Yes”。
4. 其它有用的功能
命令帮助 -- “Ctrl+A”后按 “ Z ”
清屏 -- “Ctrl+A”后按 “ C ”
设置 -- “Ctrl+A”后按 “ O ”
发送文件 -- “Ctrl+A”后按 “ S ”
退出 -- “Ctrl+A”后按 “ Q ”
三.NFS 的使用
为什么要使用 NFS:网络文件系统(NFS,Network File System)是一种在网络上的计算机间共享文
件的方法,通过它可以将计算机上的文件系统导出给另一台计算机。我们在宿主机上编辑、编译好的程序,
可以通过它导出到目标板上进行实际的运行。
1. 宿主机配置
从 NFS 服务器中共享文件又称导出目录,/etc/exports 文件控制 NFS 服务器要导出哪些目录。格式如
下:
共享的目录 可以连接的主机 (读写权限,其它参数)
如果允许目标板(IP:192.168.0.*)挂载主机的/home 目录,则/etc/exports 文件的内容如下:
/home 192.168.*.*(rw,sync)
注:如果出现 mount 不成功,可将 sync 去掉试试
更改后要使用如下命令重新载入配置文件:
#/sbin/services nfs reload 或
#/etc/init.d/nfs reload
然后启动 NFS 服务器,命令如下:
/sbin/services nfs start
上面两个命令也可以用下面的一条指令完成,如下:
/sbin/service nfs restart
设置好后也可以通过 mount 自己来测试 NFS 服务设置是否成功。如果本机 IP 为 192.168.0.1,则可以
用 mount 192.168.0.1:/home /mnt,如果 mount 成功,则在/mnt 的目录就可以看到/home 目录下面的东西
了。
2. 使用 mount 命令挂载 NFS 文件系统
下面将宿主机(IP:192.168.0.1)配置的/home 目录挂载到(IP:192.168.0.7)目标板上的/mnt 目
录。
在宿主机启动 minicom 作为目标板的显示终端,启动目标板的 linux 系统,再使用下面命令:
mount –o nolock 192.168.0.1:/home /mnt
注意:如果没有“-o nolock”选项,而直接使用命令:mount 192.168.0.1:/home /mnt 时将出现如
下错误:portmap:server localhost not responding,timed out
目前我都用:mount –t nfs 192.168.0.1:/home /mnt
四.应用程序编程实验
《GNU/Linux 编程指南》一书的例程是非常全面的,下载它的源代码后,可以直接编译运行,基本上
不会有什么问题。
五.模块编程实验
参考《Linux 设备驱动程序》P25 页,hello.c 源程序如下:
#define MODULE
#include
int init_module(void){
printk (“<1>Hello,world\n”);
return 0;
}
void cleanup_module(void){
printk(“<1>Goodbye cruel world\n”);
}
用以下命令进行编译:
#gcc –c hello.c
#insmod ./hello.o
hello,world
#rmmod hello
//注:不是#rmmod hell.o
Goodbye cruel world
出 现 的 问 题 : 在 执 行 #insmod ./hello.o 时 并 没 出 打 印 出 “hello,world ” 而 是 出 现 了 下 述 错
误:./hello:kernel –module version mismatch
hello.o was compiled for kernel version 2.4.20
while this kernel is version 2.4.20-8
原因:模块和内核版本不匹配,即编译内核的编译器与现在编译模块的编译器版本不一致。
解决方法:1> 将/usr/include/linux/version.h 文件中的#define… “2.4.20”修改成#define…
“2.4.20-8”(),再重新编译!
2> 用 insmod 的-f(force,强制)选项强行装入模块,如下:insmod –f ./hello.o
3> 因用 vi /usr/include/linux/version.h 查看到定义的内核版本是 2.4.20,而在内核原代码树下
/usr/src/linux-2.4/include/linux/version.h 中定义为 2.4.20-8 版本,所以用如下命令进行编译:
gcc –c –I/usr/src/linux-2.4/include hello.c,再装载就 OK!
注:可查看/proc/modules 文件。
六.简单的字符设备驱动实验
驱动程序源代码如下:
/*CharDriver.c*/
#define _NO_VERSION
#include
#include
char kernel_version[] = UTS_RELEASE;
#define KERNEL
#include
#include
#include
#include
#include
#define SUCCESS 0
static int device_read(struct file *file, char *buf, size_t count, loff_t *f_pos);
static int device_open(struct inode *inode, struct file *file);
static void device_release(struct inode *inode, struct file *file);
struct file_operations tdd_fops = {
read: device_read,
open: device_open,
release: device_release,
};
#define DEVICE_NAME "char_dev"
static int Device_Open = 0;
unsigned int test_major = 0;
//static char Messaege[1024];
static int device_open(struct inode *inode, struct file *file){
#ifdef DEBUG
printk ("device_open(%p)\n", file);
#endif
if (Device_Open)
return -EBUSY;
Device_Open++;
MOD_INC_USE_COUNT;
return SUCCESS;
}
static void device_release(struct inode *inode, struct file *file){
#ifdef DEBUG