嵌入式Linux入门学习调试笔记

Size: px
Start display at page:

Download "嵌入式Linux入门学习调试笔记"

Transcription

1 嵌入式 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 开发环境及工具使用 构造软件开发环境 编译嵌入式 Linux 生成 image 将嵌入式 Linux 的 image 下载到目标板 嵌入式平台测试...21 二. 嵌入式 Linux 驱动开发 模块编程实验 点亮目标板的 LED 按键中断实验 定时器驱动及 PWM 输出 点亮目标板 LCD 安装触摸板...41 三. 构建完整的嵌入式 Linux 系统 桌面系统的启动 下载可读写的文件系统 Yaffs Yaffs 文件系统移植 Yaffs 作为根文件系统启动 完整的嵌入式 Linux 系统...53 四. 嵌入式 WEB 服务器 Boa 移植 WEB 应用开发...55 五.NFS 的配置 主机的 NFS 服务器配置 目标机的 NFS 客户端配置 出现的问题...58 第三阶段在项目中应用 Linux...58 一. 进程间隔定时器 概念 数据结构...59

2 3. 操作函数 测试程序...60 二. 虚拟地址...61 三. 以太网控制器 CS8900A 硬件调试 调试步骤 出现过的问题...63 四.WiFi 无线网络 在 RedHat9 上安装 TL-WN210 无线网卡驱动 无线网络配置 RedHat9 上使用 WL-110 无线网卡 无线网卡控制器 PD6710 硬件测试 Linux 下驱动程序及装载...81 五.CPLD 扩展外部设备 扩展 I/O 扩展串口 16C 六.PWM 驱动蜂鸣器 驱动源码 驱动测试程序 出现过的问题 七.485 网络驱动 硬件测试 Linux 驱动程序 驱动测试程序 出现的问题 八. 红外学习与发射 硬件测试程序 Linux 驱动程序 驱动测试程序 出现的问题 总结 九. 网络编程 常用函数 服务器程序 测试用客户程序 利用 IO 复用替代多进程的并发服务器 用无线网络测试上述程序 十. 系统时间的实现 十一. 关于进程的体会 进程间不共享变量 进程通信 信号的使用 防止僵死进程 第四阶段用户图形界面设计 一.QT 应用编程 二.Qt/Embedded 和 QTOPIA...159

3 1.Linuette 平台 QTE / Qtopia QTE / Qtopia PDA linuette 的 root root_english usr 比较 后记 前言 很多朋友 ( 无论是单片机出身的底层软件工程师还是 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 环境, 学习常用的命令和操

4 作 ( 不一定多, 基本 常用的就可以, 以后在使用过程中慢慢积累 ), 理解各目录结构与作用等 其次, 学习在 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

5 的文件则输入 :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( ) 两项中使用键头键选中 linux 系统, 不按 [Enter], 而按 [E] 键进入菜单项目编辑器, 再使用键头键选中 kernel 项, 也按 [E] 键进行编辑, 在行的后面输入 vga=791 fb=on 后按 [Enter], 最后按 [b] 键执行命令, 并引导操作系统 20. 包管理器 RPM 使用, 以 tmake 为例安装 :#rpm ivh tmake-1.7-3mz.noarch.rpm

6 升级 :#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 以设置波特率为 , 按回车返回 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: *) 挂载主机的 /home 目录, 则 /etc/exports 文件的内容如下 : /home *.*(rw,sync) 注 : 如果出现 mount 不成功, 可将 sync 去掉试试更改后要使用如下命令重新载入配置文件 : #/sbin/services nfs reload 或 #/etc/init.d/nfs reload 然后启动 NFS 服务器, 命令如下 : /sbin/services nfs start 上面两个命令也可以用下面的一条指令完成, 如下 : /sbin/service nfs restart

7 设置好后也可以通过 mount 自己来测试 NFS 服务设置是否成功 如果本机 IP 为 , 则可以用 mount :/home /mnt, 如果 mount 成功, 则在 /mnt 的目录就可以看到 /home 目录下面的东西了 2. 使用 mount 命令挂载 NFS 文件系统下面将宿主机 (IP: ) 配置的 /home 目录挂载到 (IP: ) 目标板上的 /mnt 目录 在宿主机启动 minicom 作为目标板的显示终端, 启动目标板的 linux 系统, 再使用下面命令 : mount o nolock :/home /mnt 注意 : 如果没有 -o nolock 选项, 而直接使用命令 :mount :/home /mnt 时将出现如下错误 :portmap:server localhost not responding,timed out 目前我都用 :mount t nfs :/home /mnt 四. 应用程序编程实验 GNU/Linux 编程指南 一书的例程是非常全面的, 下载它的源代码后, 可以直接编译运行, 基本上不会有什么问题 五. 模块编程实验 参考 Linux 设备驱动程序 P25 页,hello.c 源程序如下 : #define MODULE #include <linux/module.h> 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 while this kernel is version 原因 : 模块和内核版本不匹配, 即编译内核的编译器与现在编译模块的编译器版本不一致 解决方法 :1> 将 /usr/include/linux/version.h 文件中的 #define 修改成 #define (), 再重新编译! 2> 用 insmod 的 -f(force, 强制 ) 选项强行装入模块, 如下 :insmod f./hello.o 3> 因用 vi /usr/include/linux/version.h 查看到定义的内核版本是 , 而在内核原代码树下 /usr/src/linux-2.4/include/linux/version.h 中定义为 版本, 所以用如下命令进行编译 :

8 gcc c I/usr/src/linux-2.4/include hello.c, 再装载就 OK! 注 : 可查看 /proc/modules 文件 六. 简单的字符设备驱动实验 驱动程序源代码如下 : /*CharDriver.c*/ #define _NO_VERSION #include <linux/module.h> #include <linux/version.h> char kernel_version[] = UTS_RELEASE; #define KERNEL #include <linux/types.h> #include <linux/fs.h> #include <linux/mm.h> #include <linux/errno.h> #include <asm/segment.h> #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

9 printk ("device_release(%p,%p)\n", inode, file); #endif Device_Open--; MOD_DEC_USE_COUNT; static int device_read(struct file *file, char *buf, size_t count, loff_t *f_pos){ int left; if (verify_area(verify_write, buf, count) == -EFAULT) return -EFAULT; for (left = count; left > 0; left--){ put_user(1, buf); buf++; return count; int init_module(void){ int result; result = register_chrdev(0, "char_dev", &tdd_fops); if (result < 0){ printk("char_dev:can't get major number\n"); return result; if (test_major == 0) test_major = result; printk ("Hello,I'm in kenel mode\n"); return 0; void cleanup_module(void){ printk("hello,i'm goint to out\n"); unregister_chrdev(test_major,"char_dev"); 用下述命令进行编译 : #gcc O2 -DMODULE D KERNEL -c CharDriver.c 出现下述错误 : CharDriver.c 18:Tvariable fops has initializer but incomplete type CharDriver.c 19:unknown field read specified in initializer CharDriver.c 20:unknown field open specified in initializer CharDriver.c 20:unknown field release specified in initializer CharDriver.c 53:storage size of fops isn t known 原因 : 在用 gcc 进行编译时, 默认搜索的 include 文件路径为 /usr/include, 但 /usr/include/linux/fs.h 中没有定义 file_operations 结构体 ( 可以打开该文件看一下 ),file_operations 是在原代码树目录

10 /usr/src/linux-2.4/include 下的 linux/fs.h 中定义, 而且用了 #ifdef KERNEL 条件编译 因此在编译时必须指定该目录和定义 KERNEL 编译命令如下: #gcc O2 -DMODULE D KERNEL I/usr/src/linux-2.4/include -c CharDriver.c 经过编译得到的文件 CharDriver.o 就是设备驱动程序, 执行以下命令把它安装到系统中 : #insmod CharDriver.o 如果安装成功, 用 #vi /proc/devices 打开文件将看到设备 char_dev 和主设备号 如果需要卸载, 可运行 #rmmod char_dev 然后就需要创建设备文件了, 执行以下命令 :mknod /dev/char_dev c 254 0, 其中 /dev/char_dev 是要生成的设备名及目录, 选项 c 是指字符设备,254 是生成的主设备号, 可用上面方法查看到, 也可能是 253 或其它, 从设备号设成 0 就可以 另外可以用 rm f /dev/char_dev 将删除 mknod 命令创建的设备文件 可用下述测试程序源代码进行测试 驱动的测试程序如下 : /*DriverTest.c*/ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(int argc, char *argv[]){ int testdev; int i; char buf[10]; testdev = open("/dev/char_dev", O_RDWR); if (testdev == -1){ printf("cann't open file \n"); exit(0); read(testdev, buf, 10); for (i = 0; i < 10; i++){ printf("%d\n", buf[i]); close(testdev); 需要注意的是将驱动程序数据传给用户程序时是 put_user(1,buf), 而不是 put_user(1,buf,1); 否则会出现错误 还有 copy_to_user(buf,buffer++,1) 函数的 Buffer 是指针变量, 而不是具体的数据, 如果写成 copy_to_user(buf,1,1), 也会出错 第二阶段在开发板上学习研究 Linux 公司虽然用 ARM 已经多年, 但都是裸奔, 产品在功能和性能上的提升都出现了瓶颈, 急需软件平台的突破, 这也增大了我的学习动力 过年假期没有回家 ( 尽管妈妈生病刚动完手术, 但还是含着泪在电话里告诉爸爸我的决定 ), 而是抓紧时间专心研究基于 s3c2410 的嵌入式 Linux 平台 硬件是一块普普通通的 s3c2410 开发板, 软件选择 MIZI Linux SDK (Software Development Kit) for S3C2410, 因为我觉得它是 s3c2410 最原始的平台, 国内大部分的开发板都是在它的基础上发展过来, 选择它比较可靠, 心里也比较

11 踏实, 以后应用于产品也是如此 从 mizi ftp 站点下载的 SDK 光盘, 包含了开发板原理图 BOM 表 linux 开发平台所需的所有软件 工具及使用手册等, 资料是比较齐全的, 完全可以参考它设计出自己的开发板 下面的软件安装 工具使用等内容摘自和总结于它的操作手册,LED 按键驱动实验的源代码摘自广州友善之臂科技有限公司的 SBC-2410X-UM.pdf 一.MIZI Linux SDK for S3C2410 开发环境及工具使用 1. 构造软件开发环境 1.1 安装基本的软件开发工具 安装 RedHat 9 的工作站 (workstation) 模式, 当完成后基本的开发工具也就安装完成, 主要有 : binutils gcc gcc-c++ glibc-kernheaders glibc-common glibc glibc-devel patch make minicom 等 可以用 rpm 包管理程序来查看它们的版本信息, 如查看 binutils 的命令如下 : #rpm q binutils 1.2 安装 MIZI Linux SDK (Software Development Kit) for S3C2410 先从 mizi ftp 站点下载光盘的镜像文件, 再刻录成光盘 ( 如果直接解压会有一些小问题出现 ) 将光盘放入光驱, 然后执行下述命令 : #mkdir /linuette #mount /dev/cdrom /mnt/cdrom #cd /mnt/cdrom #tar cvf /linuetter/linuetter.tar * #cd /linuette #tar xvf linuetter.tar #rm rf linuetter.tar 其实上述的操作就是将光盘里的所有内容复制到 /linuette 目录下, 但为何不直接用 cp 命令去实现呢? 是因为 cp 命令会改变文件一些属性的原因吗? 及 cp 时会出现一些不能创建 ln 等错误 另外,MIZI 文档中的 #tar cf -. (cd /linuette ; tar xvf -) 命令为何会出错? 1.3 安装交叉编译环境 进入 RPMS 目录下执行包管理程序安装所有的 *.rpm 程序 注 : 不能直接用一条 #rpm Uvh *.rpm 命令进行安装就完成, 这样没有用! 必须一步步的安装, 如下 : Tool chain #rpm Uvh cross armv4l binutils mz.i386.rpm #rpm Uvh cross armv4l kernel headers 2.4.5_rmk7_np2 1mz.i386.rpm #rpm Uvh cross armv4l gcc mz.i386.rpm #rpm Uvh cross armv4l glibc mz.i386.rpm #rpm Uvh cross armv4l gcc c mz.i386.rpm MIZI-tool-box #rpm Uvh cross armv4l libfloat 1.0 3mz.i386.rpm

12 #rpm Uvh cross armv4l zlib mz.i386.rpm #rpm Uvh cross armv4l jpeg 6b 2mz.i386.rpm #rpm Uvh cross armv4l jpeg devel 6b 2mz.i386.rpm #rpm Uvh tmake-1.7-3mz.noarch.rpm GUI Toolkit #rpm Uvh linuette_sdk_x mz.noarch.rpm #rpm Uvh qte custom 1.5 1mz.i386.rpm #rpm Uvh linuette_sdk_arm 1.5 1mz.noarch.rpm #rpm Uvh cross armv4l qte custom 1.5 4mz.i386.rpm 可以将上述写成一个脚本或直接将安装完成的目录打包, 下次安装就比较方便了 1.4 MIZI Linux SDK 的目录结构 2. 编译嵌入式 Linux 生成 image 如下 : 嵌入式 Linux 软件系统由 bootloader kernel root filesysytem 和可选的 user filesystem 构成, bootloader( 一次固化 )+ 内核 ( 多次更新 )+ 根文件系统 ( 多次更新 ) [ + user filesystem] 2.1 配置编译 bootloader vivi #cd /linuette/target/box/boot #tar jxvf vivi.tar.bz2( 如果压缩文件的后缀是.gz 则用该命令 :#tar zxvf vivi.tar.gz) #cd vivi #make menuconfig

13 选择 Load an Alternate Configuration File 菜单, 然后写入 arch/def-configs/smdk2410 再选择 OK, 最后选择 Yes 退出 #make 如果不出错, 则在目录 :/linuette/target/box/boot/vivi/ 下将生成 vivi 的二进制文件 #mkdir /image #cp vivi /image

14 2. 2 配置编译内核 #cd /linuette/target/box #tar jxvf linux rmk7-pxa1-mz4.tar.bz2 #cd kernel #make menuconfig 与编译 vivi 类似, 在 Load an Alternate Configuration File 菜单后写入 arch/arm/def-configs/smdk2410 退出后执行 : 编译内核 #make zimage 编译模块 #make modules #make modules_install #cp zimage /image 将模块打包, 准备更新文件系统模块 #cd /tmp/lib/modules/ rmk7-pxal #tar zcvf mod.tgz kernel pcmcia 2.3 生成根文件系统 生成不包括 GUI 的根文件系统 #cd /linuette/target/box/root_dir #tar jxvf root.tar.bz2 #./mkcramfs./root./root.cramfs #cp root.cramfs /image 生成包括 GUI 的根文件系统 #cd /linuette/target/box/root_dir #tar jxvf root_english.tar.bz2 ( 或者 root_ hangul.tar.bz2 和 root_china.tar.bz2) #cd root_english/usr/lib/modules/ rmk7-pxa1 #rm -rf kernel/ pcmcia/ #tar zxvf /tmp/lib/modules/ rmk7-pxa1/mod.tgz C. #./mkcramfs./root_english./root_english.cramfs #cp root_english.cramfs /image 3. 将嵌入式 Linux 的 image 下载到目标板 3. 1 第一次 ( 或系统不能启动时 ) 下载 image 使用 JTAG 接口下载 vivi 用 JTAG 小板通过 PC 机的并口与目标板的 JTAG 接口将它们相连 #cd /linuette/target/box/jflash #cp./jflash-s3c2410 /image

15 #cd /image #./Jflash-s3c help 根据目标板的 Nand Flash 选择相应项, 如 :K9S1208 #./Jflash-s3c2410 vivi /t=5 Select the function to test : 0 Input target block number: 0 Select the function to test : 通过 vivi 下载各 images 进入 vivi 的下载模式由于 vivi 正常工作在启动加载模式, 启动等待时间可能很短, 所以要想进入下载模式, 必须先按着空格键, 再复位目标板 #cd /image #minicom Supply power to target board, then press space-bar quickly. vivi> 已进入下载模式, 输入 help 将列出所有可用的命令 Flash 分区 (Partitioning) 注 : 如果没有这一步, 而直接下载内核和根文件系统时, 系统可能无法正确引导, 会出现下述错误 : Kenel panic:vfs:unable to mount root fs on 61:02 所以必须进行分区, 再下载 bootload kernel root filesystem vivi>bon part 0 192k 1M 分区后存储器分配如下 : 0 ~ 192K : vivi (bootload) 192K ~ 1M : zimage (kernel) 1M ~ End-part: root.cramfs (root filesystem) 下载 vivi image vivi>load flash vivi x 快速按下 Ctrl + A 和 S, 再选择 xmodem 发送模式切换到 /image 目录, 光标移到 vivi 后按空格选中, 再按回车开始发送 如果发送失败, 原因是执行装载命令到 xmodem_initial 的时间太短, 而产生超时 可以将 xmodem_initial_timeout 参数加大 #param show #param set xmodem_initial_timeout : means 5 second because a unit is µs. #param save 修改完后, 再次执行上述操作 下载 kernel image 与下载 vivi 同样的操作方法来下载 kernel image zimage vivi>load flash kernel x 下载 root-filesystem image 与下载 vivi 同样的操作方法来下载 root-filesystem root.cramfs vivi>load flash root x 当都下载完毕后 vivi>boot

16 如果正确将引导进入 linux 的 shell 模式 3. 2 系统能正常引导时下载 image 当能够正常引导进入操作系统时, 可以先通过以太网将 image 文件和 imagewrite 烧写工具复制到目标板, 再在目标板上执行烧写, 这样速度会更快 ( 以太网的速度要比串口快很多, 不要像我一样傻, 用 xmodem 下载带 GUI 的文件系统, 当你等了半个多小时后出错, 定会气的吐血 ) 将所需要下载到目标板的文件都放入 /image 目录下, 以方便传送 #cd /linuette/target/box/image/ #cp./imagewrite /image ztelnet ztelnet 与 redhat9 提供的 telnet 不同的是在登录后支持文件的发送命令, 即 : ztelnet>sz filename [filename] 注 : 在 RPMS 目录下有它的安装包, 要先安装 用 imagewrite 写 flash 的过程是在目标系统上进行的, 所以要在宿主机上通过 ztelnet 登录到目标机, 再把宿主机上 /image 目录的内容发送到目标机, 再执行 imagewrite 进行烧写 使用交叉网线连接宿主机与目标机, 再在宿主机的 Linux 系统中启动两个终端窗口, 一个运行 minicom 作为目标机的控制台, 另一个在 /image 目录下 Terminal 1:terminal which location is image directory Terminal 2:terminal which executes minicom (console of target board) 启动目标机, 使其也进入 shell 模式下, 为双机通信作好准备 Terminal 1:#cd /image Terminal 2:#minicom

17 设置双方的 IP 地址 Terminal 1:#ifconfig eth0 down #ifconfig eth :Set up arbitrary IP. Terminal 2:#ifconfig eth :Set up IP that can make a pair with that of host PC. #inetd inetd 命令用于启动 telnet 服务器检测双方能否常通信 Terminal 1: #ping : We can confirm that it s communicating between host PC and target board by ping command. 宿主机用 ztelnet 登录目标机 Terminal 1: #ztelnet Login by root account. Because you don t need to input password, press Enter key.

18 发送 images 只有 /tmp 目录可以被双方读写, 其它的都是只读文件系统, 所以必须下载到该目录下 Terminal 1: #cd /tmp #rz Pushing Ctrl + ], ztelnet> console appears. telnet>sz vivi zimage root.cramfs imagewrite 可以用 ls 命令来检查下载的内容

19 由于是 cramfs 文件系统, 因此当电源掉电后, 所有下载的文件都会消失 如果想保存必须将其写入到 flash 中 用 imagewrite 将 images 写入到 flash Flash 分区与上一节一样, 将给 flash 分三个区, 分别存放 bootload kernel 和 root filesystem #./imagewrite /dev/mtd/0 -part 0 192K 1M 将 images 写入 flash 格式 :#./imagewrite <mtd_dev> <file:offset> 将 vivi 写入到 0~192KB 区,zImage 写入到 192KB~1MB,root.cramfs 写入到 1MB~End-part #./imagewrite /dev/mtd/0 vivi:0 #./imagewrite /dev/mtd/0 zimage:192k #./imagewrite /dev/mtd/0 root.cramfs:1m 3. 3 出现过的问题 下载完 vivi kernel root 后执行 boot 时, 出现下述现象后就停止了, 而不能正常引导进入 l inux 系统 NOW, Booting Linux.....

20 Uncompressing Linux... done, booting the kernel. 问题 : 可能是硬件接触不良, 或内核下载有些问题, 如没有按规定分区, 重新分区下载试试 登录到 telnet 后不能发送文件, 即不支持 sz 命令 RedHat 9 自带的 telnet 不支持该功能, 需安装光盘里的 ztelnet, 使用 ztelnet 登录 3.4 windows 下发送文件到 linux 目录 可以由 windows 自带的超级终端, 或 SecureCRT 完成 在 Windows 操作系统下选择 开始 -> 程序 -> 附件 -> 通讯 -> 超级终端, 打开超级终端, 选择 文件 -> 属性 命令, 在 连接时使用 项中选择 TCP/IP(winsock), 在 主机地址 项中输入目标板的 IP 地址 ( 如下图所示 ), 将目标板作为服务器,PC 作为客户端 设置完成后, 点击 呼叫, 在超级终端上将出现目标板的 linux 系统的 telnet 登录界面, 可用 root 登录, 如下 : Linux rmk7-pxa1 ((none)) (0) (none) login: root BusyBox v ( : ) Built-in shell (ash) Enter 'help' for a list of built-in commands. # 切换到 /tmp 目录下后选择 传送 -> 发送文件, 点击 浏览 选中要发送的文件后点 发送 按钮, 如下 :

21 发送完毕后, 可用 ls 命令查看如下 : 4. 嵌入式平台测试 我们为目标板编译 运行最简单的 hello 程序, 以测试 熟悉上述的开发环境及应用开发 4. 1 hello 源程序 程序清单 : /*hello.c 在终端上打印 hello,linux*/ #include <stdio.c> int main(void){

22 printf( hello,linux\n ); return 0; 4. 2 Makefile 可以直接输入编译命令, 也可以写 Makefile 脚本进行编译 脚本清单 : CROSS=/opt/host/armv4l/bin/armv4l-unknown-linuxall: hello hello: $(CROSS)gcc -o hello hello.c clean: rm rf hello *.o 第一行是指定交叉编译器的安装路径 #make 生成 hello 可执行文件 4.3 程序运行 当生成执行文件后, 可用上节提到的 ztelnet 方法将其下载到目标板的 /tmp 目录下, 再执行 : #./hello 二. 嵌入式 Linux 驱动开发 1. 模块编程实验 1.1 源程序 模块程序清单 : #define MODULE #include <linux/module.h> int init_module(void){ printk ( <1>Hello,world!\n ); return 0; void cleanup_module(void){ printk( <1>Goodbye cruel world!\n );

23 1.2 PC 机上编译运行 #gcc c hello.c #insmod./hello.o hello,worlk! #rmmod hello Goodbye cruel world! # 1. 3 为目标板上编译和运行 Makefile 脚本清单 : CROSS=/opt/host/armv4l/bin/armv4l-unknown-linux- INCPATH=/linuette/target/box/kernel/include all: hello hello: $(CROSS)c I$(INCPATH) hello.c clean: rm rf *.o 写好脚本后, 输入 make 编译 #make /opt/host/armv4l/bin/armv4l-unknown-linux-gcc I/linuette/target/box/kernel/include 将生成的目标文件下载到目标板的 /tmp 目录下, 再动态装载和卸载时将在终端打印相应的字符串, 如下 : #insmod./hello.o Hello,world! #rmmod hello Goodbye cruel world! 当装载后, 可以查看 /proc/modules 的内容, 是否装载成功 #cat /proc/modules 2. 点亮目标板的 LED 2. 1 LED 驱动 LED 驱动源程序清单 #ifndef KERNEL #define KERNEL #endif #ifndef MODULE #define MODULE #endif #include <linux/module.h>

24 #include <linux/kernel.h> #include <linux/version.h> #include <linux/fs.h> #include <linux/init.h> #include <asm-arm/arch-s3c2410/hardware.h> #define DEVICE_NAME "leds" #define LED_MAJOR 232 static unsigned long led_table[]={gpio_b7,gpio_b8,gpio_b9,gpio_b10; static int leds_ioctl(struct inode *inode,struct file *file,unsigned int cmd, unsigned long arg){ switch(cmd){ case 0: case 1: if (arg > 4){ return -EINVAL; write_gpio_bit(led_table[arg],!cmd); default: return -EINVAL; static struct file_operations leds_fops={ owner:this_module, ioctl:leds_ioctl, ; static int init leds_init(void){ int ret; int i; ret = register_chrdev(led_major,device_name,&leds_fops); if (ret < 0){ printk(device_name "can't register major number"); return ret; for (i=0;i<4;i++){ set_gpio_ctrl(led_table[i] GPIO_PULLUP_EN GPIO_MODE_OUT); write_gpio_bit(led_table[i],1); printk(device_name "initialized\n"); return 0; static void exit leds_exit(void){ unregister_chrdev(led_major,device_name);

25 module_init(leds_init); module_exit(leds_exit); Makefile CROSS=/opt/host/armv4l/bin/armv4l-unknown-linux- INC=/linuette/target/box/kernel/include/ all: leds leds: $(CROSS)gcc -O2 -c -I$(INC) leds.c clean: rm rf leds *.o 驱动的动态装载装载模块 #insmod leds.o 如果装载成功, 在 /proc/devices 文件中可以看到 leds 和它的主设备号 (232) #cat /proc/devices 创建设备文件 #mknod /dev/leds c 成功后在 /dev 目录下将生成 leds 设备文件 #ls /dev 2. 2 LED 驱动的测试 测试程序 1 单个 LED 的控制 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> int main(int argc, char **argv){ int on; int led_no; int fd; if (argc!= 3 sscanf(argv[1],"%d",&led_no)!= 1 sscanf(argv[2],"%d",&on)!= 1 on < 0 on > 1 led_no < 0 led_no > 3){ fprintf(stderr,"usage: leds led_no 1 0\n"); exit(1); fd = open("/dev/leds",0); if (fd < 0){ perror(" open device leds"); exit(1); ioctl(fd,on,led_no); close(fd); return 0;

26 2.2.2 Makefile CROSS=/opt/host/armv4l/bin/armv4l-unknown-linuxall: leds leds: $(CROSS)gcc o led_test leds.c clean: rm rf led_test *.o 测试分别控制四个 LED 亮 灭 #./leds_test 0 1 #./leds_test 1 1 #./leds_test 2 1 #./leds_test 3 1 #./leds_test 0 0 #./leds_test 1 0 #./leds_test 2 0 #./leds_ test 将驱动编译进内核 当在实际的项目的量产中, 不可能一台台的将一堆驱动一个个的安装, 一定要将它们编译进内核, 而且当为 CRAMFS 文件系统时, 一掉电, 刚安装的模块及驱动就丢了, 所以也要求必须编译进内核 在内核配置选项中增加该驱动的选项 #cd /linuette/target/box/kernel #vi./drivers/char/config.in 增加内容 : if [ $CONFIG_ARCH_S3C2410 = y ]; then tristate S3C2410 LED Driver example CONFIG_S3C2410_LED 或直接只用该行 fi #make menuconfig 选中 Character devices->s3c2410 LED Driver example 项 在内核的 Makefile 中增加该驱动的编译内容 #vi./driver/char/makefile 增加内容 : obj-$(config_s3c2410_led) += leds.o 将 led.c 复制到 kernel/driver/char 目录下, 然后重新编译更新内核 出现的问题问题 1:make zimage 后出现 this_modules 无定义的错误原因 : 在驱动程序中有下述的定义项 #ifndef MODULE #define MODULE #endif

27 问题 2: 不能编译进内核, 即 /proc/devices 文件和 /dev 目录下都没有出 leds 原因 : 在驱动程序中有下述的定义项 #ifndef MODULE #define MODULE #endif 问题 3: 在 /dev 目录下找不到 leds 设备文件解决方法 : 可以使用设备文件系统 devfs 将原驱动程序中的初始化和退出程序修改成如下: static devfs_ handle_t devfs_handle; static int init leds_init(void){ int ret; int i; ret = register_chrdev(led_major,device_name,&leds_fops); if (ret < 0){ printk(device_name "can't register major number"); return ret; devfs_handle = devfs_register(null,device_name,devfs_fl_default,led_major,0,s_ifchr S_IRUSR S_IWUSR,&leds_fops,NULL); for (i=0;i<4;i++){ set_gpio_ctrl(led_table[i] GPIO_PULLUP_EN GPIO_MODE_OUT); write_gpio_bit(led_table[i],1); printk(device_name "initialized\n"); return 0; static void exit leds_exit(void){ devfs_unregister(devfs_handle); unregister_chrdev(led_major,device_name); 2.4 系统启动后, 自动使 LED 闪烁 最终的程序肯定是不会象上述一样需要输入命令才执行, 而是当系统启动后就自动的一直在运行 LED 测试程序 2 - LED 循环计数 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> int main(void){ unsigned int on; int led_no; int fd; unsigned char i; fd = open("/dev/leds",0);

28 if (fd < 0){ perror("open device leds"); exit(1); on = 0; while (1) { for (i = 0; i < 4; i++){ ioctl(fd, (on>>i)&1,i); on += 1; on &= 0xf; sleep(1); close(fd); return 0; Makefile CROSS=/opt/ host/armv4l/bin/armv4l-unknown-linuxall: leds leds: $(CROSS)gcc o led_inc leds.c clean: rm rf led_inc *.o 编译生成 leds_inc 可执行文件, 通过 ztelnet 下载到目标板的 /tmp 目录再运行就可以看到 4 个 LED 在不断的计数显示 启动系统时自动运行该程序可以先把可执行文件 leds_inc 复制到根文件系统 root 目录下的 sbin 目录, 再在系统的启动脚本中执行该程序, 该脚本为根文件系统 root 目录下的 linuxrc 文件 假设现在 leds_inc 所在的目录下 #cp leds_inc /linuette/target/box/root/sbin #cd /linuette/target/box/root #vi linuxrc 在 exec /bin/ sh 的前面增加下面行 /sbin/leds_inc 也可以当执行该程序时, 往终端打印提示信息, 则再加上 echo /sbin/leds_inc 将修改过的根文件系统重新生成 image 文件 #cd.. #./mkcramfs./root./root.cramfs 更新目标板的根文件系统, 再启动 3. 按键中断实验 Linux 内核维护了一个中断信号线的注册表, 模块在使用中断前要先申请一个中断通道 ( 或者中断请求 IRQ), 然后在使用后释放该通道 下列在头文件 <linux/sched.h> 中声明的函数实现了该接口 :

29 int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flag, const char * dev_name, void *dev_id); void free_irq(unsigned int irq, void *dev_id); 3.1 按键驱动源程序 #include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/poll.h> #include <linux/spinlock.h> #include <linux/irq.h> #include <linux/delay.h> #include <asm/hardware.h> #define DEVICE_NAME "custom-buttons" // 定义按键设备名 #define BUTTON_MAJOR 232 // 定义按键主设备号 static struct key_info { int irq_no; unsigned int gpio_port; int key_no; key_info_tab[4] = { // 按键所使用的 CPU 资源 { IRQ_EINT1, GPIO_F1, 1, { IRQ_EINT2, GPIO_F2, 2, { IRQ_EINT3, GPIO_F3, 3, { IRQ_EINT7, GPIO_F7, 4, ; static int ready = 0; static int key_value = 0; static DECLARE_WAIT_QUEUE_HEAD(buttons_wait); // 声明 初始化等待队列 buttons_wait static void buttons_irq(int irq, void *dev_id, struct pt_regs *reg)// 中断处理程序 { struct key_info *k; int i; int found = 0; int up; int flags; for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++){

30 k = key_info_tab + i; if (k->irq_no == irq) { found = 1; break; if (!found){ printk("bad irq %d in button\n", irq); return; save_flags(flags); cli(); // 禁用所有中断 set_gpio_mode_user(k->gpio_port, GPIO_MODE_IN); up = read_gpio_bit(k->gpio_port); set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS); restore_flags(flags); if (up) { key_value = k->key_no + 0x80; else { key_value = k->key_no; ready = 1; wake_up_interruptible(&buttons_wait); // 唤醒 buttons_wait 等待对列中的进程 static int request_irqs(void){ // 申请系统中断, 中断方式为双边延触发, 即在上升沿和下降沿均发生中断 struct key_info *k; int i; for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++){ k = key_info_tab + i; set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS); // 双边触发 if (request_irq(k->irq_no, &buttons_irq, SA_INTERRUPT, DEVICE_NAME, &buttons_irq)){ //0 表示成功, 负值表示出错 return -1; return 0; static void free_irqs(void) // 释放中断 { struct key_info *k; int i; for (i = 0; i < sizeof key_info_tab / sizeof key_info_tab[1]; i++){ k = key_info_tab + i;

31 fr ee_irq(k->irq_no, buttons_irq); stat ic int matrix4_buttons_read(struct file * file, char * buffer, size_t count, loff_t *ppos) { //*file_operations 的 " 读 " 指针函数实现 static int key; int flags; int repeat; if (!ready) return -EAGAIN; if (count!= sizeof key_value) return -EINVAL; save_flags(flags); if (key!= key_value){ key = key_value; repeat = 0; else{ repeat = 1; restore_flags(flags); if (repeat){ return -EAGAIN; copy_to_user(buffer, &key, sizeof key); ready = 0; return sizeof key_value; static unsigned int matrix4_buttons_select(struct file *file, struct poll_table_struct *wait){ if (ready) return 1; //POLLIN, 设备可以无阻塞读 poll_wait(file, &buttons_wait, wait); // 把当前进程放入一个等待对列 return 0; // 使进程调用 poll 或 select 系统调用时, 阻塞直到 buttons_wait 等待队列唤醒 static int matrix4_buttons_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ switch (cmd){ default: return -EINVAL; static struct file_operations matrix4_buttons_fops = { owner: THIS_MODULE, // 使用 copy_to_user 把键值送到用户空间

32 ioctl: matrix4_buttons_ioctl, poll: matrix4_buttons_select, /*po ll 方法是 poll 和 select 这两个系统调用的后端实现, 是在用户空间程序执行 poll 或 select 系统调用时被调用, 这两个系统调用可用来查询设备是否可读或可写, 或是否处理某种特殊状态 这两个系统调用是可阻塞的, 直至设备变为可读或可写状态为止 */ read: matrix4_buttons_read, ; static devfs_handle_t devfs_handle; static int init matrix4_buttons_init(void){ // 按键初始化 int ret; ready = 0; ret = register_chrdev(button_major, DEVICE_NAME, &matrix4_buttons_fops);// 注册按键设备 if (ret < 0){ printk(device_name " can't register major number\n"); return ret; ret = request_irqs(); // 请求中断 if (ret){ unregister_chrdev(button_major, DEVICE_NAME); printk(device_name " can't request irqs\n"); return ret; devfs_handle = devfs_register(null, DEVICE_NAME, DEVFS_FL_DEFAULT, BUTTON_MAJOR, 0, S_IFCHR S_IRUSR S_IWUSR, &matrix4_buttons_fops, NULL); // 使用 devfs 进行注册 return 0; static void exit matrix4_buttons_exit(void){ devfs_unregister(devfs_handl e) ; free_irqs(); unregister_chrdev(button_major, DEVICE_ NAME); module_init(matrix4_buttons_init); module_exit(matrix4_buttons_exit); MODULE_LICENSE("GPL"); 3.2 按键中断测试程序 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h>

33 #include <fcntl.h> #include <sys/select.h> #include <sys/time.h> #include <errno.h> int main(void){ int buttons_fd; int key_value; buttons_fd = open("/dev/buttons", 0); if (buttons_fd < 0) { perror("open device buttons"); exit( 1); for (;;){ fd_set rds; int ret; FD_ZERO(&rds); FD_SET(buttons_fd, &rds); ret = select(buttons_fd + 1, &rds, NULL, NULL, NULL);// 阻塞直到可读 if ( ret < 0){ perror("select") ; exit(1); if ( ret == 0){ printf("timeout.\n"); else if (FD_ISSET(buttons_fd, &rds)){ int ret = read(buttons_ fd, &key_value, sizeof key_value); if (ret!= sizeof key_value){ if (errno!= EAGAIN) perror("read buttons\n"); continue; else{ printf("buttons_value: %d\n", key_value); close(buttons_fd); return 0; 4. 定时器驱动及 PWM 输出 s3c2410 分别有 Timer 0,1,2,3,4 共 5 个定时器, 其中 Timer4 作为 linux 的系统调度时钟,Timer3

34 被 DMA 驱动所使用, 故只有 Timer 0,1,2 共 3 个定时器可用, 它们都具有 PWM 输出功能 4.1 驱动功能描述 1> 从 TOUT0 输出 38KHz, 占空比 50% 的 PWM 波, 且具有中断功能, 在中断服务程序中判断是否停止本定时器来关闭 PWM 输出, 实现调制功能 2> 能够使能 禁止 PWM 输出 3> 有 PWM 输出波形数量的记录功能, 且可随时读取, 清零 4.2 PWM 驱动程序 模块入口函数 :module_init(pwm_init); 和 module_exit(pwm_cleanup); pwm_init 函数主要完成注册字符设备驱动程序 注册设备文件 pwm_cleanup 函数将先前注册的都释放掉 初始化 PWM 使用的输出口 static devfs_handle_t devfs_handle; static int init pwm_init(void){ int result; result = register_chrdev(pwm_major, DEVICE_NAME, &pwm_fops); if (result < 0){ printk(kern_err DEVICE_NAME ": Unable to get major %d\n", PWM_MAJOR); return(result); devfs_handle = devfs_register(null, DEVICE_NAME, DEVFS_FL_DEFAULT, PWM_MAJOR, 0, S_IFCHR S_IRUSR S_IWUSR, &pwm_fops, NULL); set_gpio_ctrl(gpio_b0 GPIO_PULLUP_EN GPIO_MODE_TOUT);//TOUT0 printk(kern_info DEVICE_NAME ": init OK\n"); return(0); static void exit pwm_cleanup(void){ devfs_unregister(devfs_handle); unregister_chrdev(pwm_major, DEVICE_NAME); module_init(pwm_init); module_exit(pwm_cleanup); MODULE_LICENSE("GPL"); pwm_open 主要功能 : 注册 PWM 中断处理函数, 设置 PWM 的输出频率 freq 和占空比 rate 其中 freq 由 TCNTB0 寄存器值 (div) 和定时器的输入时钟决定, 定时器的输入时钟由 TCFG0 寄存器的 Prescaler0 值和 TCFG1 的 MUX0(divider value) 决定 公式如下 : Timer input clock Frequency = PCLK / {prescaler value+1 / {divider value Freq = Timer input clock Frequency / div 取 PCLK = 50,prescaler value = 1,divider value = 2, 要使 Freq = 38KHz, 则 div = Timer input clock Frequency / Freq = PCLK / {prescaler value+1 / {divider value /Freq = 50MHz /(1+1) / 2 / 38KHz = = 329

35 即 TCNTB0 = div = 329, 当 rate = 50% 时,TCMPB0 = 329 / 2 = 164 另外 CPU 的 FCLK HCLK PCLK 可由 kernel/arch/arm/mach-s3c2410/cpu.c 文件下的函数读取, 在系统启动过种中打印出来 如下 : freq = s3c2410_get_cpu_clk(); hclk = s3c2410_get_bus_clk(get_hclk); pclk = s3c2410_get_bus_clk(get_pclk); CPU clock = Mhz, HCLK = Mhz, PCLK = Mhz s3c2 410.h 中关于定时器的一些寄存器定义说明 TCFG0 = (TCFG0_DZONE(0) TCFG0_PRE1(15) TCFG0_PRE0(0)); #define T CFG0_DZONE(x) FInsrt( (x), ftcfg0_dzone) #define ftcfg0_dzone Fld(8,16) #define Fld(Size, Shft) (((Size) << 16) + (Shft)) 则 ftcfg0_dzone 为 ((8 << 16) + 16) TCFG0_DZONE(x) 为 FInsrt((x), ((8 << 16) + 16)) #define FInsrt(Value, Field) (UData (Value) << FShft (Field)) #ifndef ASSEMBLY #define UData( Data) ((unsigned long) ( Da ta) ) #else #define UData(Data) (Data) #endif #define FShft( Field) ((Field) & 0x0000FFFF) TCFG0_DZONE(x) 为 (unsigned long)x << (((8 << 16) + 16) & 0x0000FFFF) TCFG0_DZONE(x) 为 (unsigned long)x << 16 TCFG0_PRE1(x) 为 (unsigned long)x << (((8 << 16) + 8) & 0x0000FFFF) TCFG0_PRE1(x) 为 (unsigned long)x << 8 TCFG0_PRE0(x) 为 (unsigned long)x << (((8 << 16) + 0) & 0x0000FFFF) TCFG0_PRE0(x) 为 (unsigned long)x << 0 源程序 : static int pwm_open(struct inode *inode, struct file *filp){ unsigned long flag; if (usage = = 0){ request_irq(irq_timer0, pwm_irq_handle, SA_INTERRUPT, "my" DEVICE_NAME, NULL); local_irq_save(flag); TCFG0 = (TCFG0 & 0xFFFF00) 1; //prescaler value=1 TCFG1 = (TCFG1 & 0xFFFFF0) 0; //divider value=1/2 TCNTB0 = 329; //38KHz TCMPB0 = 164; //50% TCON = (TCON & 0x7FFFE0) 0x09;//Timer0:auto reload;update TCNTB0,TCMPB0;start RunTime = 0; local_irq_restore(flag); usage++; MOD_INC_USE_COUNT;

36 return 0; // success pwm_release 主要是将 PWM 中断释放, 及停止定时器运行及 PWM 输出, 源程序 : static int pwm_release(struct inode *inode, struct file *filp) { unsigned long flag; MOD_DEC_USE_ COUNT; usage--; if (usage == 0){ local_irq_save(flag); TCON = (TCON & 0x7FFFE0) 0x0A;//Timer0:auto reload;update TCNTB0,TCMPB0;stop local_irq_restore(flag); free_irq(irq_timer0, NULL); return(0); pwm_ioctl 完成 3 个功能 : 使能 禁止 读取 PWM 输出的波形数量, 源程序 : static int pwm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { switch(cmd){ case 0: local_irq_save(flag); RunTime = 0; TCON = (TCON & 0x7FFFE0) 0x09;//Timer0:auto reload; Update TCNTB0, TCMPB0; start local_irq_restore(flag); break; case 1: local_irq_save(flag); TCON = (TCON & 0x7FFFE0) 0x0A;//Timer0:auto reload; Update TCNTB0, TCMPB0; stop local_irq_restore(flag); break; case 2: if (put_user(runtime, (u32 *)arg)){ return -EFAULT; break; case 3: RunTime = 0; if (put_user(runtime, (u32 *)arg)){ return -EFAULT;

37 break; default: return -ENOTTY; break; return 0; pwm_irq_handle 定时中断函数, 用于递增 PWM 输出的波形数量值, 源程序 : static void pwm_irq_handle(int irq, void *dev_id, struct pt_regs *regs){ RunTime++ ; 4. 3 PWM 测试程序 主要测试能否正常使能 禁止 PWM 输出, 及频率 占空比是否正确 int main(void){ int fd; unsigned int RunTime; unsigned char i; fd = open("/dev/pwm", 0); if (fd < 0){ perror("open device PWM"); exit(1); while (1){ ioctl(fd,3,&runtime); for(i = 0; i < 10; i++){ ioctl(fd,0,&runtime); // 启动定时器 sleep(1); ioctl(fd,2,&runtime); // 读取 RunTime 值 printf("1s:runtime = %d\n",runtime); ioctl(fd,1,&runtime); // 停止定时器 sleep(1); ioctl(fd,2,&runtime); // 读取 RunTime 值 printf("1s:runtime = %d\n",runtime); for (i = 0; i < 10; i++){ ioctl(fd,0,&runtime); sleep(2); ioctl(fd,2,&runtime); printf("2s:runtime = %d\n",runtime); ioctl(fd,1,&runtime); sleep(2);

38 ioctl(fd,2,&runtime); printf("2s:runtime = %d\n",runtime); close(fd); return 0; // 读取 RunTime 值 5. 点亮目标板 LCD 5. 1 修改现有的 s3c2410fb.c 驱动程序 Linuette(mizi linux, 下同 ) 内核源码树下原有的 s3c2410fb.c(kernel/drivers/video/s3c2410fb.c) 是 240*480LCD 的驱动程序, 所以要将其修改成自己板子的 640 * 480, 其中部份参数需要根据特定的屏作些调整, 修改部分如下 : 1> 将 initdata 数据结构修改成如下所示 : static struct s3c2410fb_mach_info xxx_stn_info initdata = { pixclock: , bpp: 16, #ifdef CONFIG_FB_S3C2410_EMUL xres: 96, #else xres: 640, #endif yres: 480, hsync_len : 96, vsync_len : 2, left_margin : 40, upper_margin : 24, right_margin: 32, lower_margin : 11, sync:0,cmap_static: 1, reg : { lcdcon1 : LCD1_BPP_16T LCD1_PNR_TFT LCD1_CLKVAL(1), lcdcon2 : LCD2_VBPD(32) LCD2_VFPD(9) LCD2_VSPW(1), lcdcon3 : LCD3_HBPD(47) LCD3_HFPD(15), lcdcon4 : LCD4_HSPW(95) LCD4_MVAL(13), lcdcon5 : LCD5_FRM565 LCD5_INVVLINE LCD5_INVVFRAME LCD5_HWSWP LCD5_PWREN,, ; 2> 查找源文件中的 LCDLPCSEL, 修改成 LCDLPCSEL &= (~7); 如果修改成功, 内核启动时, 左上角会出现 mizilinux 字符和小蜻蜒的 LOGO 也可以将它的单个文件进行编译以模块形式装载测试, 装载前先删除原来的文件 : #rm /dev/fb/1 #insmod./s3c2410fb.o 自动生成设备文件 /dev/fb/1

39 5. 2 LCD 测试程序 #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> #include <sys/mman.h> #include <linux/fb.h> #define FBDEV "/dev/fb/1" static char *default_framebuffer=fbdev; struct fb_dev{ int fb; void *fb_mem; int fb_width, fb_height, fb_line_len, fb_size; int fb_bpp; ; static struct fb_dev fbdev; static void draw(int color){ int i, j; unsigned short int *p = (unsigned short int *)fbdev.fb_mem; for (i = 0; i < fbdev.fb_height; i++, p += fbdev.fb_line_len/2){ for (j = 0; j < fbdev.fb_width; j++){ p[j] = color; int framebuffer_open(void){ int fb; struct fb_var_screeninfo fb_vinfo; struct fb_fix_screeninfo fb_finfo; char *fb_dev_name = NULL; if (!(fb_dev_name = getenv("framebuffer"))){ fb_dev_name = default_framebuffer; fb = open(fb_dev_name, O_RDWR); if (fb < 0){ printf("device %s open failed\n", fb_dev_name); return -1; if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_vinfo)){ printf("can't get VSCREENINFO: %s\n", strerror(errno)); close(fb); return -1;

40 if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_finfo)) { printf("can't get FSCREENINFO: %s\n", strerror(errno)); return 1; fbdev.fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length + fb_vinfo.blue.length + fb_vinfo.transp.length; fbdev.fb_width = fb_vinfo.xres; fbdev.fb_height = fb_vinfo.yres; fbdev.fb_line_len = fb_finfo.line_length; fbdev.fb_size = fb_finfo.smem_len; printf("frame buffer: %d(%d)x%d, %dbpp 0x%xbyte\n", fbdev.fb_width, fbdev.fb_line_len, fbdev.fb_height, fbdev.fb_bpp, fbdev.fb_size); if (fbdev.fb_bpp!= 16){ printf("frame buffer must be 16bpp mode\n"); exit(0); fbdev.fb_mem = mmap(null, fbdev.fb_size, PROT_ READ PROT_WRITE, MAP_SHARED, fb, 0); if (fbdev.fb_mem == NULL (int)fbdev.fb_mem == -1){ fbdev.fb_mem = NULL; printf("mmap failed\n"); close(fb); return -1; fbdev.fb = fb; memset(fbdev.fb_mem, 0x0, fbdev.fb_size); return 0; void framebuffer_close(){ if (fbdev.fb_mem){ munmap(fbdev.fb_ mem, fbdev.fb_size); fbdev.fb_mem = NULL; if (fbdev.fb){ close(fbdev.fb); fbdev.fb = 0; int main(void){ int i; framebuffer_open(); for (i = 0; i < 16; i++){ printf("%d:color = 0x%x", i, 1 << i); draw(1 << i); getchar();

41 framebuffer_close(); return 0; 6. 安装触摸板 6.1 触摸板驱动程序的修改 内核自带的触摸板驱动源文件 : kernel\drivers\char\s3c2410-ts.c, 需在 s3c2410_ts_init() 初始 化函数中加入 ADCDLY = 0xFFFF 语句, 否则在按下触屏时, 触屏的采集值将非常的不稳定, 误差很大 6. 2 触摸板测试程序 #include <unistd.h> #include <stdio.h> #include <fcntl.h> typedef struct{ unsigned short pressure; unsigned short x; unsigned short y; unsigned short pad; TS_EVENT; int main(void){ static int ts = -1; static int mousex = 0; static int mousey = 0; static TS_EVENT ts_event; printf("touch screen test program\n"); printf("please touch the screen\n"); ts = open("/dev/touchscreen/0raw",o_rdonly); if (ts < 0) { fprintf(stderr,"can not open touch screen! \n"); exit(1); while (1){ read(ts, &ts_event, sizeof(ts_event)); if (ts_event.pressure > 0){ printf(ts_event.x = %d, ts_event.y = %d\n", ts_event.x, ts_event.y);

42 三. 构建完整的嵌入式 Linux 系统 1. 桌面系统的启动 当触摸板和 LCD 都能正常工作时, 就可以启动 Linuette 的桌面系统, 将原来的 root.cramfs 根文件系统, 更改为带 GUI 的根文件系统 ( 如 root_english.cramfs), 内核使用更新过的 进入 vivi 命令行模式, 重新分区 :0 192k 1M 下载 :vivi zimage root.cramfs 如果系统已正常启动, 则省略上述步骤 启动系统后, 如果一切正常将在左上角会出现蜻蜓和 mizilinux 的 logo 进入系统后, 通过 ztelnet 将 imagewrite root_english.cramfs 下载到目标系统的 /tmp 目录, 再利用 imagewrite 将文件系统更新成 root_english.cramfs #./imagewrite /dev/mtd/0 root_english.cramfs:1m 注 : 必须先通过 vivi 下载 root.cramfs, 待系统正常启动后, 通过 ztelnet 下载 root_english.cramfs 和 imagewrite, 再使用 imagewrite 烧写 root_english.cramfs 根文件系统, 如果直接用 vivi 的 xmodem 下载 root_english.cramfs 需很长的时间, 且会下载出错 重新启动系统将进入触摸屏校准程序, 校准正常后进入 QT 桌面环境 在控制台 ( 超级终端 ) 下可以按 Ctrl + C 退出 QT 服务器, 而进入平时的命令行模式 /usr/qt/bin 目录下的 cal.sh start.sh 分别为校准和 QT 服务器启动脚本, 都可以重新运行 2. 下载可读写的文件系统 Yaffs 2.1 安装 注 : 必须用 vi vi 进行分区, 再用 vivi 下载内核和根文件系统, 而不能启动目标板的 linux 系统后, 用 imagew rite 写入, 否则下载完重启时, 系统将不能正常引导 另外 mizi 公司没有在该光盘中提供 yaffs 文件系统的源代码, 只提供了编译好的测试内核 (zimage.yaffs) 所以上述的内核中也就不支持该文件系统, 必须使用编译好的 zimage.yaffs 内核, 在 linuette/target/box/image/rwimage 目录下 vivi>bon part 0 192k 1M 3M:M // 注 : 最后的 M 不能省, 它表示 MTD 分区 ( 不带 M 的为 bon 分区 ), 否则下载启动后将不出现 yaffs 文件系统相关的块驱动 (/dev/mtd/1 和 /dev/mtdblock/1), 用 df 显示文件系统时, 也不会包括 /dev/mtdblock/1 指定的文件系统项 vivi>load flash vivi x vivi>load flash kernel x // 写入 zimage.yaffs vivi>load flash root x // 写入 root.cramfs 注 : 为 rwimage 目录下的 root.cramfs, 它与原先 root.cramfs 不同的是在启动时会自动挂载 yaffs vivi>boot 启动系统后输入 #df 命令, 会查看到比原来安装的内核多出 /dev/mtdblock/1 指定的文件系统目录 /usr ( 说明 mount t yaffs /dev/mtdblock/1 /usr 成功,yaffs 有效 ), 此时就可以在 /usr 目录下创建目录和保存文件, 掉电后不会丢失 如下 : #mkdir /usr/ccn 重启系统 #ls /usr

43 2. 2 yaffs 的制作 生成根文件系统解压 /linuette/target/box/root_dir/rwimage 下的 root.tar 文件 #tar jxvf root.tar.bz2 #./mkcramfs./root./root.cramfs rwimage 目录下的该 root.cramfs 与以前的 root.cramfs 最大区别是在启动过程中会自动挂载 yaffs 生成 yaffs 类型的 usr 系统 #tar jxvf usr.tar.bz2 #./mkyaffsimage./usr usr.yaffs c 注 :mkyaffsimage 的第四个参数不能等于 convert, 这与大小端有关, 可以查看 mkyaffsimage 的源代码 2. 3 烧写 yaffs 类型的文件系统到 /usr 目录 除了上述直接在 /usr 目录下创建使用 yaffs 系统外, 也可以将整个 yaffs 类型的系统 (usr.yaffs) 烧 写到块设备 (/dev/mtdblock/1) 下, 然后挂载到 /usr 目录下, 也可以在根文件系统的 /tmp 目录下再创建 一个目录 ( 如 :/tmp/yaffs), 然后将 /dev/mtdblock/1 挂载到该目录下 下述为挂载到 /usr 目录下的方法 : 通过 ztelnet 或其它方法将 mkyaffs 和 usr.yaffs 两个文件下载到目标板上执行下述命令 #umount /usr #./mkyaffs -e /dev/mtd/1 usr.yaffs 或 #./mkyaffs /dev/mtd/1 usr.yaffs 将打印出写 NAND Flash 的许多信息, 写完后打印出 OK #mount -t yaffs /dev/mtdblock/1 /usr 此时用 #ls /usr 命令可以显示该目录下的文件夹, 也可以新键一个目录, 再写入文件进行读写测试, 如下 : #df -h Filesystem Size Used Available Use Mounted on /dev/bon/2 2.8M 2.8M 0 100% / tmpfs 0.6M M 0% /dev/shm /dev/mtdblock/1 61.0M 25.3M 35.7M 41% /usr #cd /usr;mkdir ccn #cp /tmp/mkyaffs./ccn #cp /tmp/usr.yaffs./ccn # ls mkyaffs usr.yaffs #df -h Filesystem Size Used Available Use Mounted on /dev/bon/2 2.8M 2.8M 0 100% / tmpfs 0.6M M 0% /dev/shm /dev/mtdblock/1 61.0M 51.3M 9.7M 84% /usr 最后重新启动系统, 测试新建的 ccn 目录及内容是否还存在 另外由于 usr.yaffs 里包含了 GUI, 所 以和 root_english.cramfs 作为根文件系统一样, 在启动 console 前会先运行触屏校准程序, 再启动 QT 服 务器, 进入桌面系统 可按 ctrl + C 停止 QT 服务器的运行, 而进入 console 模式下查看先前的目录

44 3. Yaffs 文件系统移植 当使用 linuette 现成提供的 zimage.yaffs 和 usr.yaffs 是不能正常启动桌面系统的, 因为它们提供的包含 yaffs 的测试内核, 支持的 LCD 是 320*480, 以及触摸板的驱动也没有修改, 所以必须在原来的内核源代码中移植 yaffs 文件系统, 才能在支持 yaffs 系统的同时, 任意修改内核代码部分, 如 LCD 分辨率 触摸板, 以及将驱动编译进内核等 移植调试思路 : 参照 mizi 提供的 yaffs( 源码不公开 ) 的使用, 及输出信息为线索, 一步步的使移植的功能接近它 如 :1> 启动时的分区信息 (BON info MTD partitions)2> /dev/mtd 和 /dev/mtdblock 3> /proc/filesystems 4> mount t yaffs /dev/mtdblock/1 /usr 3. 1 在 vivi 中进行分区 vivi>bon part 0 192k 1M 3M:M 注 : 最后面的 M 表示为 mtd 分区, 下面的 flag 将为 ; 当然也可以只分 3 个区 viiv>bon part show BON info. (4 partitions) No: offset size flags bad : 0x x k 1: 0x x000d k 2: 0x x M 3: 0x x03cfc M+1008k vivi>load flash vivi x vivi>load flash kernel x vivi>load flash root x vivi>boot NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V) bon0: ( ) bon1: (000d0000) bon2: ( ) bon3: ffc000 (03cfc000) 注意 : 也可以只分 3 个区 : vivi> bon part 0 192k 1M 3.2 修改 MTD 驱动的 NAND 分区 修改 kernel/drivers/mtd/nand/smc_s3c2410.c 文件中的 smc_partitions[], 如下 : static struct mtd_partition smc_partitions[] = { { name: "bon",

45 size: 0x , offset: 0x0, mask_flags: MTD_WRITEABLE, /*force read-only */, { name: "mtd", size: 0x03cfc000, offset: 0x , ; 另外在该文件开始部分的消除分区宏定义 : #undef CONFIG_MTD_SMC_S3C2410_SMDK_PARTITION 修改成 : #define CONFIG_MTD_SMC_S3C2410_SMDK_PARTITION 内核配置时选中 Memory Technology Devices (MTD) ---> NAND Flash Device Drivers ---> SMC Device Supp ort 及下属所有项重新编译内核, 下载, 启动 输出信息如下 : NAND device: Manufacture ID: 0xec, Chip ID: 0x76 (Samsung K9D1208V0M) Creating 2 MTD partitions on "Samsung K9D1208V0M": 0x x : "bon" 0x x03ffc000 : "mtd" bon0: ( ) bon1: (000d0000) bon2: ( ) bon3: ffc000 (03cfc000) #cat /proc/mtd dev: size erasesize name mtd0: "bon" mtd1: 03cfc "mtd" #ls /dev/mtd 0 #ls 0 1 0ro 1 1ro /dev/mtdblock 3.3 移植 yaffs 源代码 从官网 ( 下载源码 (yaffs.tar.gz) 解压, 在 kernel/fs/ 目录下新建 yaffs 目录, 将源码 (yaffs_fs.c yaffs_guts.c yaffs_mtdif.c yaffs_ecc.c devextras.h yaffs_guts.h yaffs_mtdif.h yaffs_ecc.h yaffsinterface.h yportenv.h) 复制到该目录下, 创建 yaffs_config.h 文件, 加入源码中使用到的宏定义, 如下 : #ifndef YAFFS_CONFIG_H #define YAFFS_CONFIG_H #define CONFIG_YAFFS_MTD_ENABLED

46 #define CONFIG_YAFFS_USE_OLD_MTD #endif 在该目录下创建 Makefile 文件, 内容如下 : O_TARGET := yaffs.o obj-y := yaffs_fs.o yaffs_guts.o yaffs_mtdif.o yaffs_ecc.o obj-m := $(O_TAGRET) include $(TOPDIR)/Rules.make 在 fs 目录的 Makefile 文件中加入 yaffs 子目录, 如下 : subdir-$(config_yaffs_fs) += yaffs 在 fs 目录的 Config.in 文件中加入 YAFFS 选项, 如下 : if [ $CONFIG_MTD_SMC = y ]; then tristate Yaffs filesystem on NAND CONFIG_YAFFS_FS fi 注 :if 的 [ ] 与字符间要用空隔隔开, 否则 if 条件会始终不成立内核配置时选中 File system ---> Yaffs filesystem on SMC, 再重新编译, 下载, 启动 输出信息如下 : #cat /proc/filesystems nodev rootfs nodev bdev nodev proc nodev sockfs nodev tmpfs nodev shm nodev pipefs cramfs nodev ramfs vfat nodev devfs nodev nfs jffs2 nodev autofs nodev devpts yaffs #mount -t yaffs /dev/mtdblock/1 /usr yaffs: dev is 7937 name is "1f:01" #mkdir /usr/ccn #ls /usr ccn lost+found #df -h Filesystem Size Used Available UseMounted on /dev/bon/2 2.7M 2.7M 0 100/ tmpfs 30.6M M 0/dev/shm

47 /dev/mtdblock/1 61.0M 100.0k 60.9M 0/usr 3. 4 出现的问题 在 smc_partitions[] 中添加 MTD 分区不起作用, 如下 : NAND device: Manufacture ID: 0xec, Chip ID: 0x76 (Samsung K9D1208V0M) bon0: ( ) bon1: (000d0000) bon2: ( ) bon3: ffc000 (03cfc000) #ls /dev/mtd 0 0ro #ls /dev/mtdblock 0 #cat /proc/mtd dev: size erasesize name mtd0: "Samsung K9D1208V0M" 原因是定义分区的 smc_partitions[] 在 CONFIG_MTD_SMC_S3C2410_SMDK_PARTITION 宏定义内, 而在该文件的开始又消除该宏定义, 因此必须将消除修改成定义, 如 : #undef CONFIG_MTD_SMC_S3C2410_SMDK_PARTITION 修改成 : #define CONFIG_MTD_SMC_S3C2410_SMDK_PARTITION 在 fs 目录的 Config.in 文件中加入 YAFFS 选项, 但在内核配置中始终没有出现 File system ---> Yaffs filesystem on SMC 项 原因 :Config.in 中 if 语句的 [ ] 与字符间要用空隔隔开, 否则 if 条件会始终不成立, 如下 : if [ $CONFIG_MTD_SMC = y ]; then tristate Yaffs filesystem on NAND CONFIG_YAFFS_FS fi 将加入 yaffs 的内核下载目标板启动后, 仍没有 yaffs 项, 如下 : # cat /proc/filesystems nodev rootfs nodev bdev nodev proc nodev sockfs nodev tmpfs nodev shm nodev pipefs cramfs nodev ramfs vfat nodev devfs nodev nfs

48 nodev autofs nodev devpts # 在 yaffs_fs.c 文件的 init_yaffs_fs() 函数的开始和注册文件系统语句前增加打印信息, 如下 : static int init init_yaffs_fs(void){ int error = 0; yaffs_dev = yaffsram_dev = NULL; printk( init_yaffs_fs.\n ); printk(kern_debug "yaffs " DATE " " TIME " Initialisation\n");... #ifdef CONFIG_YAFFS_MTD_ENABLED printk( register yaffs filesystem ); error = register_filesystem(&yaffs_fs_type); if (error){ #ifdef CONFIG_YAFFS_RAM_ENABLED unregister_filesystem(&yaffs_ram_fs_type); #endif //CONFIG_YAFFS_RAM_ENABLED #endif // CONFIG_YAFFS_MTD_ENABLED return error; 重新编译, 下载, 启动信息如下 : devfs: v1.10 ( ) Richard Gooch (rgooch@atnf.csiro.au) devfs: boot_options: 0x1 init_yaffs_fs... ttys00 at I/O 0x (irq = 52) is a S3C2410 ttys01 at I/O 0x (irq = 55) is a S3C2410 由上述信息中只有 init_yaffs_fs. 而没有 register yaffs filesystem, 说明系统调用了 yaffs 初始化函数, 但没有执行文件系统注册函数, 所以在 /proc/filesystems 中也就没有 yaffs 项 必须增加 CONFIG_YAFFS_MTD_ENABLED 的宏定义, 才能使该部分的注册函数有效, 故在文件开始前增加 : #defined CONFIG_YAFFS_ MTD_ENABLED 或者在源码目录下创建 yaffs_config.h 文件, 定义源码中所有的宏定义, 再被其它源文件包含 再次编译, 下载, 启动信息如下 : devfs: v1.10 ( ) Richard Gooch ( rgooch@atnf.csiro.au) devfs: boot_options: 0x1 init_yaffs_fs... register_filesystem... ttys00 at I/O 0x (irq = 52) is a S3C2410 ttys01 at I/O 0x (irq = 55) is a S3C2410 #cat /proc/filesystems

49 nodev rootfs nodev bdev nodev proc nodev sockfs nodev tmpfs nodev shm nodev pipefs cramfs nodev ramfs vfat nodev devfs nodev nfs nodev autofs nodev devpts yaffs # 包含 CONFIG_YAFFS_MTD_ENABLED 宏定义后, 编译出现错误 : yaffs_mtdif.c:33 variable yaffs_oobinfo has initializer but incomplete type yaffs_mtdif.c:34 unknow field useecc specified in initializer 将 yaffs_mtdif.c 中的用 nand_oobinfo 定义的两个结构体屏蔽掉 #mount t yaffs /dev/mtdblock/1 /usr 出错当执行该命令时会调用 yaffs_fs.c 文件中的 yaffs_internal_read_super() 函数, 主要还是该函数及子函数出现错误, 可以用 printk 函数打印信息的方法跟踪解决 本错误是由于当时没有将 yaffs_mtdif.c 文件中的 nand_oobinfo 结构完成屏蔽, 而只是屏蔽掉了编译时出现错误的 useecc, 所以在调试时出现一系列对未初始化指针操作等错误 所以如果仔细按照上述的移植步骤操作, 应不会出现类似的错误 #./mkyaffs e /dev/mtd/1 usr.yaffs 出现下述错误 : argc 4 sh 0 optcnt 2 MEMSETOOBSEL:Inappropriate ioctl for device 打开 yaffs 源码包 utils 目录下的 mkyaf fs.c 文件 (mkyaffs 工具的源文件 ), 可以看出是下例语句出现了错误 : Oobsel = usemtdecc? yaffs_oobinfo : yaffs_noeccinfo; if (ioctl(fd, MEMSETOOBSEL, &oobsel)!= 0){ perror ( MEMSETOOBSEL ); close (fd); exit (1); 该功能给 /dev/mtd/1 设备传递写入 nand flash 的 ecc 信息 (mtdchar.c 文件的 ioctl() 函数 ), 和上面屏蔽掉的 yaffs_mtdif.c 文件中的 yaffs_oobinfo 等是同一功能 由于我们使用的 MTD 驱动比较旧, 查看 /d rivers/mtd/mtdchar.c 文件的 ioctl() 函数可知还不支持该功能 因此也必须将 mkyaffs.c 文件中的该功能去掉再重新编译生成 mkyaffs 或者使用原来的 mkyaffs 工具, 但不加 -e 参数, 如 : #./mkyaffs /dev/mtd/1 usr.yaffs 或直接修改该源文件去掉 -e 功能

50 3.4.7 mkyaffs 编译出错在 Makefile 文件中的 MAKETOOLS = 处添加交叉编译工具路径, 如 : MAKETOOLS = /opt/host/armv4l/bin/armv4l-unknown-linux- 将 #include <mtd/mtd-user.h> 替换成 #include <linux/mtd/mtd.h>; 将 nand_oobinfo 两个结构屏蔽掉 ; 将 main 函数中的 struct nand_oobinfo oobsel; 和问题 6 提到的与 MEMSETOOBSEL 相关的语句屏蔽掉 最后编译生成目标文件 mkyaffs_noecc( 为了与原来的 mkyaffs 区别加上 _noecc 后缀 ) 系统启动后 /proc 目录为空等问题, 如下 : #df h Filesystem size Used Available Use% Mounted on df: /proc/mounts: No such file or directory #ls /proc 而且, 在宿主机上也不能用 ztelnet 登录, 提示 : [root@localhost root_dir]#ztelnet Trying telnet: Unable to connect to remote host: Connection refused 原因是在 vivi 中的 kernel command line 参数有错误, 如下述系统启动时的信息中缺少 linuxrc 脚本 : Kernel command line: console=ttys0 root=/dev/bon/2 在 vivi 下应设置成 : vivi> param set linux_cmd_line noinitrd root=/dev/bon/2 init=linuxrc console=ttys0 启动后信息如下 : Kernel command line: noinitrd root=/dev/bon/2 init=linuxrc console=ttys0 另外,yaffs 文件系统在多次使用, 没有可用空间时, 也可能出现该现象, 需在 vivi 中重新分区, 再下载内核 文件系统等解决 挂载 yaffs 文件系统时出现错误, 如下 : #mount t yaffs /dev/mtdblock/1 /usr yaffs: Attempting MTD mount on 31.1, if:01 mout: Mounting /dev/mtdblock/1 on /usr failed: Not a directory 原因是在执行 mkyaffsimage 工具打包 yaffs 格式文件系统影像时, 加入了 convert 参数, 如在 PC 机上 : [root@localhost root_dir]#./mkyaffsimage./root_english./root_ english.yaffs convert convert produce a big-endian image from a little-endian machine 在目标板上 : #./mkyaffs /dev/mtd/1./root_english.yaffs OK #mount t yaffs /dev/mtdblock/1 /usr yaffs: Attempting MTD mount on 31.1, if:01 mout: Mounting /dev/mtdblock/1 on /usr failed: Not a directory 只需将刚才的 MTD 设备重新用 yaffs 系统格式化就可以, 如下 : #./mkyaffs /dev/mtd/1 Erasing block at 0x83cf8000 OK #mount t yaffs /dev/mtdblock/1 /usr

51 yaffs: Attempting MTD mount on 31.1, if:01 # 制作 yaffs 文件系统的镜像不应加 convert 参数, 但又要满足参数大于 3 个, 所以第四个参数只要不为 convert 就可以, PC 机如下 : [root@localhost root_dir]#./mkyaffsimage./root_ english./root_english.yaffs c 下载到目标板后执行 : #./mkyaffs /dev/mtd/1./root_english.yaffs OK #mount t yaffs /dev/mtdblock/1 /usr yaffs: Attempting MTD mount on 31.1, if:01 # 3.5 yaffs 初始化及执行过程的简单总结 Step 1: 先调用 yaffs_fs.c 文件中的 init_yaffs_fs() 初始化函数, 它负责 yaffs 文件系统的注册, 将 yaffs 添加到 /proc/filesystems 中 ; 启动信息 : devfs: v1.10 ( ) Richard Gooch (rgooch@atnf.csiro.au) devfs: boot_options: 0x1 init_yaffs_fs... ( 需要在函数中加该打印信息 ) register_filesystem... Step 2: 调用 drivers/mtd/nand/smc_s3c2410.c 文件的 smc_s3c2410_init() 函数扫描及初始化 NAND Flash 设备及底层接口函数, 和 mtd 分区 ; 启动信息 : NAND device: Manufacture ID: 0xec, Chip ID: 0x76 (Samsung K9D1208V0M) add_mtd_partitions... ( 需要在函数中加该打印信息 ) Creating 2 MTD partitions on "Samsung K9D1208V0M": 0x x : "bon" 0x x03ffc000 : "mtd" Step 3 : 执行 mount t yaffs /dev/mtdblock/1 /usr 命令时, 调用 yaffs_fs.c 文件中的 yaffs_internal_read_super() 函数 执行信息 : # mount -t yaffs /dev/mtdblock/1 /usr yaffs_internal_read_super... ( 需要在函数中加该打印信息 ) yaffs: Attempting MTD mount on 31.1, "1f:01" Step 4: 另外还有对 yaffs 文件系统下的读或写等等, 都会调用 yaffs_fs.c 文件下的相应函数, 再调用 mtd 设备对应的 NAND Flash 接口函数等

52 4. Yaffs 作为根文件系统启动 4. 1 直接复制的方法更新 yaffs 将 root 内容复制到 yaffs 文件系统 /usr 后启动 vivi>bon part 0 192k 1M 3M:M vivi>load flash vivi x vivi>load flash kernel x vivi>load flash root x vivi>boot #ifconfig eth #inetd #mount t yaffs /dev/mtdblock/1 /usr // 支持 yaffs 的内核 // 启动 ztelnet 服务 在 PC 机上进入 /linuette/target/box/root_dir, 进入根文件系统 root( 也可是 root_english, 或其它 ) 目录下, 再将其所有内容打包 [root@localhost root]#tar zcvf root.tgz * [root@localhost root]#ztelnet 通过 ztelnet 将 root.tgz 下载到目标板的 /usr 目录下在目标板上 : # cd /usr # tar zxvf root.tgz;rm rf root.tgz 解压完后重启进入 vivi, 修改启动参数 vivi>param show Linux command line: noinitrd root=/dev/bon/2 init=linuxrc console=ttys0 vivi>param set linux_cmd_line noinitrd root=/dev/mtdblock/1 init=linuxrc console=ttys0 vivi>param save vivi>boot 此时的根文件系统为可写的 yaffs 文件系统, 可以在根目录下创建目录 文件等测试 4. 2 使用 mkyaffsimage 工具更新 Yaffs 将 root_english 制作成 Yaffs 根文件系统 上述是直接将文件系统下的所有文件简单的复制到挂载 yaffs 文件系统的 /usr 目录, 也可以利用先前提到的 mkyaffsimage 和 mkyaffs_noecc 工具完成 PC 宿主机下 : [root@localhost /]#cd /linuette/target/box/roo_ dir/ [root@localhost root_dir]#./mkyaffsimage./root_english./root_english.yaffs c [root@localhost root_dir]#ztelnet 通过 ztelnet 将 mkyaffs_ noecc root_english.yaffs 下载到目标板的 /tmp 目录下假设此时目标板根文件系统为 root.cramfs, 且未挂载 yaffs, 如果已经将 yaffs 挂载到了 /usr, 需要先 #umount /usr

53 目标板下 : #./mkyaffs_noecc /dev/mtd/1./root_english.yaffs OK 查看 root_english 是否生成成功 #mount t yaffs /dev/mtdblock/1 /usr yaffs: Attempting MTD mount on 31.1, if:01 #ls /usr 可与宿主机上的 /linuette/target/box/root_dir/root_english 目录比较是否有错误重启动进入 vivi, 修改启动参数 vivi>param set linux_cmd_line noinitrd root=/dev/mtdblock/1 init=linuxrc console=ttys0 vivi>param save vivi>boot 5. 完整的嵌入式 Linux 系统 目前有了针对 nand flash 的可读写文件系统 Yaffs, 加上先前已正常工作的 LCD 触摸板等内核驱动, 我想该平台可以称是比较完整的嵌入式 Linux 系统平台了 先前提到的嵌入式 Linux 软件系统一般有由 bootloader kernel root filesysytem 和可选的 user filesystem 构成, 则我们可有如下选择 : 不带 GUI 时平台 1:vivi + zimage + root.cramfs 平台 2:vivi + zimage + root.cramfs + user(user 为 yaffs 格式的空目录, 不含 GUI) 平台 3:vivi + zimage + root.yaffs 带 GUI 时平台 4:vivi + zimage + root_english.cramfs( 或 root_china.cramfs 等, 下同 ) 平台 5:vivi + zimage + root_english.yaffs 平台 6:vivi + zimage + root.cramfs + usr.yaffs 四. 嵌入式 WEB 服务器 1.Boa 移植 1.1 Boa 移植步骤 Step 1: 从 下载 Boa 源码, 将其解压并进入源码目录的 src 子目录 #tar xzf boa tar.gz #cd boa /src 生成 Makefile 文件 #./configure 修改 Makefile 文件, 找到 CC=gcc 和 CPP=gcc -E, 分别将其改为交叉编译器安装的路径 CC=/opt/host/armv4l/bin/armv4l-unknown-linux-gcc 和 CPP=/opt/host/armv4l/bin/armv4l-unknown-linux-gcc -E 并保存退出

54 然后运行 make 进行编译, 得到可执行程序 boa #make 去掉调试信息 #/opt/host/armv4l/bin/armv4l-unknown-linux-strip boa Step 2:Boa 的配置 Boa 需要在 /etc 目录下建立一个 boa 目录, 里面放入 Boa 的主要配置文件 boa.conf 在 Boa 源码目录下已有一个示例 boa.conf, 可以在其基础上进行修改 Group nogroup 修改成 Group 0, 由于在 /etc/group 文件中没有 nogroup 组, 所以设成 0 另外在 /etc/passwd 中有 nobody 用户, 所以 User nobody 不用修改 ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ 修改成 ScriptAlias /cgi-bin/ /var/www/cgi-bin/ 其它默认设置即可 还需要创建日志文件所在目录 /var/log/boa, 创建 HTML 文档的主目录 /var/www, 将静态网页存入该目录下 ( 可以将主机 /usr/share/doc/html/ 目录下的 index.html 文件和 img 目录复制到 /var/www 目录下 ), 创建 CGI 脚本所在目录 /var/www/cgi-bin, 将 cgi 的脚本存放在该目录下 另外还要将 mime.types 文件复制 /etc 目录下, 通常可以从 linux 主机的 /etc 目录下直接复制即可 Step 3: 测试 1> 静态 HTML 网页在目标板上运行 boa 程序, 将主机与目标机的 ip 设成同一网段, 然后打开任一个浏览器 (linux 或 window 下都可 ), 输入目标板的 ip 地址 ( 即可打开 /var/www/index.html 网页 2> CGI 脚本测试 boa 源码中有 cgi-bin 测试脚本 (boa /examples/cgi-test.cgi), 但由于它不是在我们目标平台下编译的, 所以不能将它复制到 /var/www/cgi-bin 目录下进行测试 下面是一个简单的 hello, world! 程序, 代码如下 : #include <stdio.h> void main(){ printf("content-type: text/html\n\n"); printf("<html>\n"); printf("<head><title>cgi Output</title></head>\n"); printf("<body>\n"); printf("<hl>hello, world.</hl>\n"); printf("<body>\n"); printf("</html>\n"); exit(0); 1.2 Boa 移植时出现的问题 1> 当运行 boa 程序时出现错误, 如下 : #./boa [27/Nov/1990:13:22: ]boa.c:266.icky Linux kernel bug!:no such file 将 User 0 修改成 User nobody 2> 打开网页时, 网页中的图片无法显示就将存放图片的子目录 /var/www/images 修改成 /var/www/img 3> 在测试 cgi 脚本时, 当在浏览器地址中输入 http// /cgi-bin/helloworld.cgi 时,

55 浏览输出下述错误 : 502 Bad Gateway The CGI was not CGI/1.1 compliant 在目标板的调试终端中输出下述错误 : cgi_header:unable to find LFIF 上述错误是在 boa 原码中的 cgi_header.c 文件中的 process_cgi_header 函数产生, 如下 : buf = req->header_line; c = strstr(buf, "\n\r\n"); if (c == NULL) { c = strstr(buf, "\n\n"); if (c == NULL) { log_error_time(); fputs("cgi_header: unable to find LFLF\n", stderr); // 出错信息 #ifdef FASCIST_LOGGING log_error_time(); fprintf(stderr, "\"%s\"\n", buf); #endif send_r_bad_gateway(req); return 0; 我们可以定义 FASCIST_LOGGING, 使产生该错误时将 buf 内容打印出来, 结果如下 : cgi_header:unable to find LFIF Content-type: text/html <html> <head><title>cgi Output</title></head> <body> <hl>hello, world.</hl> <body> </html> 原来 buf 中的内容就是 helloworld.c 中输出的内容, 查看输出结果, 再看 process_cgi_header 函数中的语句 :c = strstr(buf, "\n\n"), 很明显 buf 中没有两个连续的换行符 "\n\n", 所以是 helloworld.c 文件中的语句 :printf("content-type: text/html\n\n"); 错写成了 printf("content-type: text/html\n"); 上述行通过标准输出将字符串 Contenttype:text/plain\n\n 传送给 Web 服务器 它是一个 MIME 头信息, 告诉 Web 服务器随后的输出是以纯 ASCII 文本的形式 在这个头信息中有两个新行符, 这是因为 Web 服务器需要在实际的文本信息开始之前先看见一个空行 2.WEB 应用开发 在实践的产品开发中, 一般都使用 java 小程序, 通常先将控制界面的网页放在目标板 WEB 服务器指定的目录, 目标板同时也存放 java 小程序, 当客户浏览器打开控制网页时, 获取 java 小程序 ( 需安装 java

56 虚拟机 ),java 小程序再与目标板应用程序的网络服务器建立一个连接, 实现相互通信 由于我还没有时间精力学习 jave, 所以下面是基于 CGI 的方法 2. 1 CGIC 库的移植 从 CGIC 的主站点 上下载源码, 将其解压并进入源码目录 #tar zxvf cgic.tar.gz #cd cgic205 修改 Makefile 文件, 找到 CC=gcc, 将其改为 CC=/opt/host/armv4l/bin/armv4l-unknown-linux-gcc, 找到 AR=ar, 将其改为 AR=/opt/host/armv4l/bin/armv4l-unknown-linux-ar, 找到 RANLIB=ranlib, 将其改为 RANLIB=/opt/host/armv4l/bin/armv4l-unknown-linux-ranlib 找到 gcc cgictest.o o cgictest.cgi ${LIBS, 将其改为 $(CC) $(CFLAGS) cgictest.o o cgictest.cgi ${LIBS, 找到 gcc capture.o o capture ${LIBS, 并保存退出 然后输入 make 进行编译, 可以将生成的 capture 和 cgictest.cgi 文件复制到目标板目录 /var/www/cgi-bin/ 下, 以测试正确性 2.2 基于 CGIC 库的例程 参考 嵌入式 Linux 系统开发详解 基于 EP93XX 系列 ARM 一书中的 list.html 和 list.c 2.3 例程出现的问题 1> 点击 submit( 提交 ) 按钮后, 终端输出错误信息 : mkstemp:permission denied 浏览器弹出错误对话框 : 此文档中无数据原因 : 是在 boa 源代码目录下的 util.c 文件中, 用 mkstemp() 函数创建一个临时文件时出现权限错误 这是由于在 boa.conf 文件设置了 user:nobody, 使其运行 boa 服务器时以 nobody 为用户 ( 可以用 ps 命令查看 ), 所以在创建临时文件是没有足够的权限, 可以在 boa.conf 中将运行 boa 的用户为 root 身份 (user:root) 2> 当上述设置 user:root, 运行 boa 时, 在终端会输出错误信息 :boa.c:266.icky Linux kernel bug!:no such file 原因 :boa.c 文件中的下述语句出现问题, 可以将 boa.c 文件中的该行屏蔽掉 if (setuid(0)!= -1) { DIE("icky Linux kernel bug!"); 3> 点击例程中的 submit( 提交 ) 按钮后浏览器出现下述错误 : 地址变为 : 内容 :400 Bad Request Your client has issued a malfarned or illegal request 原因是 list.html 中 <form name="systemcont" method="post" action="/cgi-bin/list.cgi" onsubmit="return checkform()"> 写成了 <form name="systemcont" method="post" action="/var/www/cgi-bin/list.cgi" onsubmit="return checkform()"> 4> 在查看目录项输入目录如 :/var/www/cgi-bin/, 然后点击 submit( 提交 ) 按钮后, 浏览器恢复原样, 而没有在文本框中显示 ls /var/www/cgi-bin 的内容 原因是在 list.html 文件中的 <!--Dir--> 和 <!--Files--> 的前面有空格, 使 list.c 文件中下述语句出

57 错, 所以在 list.html 中的上面两个注释一定要写在行的开头 if (strcmp(buf, <!--Dir--> )==0) { if (strcmp(buf, <!--Files--> )==0) { 2. 4 CGI 的简单调试 CGI 程序像其他可执行程序一样, 可通过标准输入 (stdin) 从 Web 服务器得到输入信息, 如 Form 中的数据, 这就是所谓的向 CGI 程序传递数据的 POST 方法 这意味着在操作系统命令行状态可执行 CGI 程序, 对 CGI 程序进行调试 CGI 程序通过标准输出 (stdout) 将输出信息传送给 Web 服务器 传送给 Web 服务器的信息可以用各种格式, 通常是以纯文本或者 HTML 文本的形式, 这样我们就可以在命令行状态调试 CGI 程序, 并且得到它们的输出 实验下例程序, 直接在命令行下调试, 主要测试环境变量 #include <stdio.h> #include <stdib.h> main(){ int,i,n; printf ( Contenttype: te xt/plain\n\n ); n=0; if(getenv( CONTENT-LENGTH )) n=atoi(getenv(content-length )); for (i= 0;i<n;i++) putchar(getchar()); putchar ( \n ); fflush(stdout); 五.NFS 的配置 尽管 ztelnet 也可以将主机上的文件传送到目标板上, 但还是没有利用 NFS 将主机的目录直接挂载到目标机的目录下方便 1. 主机的 NFS 服务器配置 setp 1: 编辑共享目录配置文件 exports, 指定共享目录及权限等 #vi /etc/exports 在该文件中添加如下内容 : /image * (rw,sync,no_root_squash) 表示允许 IP 地址为 * 的目标机以读写的权限来访问 /image 目录, 也可简单的写成 : /image * (rw) setp 2: 关闭防火墙 ( 如果不执行这一步,setp 4 的回环测试也能通过, 但不能被客户端访问 ) 在文本模式下 # setup 进行进入设置窗口, 在 Firewall configration 的 Security Level 项中, 选中

58 No firewall, 然后退出 setp 3: 启动 NFS 服务 #/etc/init.d/nfs restart setp 4:NFS 服务器的回环测试, 以验证共享目录能否被访问 #mount :/image /mnt/nfs 将共享目录挂载到本机的 /mnt/nfs 目录下, 如果成功, 则 NFS 正常工作 2. 目标机的 NFS 客户端配置 setp 1: 让目标系统的 linux 内核支持 NFS 客户端在进行内核配置 (# make menuconfig) 时选中如下项 : File systems -> Network File Systems -> Provide NFSv3 client support Setp 2: 在目标机的 linux 系统目录下挂载 NFS 服务器的共享目录 #cd /tmp #mkdir nfs #mount o nolock :/image./nfs #ls./nfs 3. 出现的问题 在目标机上执行 #mount o nolock :/image./nfs 时, 总不能成功原因是没有关闭主机的防火墙, 执行 #setup 将 Firewall config 的 Security 设置成 NO Firewall, 再执行 #/etc/init.d/nfs restart, 最后再在目标机上 #mount o nolock :/image./nfs 第三阶段在项目中应用 Linux 公司没有其它的 Linux 工程师, 一直以来也没有招到合适的 Linux 工程师, 因此领导觉得用 Linux 的技术难度太大, 但更不愿意花高价钱引入 VxWorks 可是产品要突破瓶颈, 要与对手竞争, 早晚而且必须要走这一步 在对产品实现所需的相关技术深入学习评估后, 坚定的向领导承诺能够独自实现 解决所有的方方面面 虽然有些害怕 忧虑和信心不足, 但却给自己断了所有的退路 事实证明那是是完全正确的, 很多东西并没有当初想象的那么复杂, 时间也足够 由于产品没有图形界面, 不需 GUI, 这也省心了不少 原理图参考 mizi 光盘里的, 那是比较完整的, 再参照对比其它的开发板和书籍, 分析它们不同的地方, 再扩展产品特有部分 像以太网等很多外围器件的驱动, 系统都已自带了, 或有些只需修改一小部分, 而先增的外围驱动参考先前的 linux 设备驱动程序 一书, 难度也不是很大 应用编程, 由于对自己产品的熟悉, 和参考 GNU/Linux 编程指南 和 UNIX 环境高级编程, 所以只是工作量大些, 也不存在难度问题 网络通信可以参考 UNIX 网络编程, 虽然它很厚, 但只需参考学习一部分, 比想象中要简单很多 WEB 控制肯定不能自己用 CGI 写, 找个 PC 机程序员, 写个 java 小程序, 自己把 boa 服务器放进去, 也就是普通的网络编程 WiFi 花的精力比较多, 领导也最重视这个功能, 而当时对它也最为模糊 我觉得要想在产品上应用它, 自己应该先学会它的使用和配置, 于是就上网收索, 学习在 windows 下配置使用, 然后在 linux 下配置使用 因为一般的网卡在 linux 下都没有驱动, 又用 ndiswrapper 在 RedHat 9 下驱动无线网卡 由于扩展的 PCMCIA 卡控制器 PD6710 是 16 位的, 所以选择了华硕的 WL-110, 它没有现成的 linux 驱动, 使用的是 linux-wlan 项目的 linux-wlan-ng 驱动程序 也是先在 PC 机上使用 linux-wlan, 成功后再在目标板上使用 linux-wlan

59 注 : 以下只记录了我觉得不会对公司利益产生影响的部分内容 一. 进程间隔定时器 1. 概念 所谓 间隔定时器 (Interval Timer, 简称 itimer) 就是指定时器采用 间隔 值 (interval) 来作为计时方式, 当定时器启动后, 间隔值 interval 将不断减小 当 interval 值减到 0 时, 我们就说该间隔定时器到期 它主要被应用在用户进程上, 每个 Linux 进程都有三个相互关联的间隔定时器 : 1> 真实间隔定时器 (ITIMER_REAL): 这种间隔定时器在启动后, 不管进程是否运行, 每个时钟滴答都将其间隔计数器减 1 当减到 0 值时, 内核向进程发送 SIGALRM 信号 2> 虚拟间隔定时器 ITIMER_VIRT: 也称为进程的用户态间隔定时器 当虚拟间隔定时器启动后, 只有当进程在用户态下运行时, 一次时钟滴答才能使间隔计数器当前值 it_virt_value 减 1 当减到 0 值时, 内核向进程发送 SIGVTALRM 信号 ( 虚拟闹钟信号 ), 并将 it_virt_value 重置为初值 it_virt_incr 3> PROF 间隔定时器 ITIMER_PROF: 当一个进程的 PROF 间隔定时器启动后, 则只要该进程处于运行中, 而不管是在用户态或核心态下执行, 每个时钟滴答都使间隔计数器 it_prof_value 值减 1 当减到 0 值时, 内核向进程发送 SIGPROF 信号, 并将 it_prof_value 重置为初值 it_prof_incr 定时器在初始化时, 被赋予一个初始值, 随时间递减至 0 后发出信号, 同时恢复初始值 在任务中我们可以使用一种或全部三种定时器, 但同一时刻同一类型的定时器只能使用一个 2. 数据结构 Linux 在 include/linux/time.h 头文件中为上述三种进程间隔定时器定义了索引标识, 如下所示 : #define ITIMER_REAL 0 #define ITIMER_VIRTUAL 1 #define ITIMER_PROF 2 虽然, 在内核中间隔定时器的间隔计数器是以时钟滴答次数为单位, 但是让用户以时钟滴答为单位来指定间隔定时器的间隔计数器的初值显然是不太方便的, 因为用户习惯的时间单位是秒 毫秒或微秒等 所以 Linux 定义了数据结构 itimerval 来让用户以秒或微秒为单位指定间隔定时器的时间间隔值 其定义如下 (include/linux/time.h): struct itimerval { struct timeval it_interval; /* timer interval */ struct timeval it_value; /* current value */ ; 其中,it_interval 成员表示间隔计数器的初始值, 而 it_value 成员表示间隔计数器的当前值, 它们都是 timeval 结构类型的变量 struct timeval { time_t tv_sec; /* seconds */ suseconds_t tv_usec; /* microseconds */ ;

60 3. 操作函数 int getitimer(int which, struct itimerval *value); getitimer() 函数得到间隔计时器的时间值并保存在 value 中 有两个参数 : 1> which, 指定查询调用进程的哪一个间隔定时器, 其取值可以是 ITIMER_REAL ITIMER_VIRT 和 ITIMER_PROF 三者之一 2> value 指针, 指向用户空间中的一个 itimerval 结构, 用于接收查询结果 setitimer(int which, struct itimerval *value, struct itimerval *ovalue); setitimer() 不仅设置调用进程的指定间隔定时器, 而且还返回该间隔定时器的原有信息 它有三个参数 : 1> which, 含义与 sys_getitimer() 中的参数相同 2> 输入参数 value, 指向用户空间中的一个 itimerval 结构, 含有待设置的新值 3> 输出参数 ovalue, 指向用户空间中的一个 itimerval 结构, 用于接收间隔定时器的原有信息 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 该函数为 signum 所指定的信号设置信号处理器 sigaction 结构 (act 和 oldact) 描述了信号的部署 它在 <signal.h> 中的完整定义为 : struct sigaction{ void (*sa_handler)(int); // 规定了当 signum 中的信号产生后, 要调用的处理函数 sigset_t sa_mask; // 定义了在执行处理函数期间应该阻塞的其它信号集合的信号掩码 int sa_flags; void (*sa_restorer)(void); ; 4. 测试程序 #include <stdio.h> #include <signal.h> #include <sys/time.h> #include <asm/param.h> //#define HZ struct timeval tpstart,tpend; float timeuse; /* signal process */ static timer_count = 0; void prompt_info(int signo){ if ((++timer_count)%100 == 0){ time_t t=time(null); // 获取秒数表示的系统当前时间 printf("[%d]prompt_info called", timer_count); printf(" current time %s",ctime(&t)); // 将秒数转换成字符串输出 gettimeofday(&tpend,null); timeuse= * (tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec; // timeuse /= ; printf(" Used Time:%f\n",timeuse); void init_sigaction(void){

61 struct sigaction act; act.sa_handler = prompt_info; act.sa_flags = 0; sigemptyset(&act.sa_mask); // 初始化一个空的信号集合 act.sa_mask sigaction(sigalrm, &act, NULL); // 为 SIGALRM 信号设置信号处理函数 gettimeofday(&tpstart,null); void init_time(void){ struct itimerval val; val.it_value.tv_sec = 0; // 设置间隔定时器的当前值 val.it_value.tv_usec = 10000; // 取值要大等于时钟滴答的周期, 否则仍为时钟滴答的时间 val.it_interval = val.it_value; // 间隔计数器的初始值 setitimer(itimer_real, &val, NULL);// 设置真实间隔定时器, 定时结束后将发出 SIGALRM 信号 int main(void){ printf("clock tick frequency is %d\n",hz); // 输出时钟滴答的频率 init_sigaction(); init_time(); // printf("clock tick frequency is %d\n",hz); while(1); exit(0); 注 : 单独运行该测试程序时, 几乎看不到什么误差, 但在运行比较复杂程序的同时, 再运行该测试程序, 误差就会显示出来, 而且比想象中要恶劣的多, 所以在实际应用时一定要注意! 二. 虚拟地址 在标准的 Linux 中对硬件物理地址的访问和 uclinux 是完全不同的, 在 uclinux 下可以直接引用硬件的物理地址, 因为 uclinux 是针对无 MMU 的处理器, 因此对硬件物理地址采用的是实际地址 与此相反, 标准 linux 下, 硬件的实际物理地址是直接访问不到的, 必须映射到 Linux 的虚拟地址空间统一管理 如特殊功能寄存器, 完成物理地址到虚拟地址转换的函数和定义分别位于 Linux 源码的 kernel/arch/arm/mach-s3c2410/generic.c 和 kernel/include/asm-arm/arch-s3c2410/hardware.h generic.c 中相关程序如下 : static struct map_desc standard_io_desc[] initdata = { /* virtual physical length domain r w c b */ { 0xe , 0x , 0x , DOMAIN_IO, 0, 1, 0, 0, LAST_DESC ; void init s3c2410_map_io(void){ iotable_init(standard_io_desc); Hardware.h 中的相关定义如下 : #define VIO_BASE 0xe /* virtual start of IO space */ #define PIO_START 0x /* physical start of IO space */

62 如外部设备, 完成物理地址到虚拟地址转换的函数和定义分别位于 Linux 源码的 kernel/arch/arm/mach-s3c2410/smdk.c 和 kernel/include/asm-arm/arch-s3c2410/smdk.h smdk.c 中相关程序如下 : static struct map_desc smdk_io_desc[] initdata = { /* virtual physical length domain r w c b */ { vcs8900_base, pcs8900_base, 0x , DOMAIN_IO, 0, 1, 0, 0, { vcf_ MEM_BASE, pcf_mem_base, 0x , DOMAIN_IO, 0, 1, 0, 0, { vcf_ IO_BASE, pcf_io_base, 0x , DOMAIN_IO, 0, 1, 0, 0, LAST_DESC ; static void init smdk_map_io(void){ s3c2410_map_io(); iotable_init(smdk_io_desc); s3c2410_register_uart(0, 0); s3c2410_register_uart(1, 1); set_gpio_ctrl(gpio_ir_txd); set_gpio_ctrl(gpio_ir_rxd); s3c2410_register_uart(2, 2); #ifdef CONFIG_PM register_wakeup_src(0, EXT_FALLING_EDGE, 0); #endif smdk.h 中的相关定义如下 : /* CS8900a, ngcs3 */ #define pcs8900_base 0x #define vcs8900_ BASE 0xd /* PCMCIA, ngcs2 */ #define pcf_mem_base #define vcf_mem_base #define pcf_io_ BASE #define vcf_io_base 0x xd x xd 三. 以太网控制器 CS8900A 硬件调试 1. 调试步骤 Step 1: 检查网络的物理连接 用交叉网线将目标板于 PC 机相联, 此时目标板和 PC 机的以太网连接指示灯 (LINKLED) 将常亮, 活动指示灯将闪烁,PC 机 (windows 系统 ) 将出现网络已连接信息 如果不正常, 可能是接收或发送链路还有问题, 或芯片的该相关部分有问题, 特别注意芯片第 93 脚 (RES) 连接的电阻阻值

63 Step 2: 读取芯片 ID 判断芯片及 ISA 总线是否正常 可在 kernel/drivers/net/cs8900a.c 的初始化部分增加读取芯片 ID 号及打印的代码 正常的 ChipID: 630e, 通常不正确时读出来 ChipID:dc90 此时可能是 I/O 和内存空间读写部分的逻辑转换电路, 或地址数据线不正常等 也可直接在 ADS 或其它环境下写一小段不用在 linux 下运行的代码 : #define CS8900_BASE (*(volatile unsigned short*)0x ) #define EthIOAddr (*(volatile unsigned short*)0x ) #define EthPPP (*(volatile unsigned short*)0x a) #define EthPPD0 (*(volatile unsigned short*)0x c) void Test_CS8900(void){ rbwscon = rbwscon & ~(0xf << 12) (0xd << 12);//nGCS3=nUB/nLB(sSBHE),nWAIT,16-bit rbankcon3 = (0 << 13) (3 << 11) (7 << 8) (1 << 6) (0 << 4) (3 << 2) 0; EthPPP = 0; Uart_Printf("CS8900A ChipID1 is %x\n", EthPPD0);// 打印 ID EthPPP = 2; Uart_Printf("CS8900A ChipID2 is %x\n", EthPPD0); 以上两部完成后在启动内核的初始化以太网时将打印下述信息 : Eth0:cs8900 rev K(3.3 Volts) found at 0xd Cs89x0 media RJ-45, IRQ 37 然后启动系统后就可以用 ifconfig eth0 进行设置,ping 通了 2. 出现过的问题 1> 用交叉网线连接到 PC 机时网络指示灯不亮,PC 机没有任何反应 原因 :CS8900A 第 93 脚连接的 RES 阻值不正确 2> PC 机显示网络已连接 ( 只说明物理层正常 ), 但读取 CS8900A 的 ID 不正确 原因 : 总线没有配置好, 如 : rbwscon = rbwscon & ~(0xf << 12) (0xd << 12); //ngcs3=nub/nlb(ssbhe),nwait,16-bit rbankcon3 = (0 << 13) (3 << 11) (7 << 8) (1 << 6) (0 << 4) (3 << 2) 0; 或缓冲芯片 (74LVCH162245) 等不正常或虚焊 3> 在以太网接口芯片 CS8900A 和 PCMCIA 接口 PD6700 电路中为何都要用到 ADDR24 及一些组合逻辑电路? 原因 :CS8900A 和 PD6700 都为 ISA 总线接口, 而在 ISA 总线接口中,I/O 空间和内存空间是独立寻址的, 因此它们有各自不同的读写信号 但 ARM 体系中,I/O 空间和内存空间是统一寻址, 因此电路设计的时候用高位地址线 (ADDR24) 经过组合逻辑的译码来区分 I/O 空间和内存空间的读写 如使用 ngcs3 的 CS8900A, 它的内存空间地址为 0x (ADDR24 = 1), 则 I/O 空间地址为 0x 又如使用 ngcs2 的 PD6700, 它的内存空间地址为 0x , 则 I/O 空间地址为 0x 四. WiFi 无线网络

64 1. 在 RedHat9 上安装 TL-WN210 无线网卡驱动 1. 1 安装步骤 在调试目标板的无线网络时,PC 机也必须有一个无线网卡和其连接 目前比较便宜通用的是 TP-LINK, 但其没有 linux 下的驱动, 所以下面介绍用 ndiswrapper 驱动该网卡的方法 Step 1: 下载 ndiswrapper 从该项目的主页 ( 下载 ndiswrapper-1.1.tar.gz Step 2: 重新编译内核 在安装 ndiswrapper 包之前, 要保证 /lib/modules/ /build 存在, 它是指向 /usr/src/linux 目录的符号链接 重新编译内核, 否则安装 ndiswrapper 过程中, 执行 depmod -a 命令时, 会出现以下错误 : depmod: *** Unresolved symbols in /lib/modules/ default/misc/ndiswrapper.o 安装完执行 modeprobe ndiswrapper 命令时也会执行上述的一系列错误, 而失败 即使都成功, 网卡在运行过程当中也有可能会出不正常现象, 如定时的往终端上打印信息的现象 具体操作如下 : 切换到 /usr/src/linux 目录, 运行 make mrproper 保证源码树是干净的, 查看该目录下的 Makefile, 将 EXTRAVERSION = -8custom 的 custom 字样去掉, 运行 make menuconfig, 可以不修改, 保存配置文件, 运行 make dep Step 3: 安装 ndiswrapper 解压缩下载的 ndiswrapper-1.1.tar.gz 文件, 切换到压缩后的目录, 运行 make clean, 再运行 make install 安装 Step 4: 安装网卡驱动 将网卡驱动光盘里该网卡在 Windows XP 下的安装信息文件 (NET8180.INF) 和系统文件 (rtl8180.sys) 复制到一个目录中 ( 如在当前目录下新建 TL-WN210, 将两个文件复制到 TL-WN210 目录 ) 用 ndiswrapper I./TL-WN210/NET8180.INF 命令来加载该网卡 Windows 下的驱动, 安装成功后会提示 :install NET8180, 如果用 ndiswrapper l 命令会列出加载的驱动程序 最后运行 modprobe ndis wrapper 命令加载 ndiswrapper 模块, 此时无线网卡的 POWER 指示灯将闪烁 ( 每次重启后, 都需要重新执行 modprobe ndiswrapper 命令加载 ndiswrapper 模块 ) 如果不闪烁, 则执行 /etc/init.d/pcmcia restart Step 5: 使用 iwconfig 设定无线接口 当网卡的 POWER 指示灯将闪烁后, 输入 iwconfig 命令列出可用的无线网络接口, 及各接口的操作模式 频率 无线接入点的 MAC 地址 信号质量 电源管理状态 密钥值等 [root@zkccn /]#iwconfig Lo no wireless extensions. eth0 no wireless extensions. Wlan0 IEEE b ESSID:off/any Mode:Auto Frequency:2.412GHz Access Point: 00:00:00:00:00:00 Bit Rate=11Mb/s Tx-Power=20 dbm Sensitivity=0/3 RTS thr:2432 B Fragment thr:2432 B Encryption key:off Power Management:off Link Quality:100/100 Signal level:-80 dbm Noise level:-256 dbm Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0 Step 6: 搜索网络 可用 iwlist 来扫描邻近无线接入点的信标帧 : [root@zkccn /]#iwlist wlan0 scan

65 Wlan0 Scan completed : Cell 01 - Address: 00:15:E9:DE:B1:5D ESSID:"R$DNAN6" (Unknown Wireless Token 0x8B01) Mode:Master Frequency:2.422GHz Quality:0/100 Signal level:-80dbm Noise level:-256 dbm Encryption key:on Bit Rate:1Mb/s Bit Rate:2Mb/s Bit Rate:5.5Mb/s Bit Rate:11Mb/s Extra:bcn_int=100 Extra: atim=0 Step 7: 连接无线网络连接无线网络的第一步, 是使用 iwconfig 的 essid 选项让网卡知道你想参与的无线网络的标识 (ESSID): [root@zkccn /]#iwconfig wlan0 essid "R&DNAN6" 每个无线网络都有一个标识, 而且区分大小写 若名称中含有空格, 则必须以一对双引号括住 设定网络标识后, 还需要该标识的密码 (WEP key), 否则执行上面指令后还不能连接上 ( 用 iwconfig wlan0 时显示 ESSID:off/any, 而不是预期的 ESSID: "R$DNAN6") 设定 key 指令 : [root@zkccn /]#iwconfig wlan0 key B19227EF6E 设定好标识及密码之后, 无线网卡的 LINK 指示灯会亮, 表明已连接上无线网络的接入点 可以再一次用 iwconfig 检查设定结果 : [root@zkccn /]#iwconfig wlan0 Wlan0 IEEE b ESSID: "R$DNAN6" Mode:Managed Frequency:2.412GHz Access Point: 00:15:E9:DE:B1:5D Bit Rate=11Mb/s Tx-Power=20 dbm Sensitivity=0/3 RTS thr:2432 B Fragment thr:2432 B Encryption key:b192-27ef-6e Encryption mode:restricted Power Management:off Link Quality:100/100 Signal level:-80 dbm Noise level:-256 dbm Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0 除了 WEP-key 之外, 还必须选择 WEP 系统形式 开放式 (open) 系统接受明文形式的数据帧, 而受限 (restricted) 系统会丢弃明文形式的数据帧 [root@zkccn /]#iwconfig wlan0 key open [root@zkccn /]#iwconfig wlan0 key restricted 设定好所要用的 WEP-key 与 WEP 系统形式 另外, 如果为点对点还需设置连接模式, 如 : [root@zkccn]#ifconfig wlan0 mode ad-hoc Step 8: 获取 IP 地址, 访问网络当连接上无线接入点后, 还不能访问网络, 还需配置 IP 地址, 用 ifconfig 命令查看状态 :

66 /]#ifconfig wlan0 Wlan0 Link encap:ethernet HWaddr 00:0A:EB:A4:DE:A3 BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:14 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:14472 (14.1 Kb) TX bytes:4140 (4.0 Kb) Memory: 此时如果 PING 会失败, 如下 : [root@zkccn /]#ping Connect:Network is unreachable ( 网络不能获得 ) 创建 /etc/sysconfig/network-scripts/ifcfg-wlan0 文件, 使无线网卡自动获得 IP 地址 该文件内容如下 : BOOTPROTO= dhcp MTU= REMOTE_IPADDR= STARTMODE= onboot UNIQUE= 编辑完上述文件保存后, 用 dhclient 来取得 IP 地址 : [root@zkccn /]#dhclient wlan0 如果不成功, 可能是没有 ifcfg-wlan0 文件 [root@zkccn /]#dhclient eth1 Internet Systems Consortium DHCP Client V3.0pl1 Copyright Internet Systems Consortium. All rights reserved. For info, please visit Listening on LPF/wlan0/00:0a:eb:a4:de:3a Sending on LPF/wlan0/00:0a:eb:a4:d3:3a Sending on Socket/fallback DHCPDISCOVER on wlan0 to port 67 DHCPACK from bound to renewal in seconds. [root@zkccn /]#ifconfig wlan0 Wlan0 Link encap:ethernet HWaddr 00:0A:EB:A4:DE:A3 inet addr: Bcast: Mask: UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:74 errors:0 dropped:0 overruns:0 frame:0 TX packets:28 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:100 RX bytes:14472 (14.1 Kb) TX bytes:4140 (4.0 Kb) Memory:

67 现在就可以 ping 通公司内部 BBS 了如 : [root@zkccn /]# ping PING ( )56(84) bytes of data. 64 bytes from : icmp_seq=1 ttl=127 time=4.46ms 64 bytes from : icmp_seq=2 ttl=127 time=1.68ms 64 bytes from : icmp_seq=3 ttl=127 time=2.01ms ping statistics packets transmitted, 8 received, 0% packet loss, time 3047ms Rtt min/avg/max/mdev = 1.681/2.150/4.465/0.882 ms 然后进入 X Window 环境, 打开浏览器, 就可以上网了 Step 9: 删除 ndiswrapper 卸载前首先要用 modprobe -r ndiswrapper 来卸载这个内核模块, 用 ndiswrapper -e drivername 来卸载安装的一个具体驱动程序, 删除 /etc/ndiswrapper 目录下的关于该驱动程序的文件夹, 就可以运行 make uninstall 命令来卸载程序了 1.2 出现的问题 : modprobe ndiswrapper 命令加载 ndiswrapper 模块时, 网卡的 POWER 灯不亮, 且运行 cardctl eject 命令时提示 /proc/driver 目录下找不到 pcmcia 驱动, 运行 /etc/rc.d/init.d/pcmcia restart 时出现 : pcmcia_core.o 原因是删除了 pcmcia 模块及相关驱动, 需要重装, 可以安装 pcmcia-cs tar 方法 : 到 下载 pcmcia-cs tar [root@zkccn src]#tar zxvf pcmcia-cs tar [root@zkccn src]#cd pcmcia-cs [root@zkccn pcmcia-cs-3.2.8]#make config 中间有一步需设定 kernel source 所在目录 : Linux kernel source directory [/usr/src/linux]: /usr/src/linux [root@zkccn pcmcia-cs-3.2.8]#make all [root@zkccn pcmcia-cs-3.2.8]#make install [root@zkccn pcmcia-cs-3.2.8]#/etc/rc.dinit.d/pcmcia restart 重新启动 pcmcia 裝置 [root@zkccn pcmcia-cs-3.2.8]#dump_cis 观察是否有抓到网络卡 2. 无线网络配置 2. 1 Window XP 下配置点对点连接 Setup 1: 打开 无线网络连接 属性对话框, 切换到 无线网络配置 选项卡, 勾选 用 Windows 配置我的无线网络设置 选项, 如下图所示

68 Setup 2: 点击 Setup 1 图所示的 高级 按钮, 将会弹出如下图所示对话框 在其中点选 仅计算机 到计算机 选项, 然后去掉 自动连接到非首选的网络 复选框, 最后单击 关闭 按钮 Setup 3: 返回 Setup 2 所示窗口后再单击 添加 按钮 接着会弹出如下图所示 无线网络属性 设置框 在 网络名 (SSID) 中输入无线网络的标识, 如 my net, 然后去掉 自动为我提供此密钥 选项, 再输入 10 位十六进制的数字密钥 ( 注 : 如不执行这一步, 给网络提供密钥, 尽管最后网络能够连接, 但也不能 ping 通 ) 最后点 确定 按钮

69 提示 :SSID 值主要用来区分不同的网络, 最多可以设置 32 个字符 只有为两台计算机的无线网卡设置了名称相同的 SSID 值, 才能实现互相通信 Setup 4: 切换到 常规 选项卡, 双击 Internet 协议 (TCP/IP), 打开 Internet 协议 (TCP/IP) 属性 对话框 选中 使用下面的 IP 地址 选项, 将 IP 地址设置为 , 子网掩码设置为 Setup 5: 切换到 高级 选项卡, 然后勾选中 Internet 连接共享的两个选项, 如下图所示 :

70 到此完成了主机的设置 Setup 6: 再到另一台计算机进行同样的设置 ( 这里称其为客户机 ) 主要是 IP 地址一项要注意, 应将客户机的 IP 地址设置在与主机同一网段, 比如 ; 还有网关和 DNS 服务器都应设置为 ( 即主机 IP 地址 ) Setup 7: 当两台计算机连接到网络后, 就可以分别在命令行窗口下 ping 对方的 IP 地址 注 : 如果网络没有设置密钥时, 可能会 ping 不通 2.2 Linux 下配置点对点连接 Step 1:[root@zkccn /]#modprobe nidswrapper Step 2:[root@zkccn /]#iwconfig wlan0 mode ad-hoc Step 3:[root@zkccn /]#iwconfig wlan0 essid my net Step 4:[root@zkccn /]#iwconfig wlan0 key [root@zkccn /]#iwconfig wlan0 Wlan0 IEEE b ESSID: "my net" Mode:Ad-hoc Frequency:2.412GHz Access Point: 00:11:22:33:53:B8 Bit Rate=11Mb/s Tx-Power=20 dbm Sensitivity=0/3 RTS thr:2432 B Fragment thr:2432 B Encryption key: Encryption mode:restricted Power Management:off Link Quality:100/100 Signal level:-80 dbm Noise level:-256 dbm Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def Kaise s 2410 Board setting [1]. Device Driver Device Driver Linux s Kernel ARM s kernel s3c2410_kernel2.4.18_r1.1_change.tar.bz2 /usr/src (1) #cd /usr/src (2) #tar xfj s3c2410_kernel2.4.18_r1.1_change.tar.bz2

More information

华恒家庭网关方案

华恒家庭网关方案 LINUX V1.5 1 2 1 2 LINUX WINDOWS PC VC LINUX WINDOWS LINUX 90% GUI LINUX C 3 REDHAT 9 LINUX PC TFTP/NFS http://www.hhcn.com/chinese/embedlinux-res.html minicom NFS mount C HHARM9-EDU 1 LINUX HHARM9-EDU

More information

Abstract arm linux tool-chain root NET-Start! 2

Abstract arm linux tool-chain root NET-Start! 2 Lab III - Embedding Linux 1 Abstract arm linux tool-chain root NET-Start! 2 Part 1.4 Step1. tool-chain 4 Step2. PATH 4 Part 2 kernel 5 Step1. 5 Step2... 6 Step3...8 Part 3 root. 8 Step1. 8 Step2. 8 Part

More information

Microsoft Word - PS2_linux_guide_cn.doc

Microsoft Word - PS2_linux_guide_cn.doc Linux For $ONY PlayStatioin2 Unofficall General Guide Language: Simplified Chinese First Write By Beter Hans v0.1 Mail: hansb@citiz.net Version: 0.1 本 人 是 菜 鸟 + 小 白 欢 迎 指 正 错 误 之 处, 如 果 您 有 其 他 使 用 心 得

More information

Microsoft Word - 在VMWare-5.5+RedHat-9下建立本机QTopia-2.1.1虚拟平台a.doc

Microsoft Word - 在VMWare-5.5+RedHat-9下建立本机QTopia-2.1.1虚拟平台a.doc 在 VMWare-5.5+RedHat-9 下建立 本机 QTopia-2.1.1 虚拟平台 张大海 2008-5-9 一 资源下载 1. 需要以下安装包 : tmake-1.13.tar.gz qtopia-free-source-2.1.1.tar.gz qt-embedded-2.3.10-free.tar.gz qt-x11-2.3.2.tar.gz qt-x11-free-3.3.4.tar.gz

More information

Microsoft Word - linux命令及建议.doc

Microsoft Word - linux命令及建议.doc Linux 操 作 系 统 命 令 集 1 基 本 命 令 查 看 系 统 信 息 : uname -a 修 改 密 码 : passwd 退 出 : logout(exit) 获 取 帮 助 : man commands 2 文 件 和 目 录 命 令 显 示 当 前 工 作 目 录 : pwd 改 变 所 在 目 录 : cd cd - 切 换 到 上 一 次 使 用 的 目 录 cd 切 换

More information

本文由筱驀釹贡献

本文由筱驀釹贡献 本 文 由 筱 驀 釹 贡 献 ppt 文 档 可 能 在 WAP 端 浏 览 体 验 不 佳 建 议 您 优 先 选 择 TXT, 或 下 载 源 文 件 到 本 机 查 看 Linux 操 作 系 统 Linux 操 作 系 统 第 一 部 分 介 绍 与 安 装 Linux 的 由 来 : Linux 的 由 来 : 的 由 来 Linus Torvalds 1.Linux 的 版 本 1.Linux

More information

<4D6963726F736F667420576F7264202D20C7B6C8EBCABD6C696E7578BBF9B4A1CAB5D1E92E646F63>

<4D6963726F736F667420576F7264202D20C7B6C8EBCABD6C696E7578BBF9B4A1CAB5D1E92E646F63> 嵌 入 式 linux 基 础 实 验 1 内 核 配 置 及 编 译 1. 进 入 内 核 所 在 目 录 /opt/ruiva/xscale/linux-2.6.26 #cd /opt/ruiva/xscale/linux-2.6.26 2. 键 入 make menuconfig, 根 据 需 要 适 当 配 置 内 核 #make menuconfig 这 里 先 使 用 默 认 的 配 置,

More information

C/C++ - 文件IO

C/C++ - 文件IO C/C++ IO Table of contents 1. 2. 3. 4. 1 C ASCII ASCII ASCII 2 10000 00100111 00010000 31H, 30H, 30H, 30H, 30H 1, 0, 0, 0, 0 ASCII 3 4 5 UNIX ANSI C 5 FILE FILE 6 stdio.h typedef struct { int level ;

More information

嵌入式Linux知识培训

嵌入式Linux知识培训 嵌入式 Linux 知识培训 主要包括以下四部分内容 : 一 嵌入式 Linux 开发的基本知识 二 Linux 下使用 C 语言进行系统开发 三 面向嵌入式 Linux 的 GUI 系统的体系结构及二次开发 四 基于 Linux OS Smart Phone 的体系结构及开发内容 李玉东 第一部分 基础知识 嵌入式 Linux 软件系统的构成 1.BootLoader 2. Kernel 3.FileSystem

More information

lect03.ppt

lect03.ppt Linux 操 作 系 统 Linux 基 础 主 要 内 容 q 使 用 Linux q Linux 的 两 种 登 录 方 式 q 字 符 操 作 环 境 和 X Windows 系 统 q Linux 图 形 界 面 基 本 操 作 q Linux 命 令 的 使 用 方 式 q Linux 一 些 常 用 命 令 1 2 一 些 基 本 术 语 u 命 令 (Command) 给 计 算 机

More information

DVK530/531扩展板

DVK530/531扩展板 DVK720 扩展板 驱动移植手册 2014.04.03 V1.0 版权声明 本手册所有权由深圳市微雪电子有限公司独家持有 未经本公司的书 面许可, 不得以任何方式或形式进行修改 分发或复制本文档的任何 部分, 否则一切后果由违者自负 版本更新记录 版本日期说明 V1.0 2014.04.03 初始发布 深圳市微雪电子有限公司 www.waveshare.net I 目录 版权声明... I 版本更新记录...

More information

ebook70-22

ebook70-22 2 2 L i n u x f s t a b X 11 L i n u x L i n u x L i n u x D O S Wi n d o w s L i n u x O p e n L i n u x / u s r / m a n / m a n 5 f s t a b m o u n t m o u n t L i n u x 22.1 OpenLinux L i n u x U N

More information

ebook15-C

ebook15-C C 1 1.1 l s ( 1 ) - i i 4. 14 - d $ l s -ldi /etc/. /etc/.. - i i 3077 drwxr-sr-x 7 bin 2048 Aug 5 20:12 /etc/./ 2 drwxr-xr-x 13 root 512 Aug 5 20:11 /etc/../ $ls -ldi /. /..... i 2 2 drwxr-xr-x 13 root

More information

ARM JTAG实时仿真器安装使用指南

ARM JTAG实时仿真器安装使用指南 ARM JTAG Version 1.31 2003. 11. 12 ARM JTAG ARM JTAG.3 ARM 2.1.4 2.2.4 ARM JTAG 3.1 18 3.2 18 3.2.1 Multi-ICE Server.18 3.2.2 ADS..21 ARM JTAG 4.1 Multi-ICE Server 33 4.1.1 Multi-ICE Server..... 33 4.1.2

More information

自由軟體教學平台

自由軟體教學平台 NCHC Opensource task force DRBL steven@nchc.gov.tw, c00hkl00@nchc.gov.tw National Center for High-Performance Computing http://www.nchc.gov.tw Jan, 2003 1 2003/1/28 ( ) 09:00-10:30 10:40-12:00 Linux 13:00-14:30

More information

untitled

untitled V3041A-J/V3042A-J IP-SAN/NAS Infinova Infinova Infinova Infinova www.infinova.com.cn Infinova Infinova Infinova 1 2 1 2 V3041A-16R-J V3041A-24R-J V3042A-16R-J V3042A-24R-J V3049-EXD-R16 V3049-EXD-R24 ...

More information

untitled

untitled V3049A-EXD IP-SAN/NAS Infinova Infinova Infinova Infinova www.infinova.com.cn Infinova Infinova Infinova 1 2 1 2 V3049A-EXD-R16 V3049A-EXD-R24 ... 1 1.1... 1 1.2... 1 1.3... 1... 2 2.1... 2 2.2... 3...

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,

More information

快 速 入 门 (Linux) 概 述 文 档 目 的 本 文 档 介 绍 了 如 何 快 速 创 建 Linux 系 统 实 例 远 程 连 接 实 例 部 署 环 境 等 旨 在 引 导 您 一 站 式 完 成 实 例 的 创 建 登 录 和 快 速 环 境 部 署 云 服 务 器 ECS 实

快 速 入 门 (Linux) 概 述 文 档 目 的 本 文 档 介 绍 了 如 何 快 速 创 建 Linux 系 统 实 例 远 程 连 接 实 例 部 署 环 境 等 旨 在 引 导 您 一 站 式 完 成 实 例 的 创 建 登 录 和 快 速 环 境 部 署 云 服 务 器 ECS 实 云 服 务 器 ECS 快 速 入 门 (Linux) 快 速 入 门 (Linux) 概 述 文 档 目 的 本 文 档 介 绍 了 如 何 快 速 创 建 Linux 系 统 实 例 远 程 连 接 实 例 部 署 环 境 等 旨 在 引 导 您 一 站 式 完 成 实 例 的 创 建 登 录 和 快 速 环 境 部 署 云 服 务 器 ECS 实 例, 有 时 候 也 被 称 为 阿 里 云

More information

2004 Sun Microsystems, Inc Network Circle, Santa Clara, CA U.S.A. Sun Sun Berkeley BSD University of California UNIX X/Open Company, Ltd.

2004 Sun Microsystems, Inc Network Circle, Santa Clara, CA U.S.A. Sun Sun Berkeley BSD University of California UNIX X/Open Company, Ltd. Java Desktop System 2 Sun Microsystems, Inc. 4150 Network Circle Santa Clara, CA 95054 U.S.A. : 817 7758 10 2004 9 2004 Sun Microsystems, Inc. 4150 Network Circle, Santa Clara, CA 95054 U.S.A. Sun Sun

More information

手册 doc

手册 doc 1. 2. 3. 3.1 3.2 3.3 SD 3.4 3.5 SD 3.6 3.7 4. 4.1 4.2 4.3 SD 4.4 5. 5.1 5.2 5.3 SD 6. 1. 1~3 ( ) 320x240~704x288 66 (2G SD 320x2401FPS ) 32M~2G SD SD SD SD 24V DC 3W( ) -10~70 10~90% 154x44x144mm 2. DVR106

More information

. Outline 编译 Linux 在 QEMU 模拟器上运行制作带 grub 启动的磁盘映像...1 编译 Linux 在 QEMU 模拟器上运行...2 制作带 grub 启动的磁盘映像

. Outline 编译 Linux 在 QEMU 模拟器上运行制作带 grub 启动的磁盘映像...1 编译 Linux 在 QEMU 模拟器上运行...2 制作带 grub 启动的磁盘映像 .... 计算机应用教研室 @ 计算机学院嵌入式系统实验室 @ 苏州研究院中国科学技术大学 Fall 2010 . Outline 编译 Linux 在 QEMU 模拟器上运行制作带 grub 启动的磁盘映像...1 编译 Linux 在 QEMU 模拟器上运行...2 制作带 grub 启动的磁盘映像 . 编译 Linux 在 QEMU 模拟器上运行 qemu+linux-2.6.26.1. 准备模拟器.2.

More information

Microsoft Word - 正文.doc

Microsoft Word - 正文.doc 1 2 1 2 3 4 5 6 7 8 9 10 3 1 150 2 150 1 1 1.1 1.1.1 1.2 1.2.1 1.2.2 1.2.3 1.3 1.3.1 1.3.2 1.4 1.4.1 CPU 1.4.2 I/O 1.4.3 I/O 1.5 1.5.1 CISC RISC 1.5.2 1.5.3 1.6 1.6.1 1.6.2 N 1.6.3 2 2.1 2.1.1 2.1.2 2.1.3

More information

05_資源分享-NFS及NIS.doc

05_資源分享-NFS及NIS.doc 5 NFS NFS Server NFS Client NIS NIS 5-0 (Network File System, NFS) Unix NFS mount NFS... Network Information Service NIS Linux NIS NIS NIS / / /etc/passwd /etc/group NFS NIS 5-1 NFS 5-1-1 NFS NFS Network

More information

ebook71-13

ebook71-13 13 I S P Internet 13. 2. 1 k p p p P P P 13. 2. 2 1 3. 2. 3 k p p p 1 3. 2. 4 l i n u x c o n f P P P 13. 2. 5 p p p s e t u p 13. 2. 6 p p p s e t u p P P P 13. 2. 7 1 3. 2. 8 C a l d e r a G U I 13.

More information

Windows 2000 Server for T100

Windows 2000 Server for T100 2 1 Windows 95/98 Windows 2000 3.5 Windows NT Server 4.0 2 Windows DOS 3.5 T200 2002 RAID RAID RAID 5.1 Windows 2000 Server T200 2002 Windows 2000 Server Windows 2000 Server Windows 2000 Server 3.5 for

More information

嵌入式系统实验报告之一

嵌入式系统实验报告之一 南京航空航天大学 嵌入式系统综合实验报告 Qtopia 在 S3C2440 开发板上的移植 040630520 彭立勋 2009.05 一 实验目的 1. 熟悉 ARM 体系结构 ; 2. 熟悉 Qtopia 图形环境 二 实验内容 将 Qtopia 图形环境移植到 FriendlyARM QQ2440 开发板 三 预备知识 Qtopia 的体系结构 四 实验设备及工具 硬件 :QQ2440 开发板

More information

untitled

untitled 錄 行 令 X Window 切 /etc/inittab, X Window GNOME 例, X Window, 滑, 行 令, X Window X Window 了 滑,, 行 / 令, 來 切 切 Linux (console) 了 7, 行 X Window, 來切, 切 Linux X Window,,, 滑, 不,,,, /etc/inittab, "id:5:initdefault:",

More information

Red Flag Linux Desktop 4.0 Red Flag Linux Desktop 4.0 1

Red Flag Linux Desktop 4.0 Red Flag Linux Desktop 4.0 1 Red Flag Linux Desktop 4.0 68 6 Red Flag Software Co., Ltd. http://www.redflag-linux.com Red Flag Linux Desktop 4.0 Red Flag Linux Desktop 4.0 1 1 Red Flag Linux Desktop 4.0 1.1 Red Flag Linux Desktop

More information

Windows XP

Windows XP Windows XP What is Windows XP Windows is an Operating System An Operating System is the program that controls the hardware of your computer, and gives you an interface that allows you and other programs

More information

Windows 2000 Server for T100

Windows 2000 Server for T100 T200 3020 Windows 2000 Advanced Server /Windows NT 4.0 Server /Redhat Linux7.3 SCO UnixWare7.1.1 Novell NetWare5.0 1. Windows 2000 Advanced Server / 2. Windows NT 4.0 Server / 3. Redhat Linux7.3 4. SCO

More information

1

1 SDT Uclinux SDT.alf.c 44blib.alf 44blib.c jtag ADS.alf.c make menuconfig make dep make clean make lib_only make user_only make romfs make image make uclinux ext2 cash lcd frambuffer 1 armsys-c uclinux

More information

PowerPoint 演示文稿

PowerPoint 演示文稿 Linux 操 作 系 统 基 础 介 绍 课 程 目 标 及 要 求 了 解 Linux 操 作 系 统 的 登 入 方 式 掌 握 常 用 命 令 的 基 本 用 法 能 够 熟 练 在 各 个 目 录 转 换 Outline 1. Linux 操 作 系 统 简 介 2. Linux 操 作 系 统 的 登 录 3. Linux 操 作 系 统 的 目 录 结 构 4. 常 用 命 令 5.

More information

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File 51 C 51 51 C C C C C C * 2003-3-30 pnzwzw@163.com C C C C KEIL uvision2 MCS51 PLM C VC++ 51 KEIL51 KEIL51 KEIL51 KEIL 2K DEMO C KEIL KEIL51 P 1 1 1 1-1 - 1 Project New Project 1 2 Windows 1 3 N C test

More information

ebook35-2

ebook35-2 2 2.1 Linux login Login: < > Password: < > Linux r o o t l o g o u t 2.2 Linux X Window Linux Linux Bourne ( b s h ) C ( c s h ) Korn ( k s h ) Bourne Steven Bourne UNIX Bourne bash Bourne C Bill Joy Bourne

More information

Bus Hound 5

Bus Hound 5 Bus Hound 5.0 ( 1.0) 21IC 2007 7 BusHound perisoft PC hound Bus Hound 6.0 5.0 5.0 Bus Hound, IDE SCSI USB 1394 DVD Windows9X,WindowsMe,NT4.0,2000,2003,XP XP IRP Html ZIP SCSI sense USB Bus Hound 1 Bus

More information

TCA Linux 相容性認證測試流程步驟

TCA Linux 相容性認證測試流程步驟 年 度 流 -Linux 行 北 年 錄...2 說...4 2.1...4 2.2...4 2.3...4 2.4 行...5...6 3.1...6 3.2...6 3.3...7 3.4 列...7 Linux...8 4.1...8 4.1.1 CD-ROM...8 4.1.2 滑...10 4.1.3...14 4.1.4 路...19 4.1.5 Linux...22 4.1.6...27

More information

05 01 X Window X Window Linux Linux X Window X Window Webmin Web Linux Linux X Window X Window Notebook PC X Window X Window module Linux Linux kernel

05 01 X Window X Window Linux Linux X Window X Window Webmin Web Linux Linux X Window X Window Notebook PC X Window X Window module Linux Linux kernel Linux sub bash test2.sh sub bash test.sh test2.sh sub bash var1 123 123 test.sh test2.sh var1 bash sub bash var1 bash 01 5-4 X Window X Window X Window Linux Server X Window CPU2006 Linux X Window benchmark

More information

錄...1 說...2 說 說...5 六 率 POST PAY PREPAY DEPOSIT 更

錄...1 說...2 說 說...5 六 率 POST PAY PREPAY DEPOSIT 更 AX5000 Version 1.0 2006 年 9 錄...1 說...2 說...3...4 說...5 六...6 6.1 率...7 6.2 POST PAY...8 6.3 PREPAY DEPOSIT...9 6.4...10 6.5...11 更...12...12 LCD IC LED Flash 更 兩 RJ11 ( ) DC ON OFF ON 狀 狀 更 OFF 復 狀 說

More information

Guide to Install SATA Hard Disks

Guide to Install SATA Hard Disks SATA RAID 1. SATA. 2 1.1 SATA. 2 1.2 SATA 2 2. RAID (RAID 0 / RAID 1 / JBOD).. 4 2.1 RAID. 4 2.2 RAID 5 2.3 RAID 0 6 2.4 RAID 1.. 10 2.5 JBOD.. 16 3. Windows 2000 / Windows XP 20 1. SATA 1.1 SATA Serial

More information

09 Linux Linux Linux Linux 009.indd /9/4 下午 12:11:10

09 Linux Linux Linux Linux 009.indd /9/4 下午 12:11:10 09 Linux Linux Linux Linux 009.indd 1 2009/9/4 下午 12:11:10 Linux 指令範例速查手冊 9.1 badblocks badblocks [ ][ ] badblocks -b < > -c < > -i < > -o < > mke2fs -p -t < > -n -s -v -w 0 badblocks -o 9-2 009.indd 2

More information

(Guangzhou) AIT Co, Ltd V 110V [ ]! 2

(Guangzhou) AIT Co, Ltd V 110V [ ]! 2 (Guangzhou) AIT Co, Ltd 020-84106666 020-84106688 http://wwwlenxcn Xi III Zebra XI III 1 (Guangzhou) AIT Co, Ltd 020-84106666 020-84106688 http://wwwlenxcn 230V 110V [ ]! 2 (Guangzhou) AIT Co, Ltd 020-84106666

More information

Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7.

Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7. Kubernetes 包管理理 工具 Helm 蔺礼强 Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7. Kubernetes

More information

K7VT2_QIG_v3

K7VT2_QIG_v3 ............ 1 2 3 4 5 [R] : Enter Raid setup utility 6 Press[A]keytocreateRAID RAID Type: JBOD RAID 0 RAID 1: 2 7 RAID 0 Auto Create Manual Create: 2 RAID 0 Block Size: 16K 32K

More information

Microsoft Word - 第5章.doc

Microsoft Word - 第5章.doc 目 录 及 权 限 管 理 随 着 的 不 断 发 展, 越 来 越 多 的 人 开 始 使 用, 对 于 那 些 刚 接 触 的 人 来 说, 恐 怕 最 先 感 到 困 惑 的 就 是 那 些 不 明 不 白 的 目 录 了 同 样, 系 统 是 一 个 典 型 的 多 用 户 系 统 为 了 保 护 系 统 的 安 全 性, 系 统 对 不 同 用 户 访 问 同 一 文 件 或 目 录 的

More information

Linux服务器构建与运维管理

Linux服务器构建与运维管理 1 Linux 服务器构建与运维管理 第 2 章 :Linux 基本命令 阮晓龙 13938213680 / rxl@hactcm.edu.cn http://linux.xg.hactcm.edu.cn http://www.51xueweb.cn 河南中医药大学管理科学与工程学科 2018.3 2 提纲 目录与文件的操作 mkdir touch mv cp rm rmdir file tree

More information

LSI U320 SCSI卡用户手册.doc

LSI U320 SCSI卡用户手册.doc V1.0 Ultra320 SCSI SCSI 2004 7 PentiumIntel MS-DOS Windows Novell Netware Novell Sco Unix Santa Cruz Operation LSI U320 SCSI SCSI SCSI Integrated Mirroring/Integrated Striping BIOS Firmware LSI U320 SCSI

More information

C/C++程序设计 - 字符串与格式化输入/输出

C/C++程序设计 - 字符串与格式化输入/输出 C/C++ / Table of contents 1. 2. 3. 4. 1 i # include # include // density of human body : 1. 04 e3 kg / m ^3 # define DENSITY 1. 04 e3 int main ( void ) { float weight, volume ; int

More information

1.ai

1.ai HDMI camera ARTRAY CO,. LTD Introduction Thank you for purchasing the ARTCAM HDMI camera series. This manual shows the direction how to use the viewer software. Please refer other instructions or contact

More information

C 1

C 1 C homepage: xpzhangme 2018 5 30 C 1 C min(x, y) double C // min c # include # include double min ( double x, double y); int main ( int argc, char * argv []) { double x, y; if( argc!=

More information

Microsoft Word - 实用案例.doc

Microsoft Word - 实用案例.doc 计 算 机 系 统 应 用 2009 年 第 12 期 嵌 入 式 Linux 下 温 湿 度 传 感 器 的 设 计 与 实 现 1 Design and Implementation of Temperature and Humidity Sensor Based on Embedded Linux 陈 博 刘 锦 高 ( 华 东 师 范 大 学 电 子 科 学 技 术 系 上 海 200241)

More information

QLOGIC QLA22OO 使用手冊

QLOGIC QLA22OO 使用手冊 QLOGIC QLA23XX HBA 1.0 2002 ...5 1....5 2.?...5 3....5...7 1....7 2....7 3....99...122 1....122 2....122 3....133 4....133 FAST!UTIL...144 1....144 2. CONFIGURATION SETTINGS...144 3. SCAN FIBRE CHANNEL

More information

68369 (ppp quickstart guide)

68369 (ppp quickstart guide) Printed in USA 04/02 P/N 68369 rev. B PresencePLUS Pro PC PresencePLUS Pro PresencePLUS Pro CD Pass/Fails page 2 1 1. C-PPCAM 2. PPC.. PPCAMPPCTL 3. DB9D.. STPX.. STP.. 01 Trigger Ready Power 02 03 TRIGGER

More information

User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2

User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2 Terminal Mode No User User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2 Mon1 Cam-- Mon- Cam-- Prohibited M04 Mon1 Cam03 Mon1 Cam03

More information

IP505SM_manual_cn.doc

IP505SM_manual_cn.doc IP505SM 1 Introduction 1...4...4...4...5 LAN...5...5...6...6...7 LED...7...7 2...9...9...9 3...11...11...12...12...12...14...18 LAN...19 DHCP...20...21 4 PC...22...22 Windows...22 TCP/IP -...22 TCP/IP

More information

Basic System Administration

Basic System Administration 基 本 系 统 管 理 ESX Server 3.5 ESX Server 3i 版 本 3.5 Virtual Center 2.5 基 本 管 理 指 南 基 本 管 理 指 南 修 订 时 间 :20080410 项 目 :VI-CHS-Q208-490 我 们 的 网 站 提 供 最 新 的 技 术 文 档, 网 址 为 : http://www.vmware.com/cn/support/

More information

FY.DOC

FY.DOC 高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主

More information

新・明解C言語入門編『索引』

新・明解C言語入門編『索引』 !... 75!=... 48 "... 234 " "... 9, 84, 240 #define... 118, 213 #include... 148 %... 23 %... 23, 24 %%... 23 %d... 4 %f... 29 %ld... 177 %lf... 31 %lu... 177 %o... 196 %p... 262 %s... 242, 244 %u... 177

More information

TPM BIOS Infineon TPM Smart TPM Infineon TPM Smart TPM TPM Smart TPM TPM Advanced Mode...8

TPM BIOS Infineon TPM Smart TPM Infineon TPM Smart TPM TPM Smart TPM TPM Advanced Mode...8 Smart TPM Rev. 1001 Smart TPM Ultra TPM Smart TPM TPM...3 1. BIOS... 3 2. Infineon TPM Smart TPM... 4 2.1. Infineon TPM...4 2.2. Smart TPM...4 3. TPM... 5 3.1. Smart TPM TPM...5 3.2. Advanced Mode...8

More information

Microsoft Word - S3c6410移植过程.doc

Microsoft Word - S3c6410移植过程.doc S3C6400/6410 移植 Android 内核 主要过程 : 安装 lunux 环境 安装编译工具 下载 Linux kernel 安装 Android SDK 获得 root file system 修改 Linux kernel 源码 配置 Linux kernel 修改 root file system 编译 Linux kernel 下载 kernel Image 1. 安装 linux

More information

ebook62-1

ebook62-1 1 Red Hat Linux R e d Hat Linux L i n u x X Wi n d o w Red Hat L i n u x 1.1 Red Hat Linux Red Hat 16 M 120 M 3. 5 Intel 386 C D - R O M C D - R O M We b / 1.1.1 L i n u x L i n u 4 Primary Partition Extended

More information

Linux Ubuntu Part Linux Ubuntu Linux UNIX...19 Linux...19 Linux Linux...21 Linux GNU FSF Open So urce.

Linux Ubuntu Part Linux Ubuntu Linux UNIX...19 Linux...19 Linux Linux...21 Linux GNU FSF Open So urce. Linux Ubuntu 10.04 Part 1 17 1 Linux Ubuntu... 18 1-1 Linux... 19 UNIX...19 Linux...19 Linux...20...20 Linux...21 Linux...21 1-2 GNU FSF Open So urce...22 GNU...22 GPL...23...24 1-3 GNU/Linux V.S. Linux...25

More information

51 C 51 isp 10 C PCB C C C C KEIL

51 C 51 isp 10   C   PCB C C C C KEIL http://wwwispdowncom 51 C " + + " 51 AT89S51 In-System-Programming ISP 10 io 244 CPLD ATMEL PIC CPLD/FPGA ARM9 ISP http://wwwispdowncom/showoneproductasp?productid=15 51 C C C C C ispdown http://wwwispdowncom

More information

Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE "Project Properties" IDE makefile 1.

Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE Project Properties IDE makefile 1. Oracle Solaris Studio 12.2 IDE 2010 9 2 8 9 10 11 13 20 26 28 30 32 33 Oracle Solaris Studio makefile C C++ Fortran IDE Solaris Linux C/C++/Fortran IDE "Project Properties" IDE makefile 1. "File" > "New

More information

bingdian001.com

bingdian001.com TSM12M TSM12 STM8L152C6, STM8L152R8 MSP430F5325 whym1987@126.com! /******************************************************************************* * : TSM12.c * : * : 2013/10/21 * : TSM12, STM8L f(sysclk)

More information

目录

目录 ALTERA_CPLD... 3 11SY_03091... 3 12SY_03091...4....5 21 5 22...8 23..10 24..12 25..13..17 3 1EPM7128SLC.......17 3 2EPM7032SLC.......18 33HT46R47......19..20 41..20 42. 43..26..27 5151DEMO I/O...27 52A/D89C51...28

More information

ch08.PDF

ch08.PDF 8-1 CCNA 8.1 CLI 8.1.1 8-2 8-3 8.1.21600 2500 1600 2500 / IOS 8-4 8.2 8.2.1 A 5 IP CLI 1600 2500 8-5 8.1.2-15 Windows 9598NT 2000 HyperTerminal Hilgraeve Microsoft Cisco HyperTerminal Private Edition (PE)

More information

Unix®t Œ fi z.PDF

Unix®t Œ fi z.PDF 7 9 8 0 $ man umount newfs $ man -a intro $ man -a chown ORDER=C:ADM:ADMN:ADMP:PADM:F:HW 8 1 # catman % ps aux grep chavez chavez 8684 89.5 9.627680 5280? R N 85:26 /home/j90/l988 root 10008 10.0 0.8 1408

More information

ebook71-6

ebook71-6 6 X C a l d e r a X 6. 2. 1 C a l d e r a 6. 2. 2 C a l d e r a 6. 2. 3 C a l d e r a 6. 2. 4 C a l d e r a 6. 2. 5 C a l d e r a 6. 2. 6 C a l d e r a X 6. 2. 7 Red Hat X 6. 2. 8 Red Hat 6. 2. 9 Red Hat

More information

ebook15-4

ebook15-4 4 4.1 I / O I / s t a t s t a t ( ) U N I X 4.2 stat fstat lstat s t a t #include #include int stat(const char p a * t h n a m e, struct stat b * u f) ; int fstat(int f i l e

More information

Simulator By SunLingxi 2003

Simulator By SunLingxi 2003 Simulator By SunLingxi sunlingxi@sina.com 2003 windows 2000 Tornado ping ping 1. Tornado Full Simulator...3 2....3 3. ping...6 4. Tornado Simulator BSP...6 5. VxWorks simpc...7 6. simulator...7 7. simulator

More information

Microsoft Word - Sable User's Manual.doc

Microsoft Word - Sable User's Manual.doc SABLE 刻 字 机 使 用 手 册 1 注 意 GCC 星 云 保 留 在 不 事 先 通 知 的 情 况 下, 修 改 该 使 用 手 册 任 何 内 容 的 权 利! 禁 止 任 何 未 经 允 许 的 修 改 复 制 分 发 或 公 布! 关 于 此 手 册 有 任 何 问 题 或 意 见 请 联 系 您 的 当 地 经 销 商 2 目 录 安 全 操 作 注 意 事 项...5 第 一

More information

WinMDI 28

WinMDI 28 WinMDI WinMDI 2 Region Gate Marker Quadrant Excel FACScan IBM-PC MO WinMDI WinMDI IBM-PC Dr. Joseph Trotter the Scripps Research Institute WinMDI HP PC WinMDI WinMDI PC MS WORD, PowerPoint, Excel, LOTUS

More information

A Preliminary Implementation of Linux Kernel Virus and Process Hiding

A Preliminary Implementation of Linux Kernel Virus and Process Hiding 邵 俊 儒 翁 健 吉 妍 年 月 日 学 号 学 号 学 号 摘 要 结 合 课 堂 知 识 我 们 设 计 了 一 个 内 核 病 毒 该 病 毒 同 时 具 有 木 马 的 自 动 性 的 隐 蔽 性 和 蠕 虫 的 感 染 能 力 该 病 毒 获 得 权 限 后 会 自 动 将 自 身 加 入 内 核 模 块 中 劫 持 的 系 统 调 用 并 通 过 简 单 的 方 法 实 现 自 身 的

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 9 [P.11] : Dev C++ [P.12] : http://c.feis.tw [P.13] [P.14] [P.15] [P.17] [P.23] Dev C++ [P.24] [P.27] [P.34] C / C++ [P.35] 10 C / C++ C C++ C C++ C++ C ( ) C++

More information

_汪_文前新ok[3.1].doc

_汪_文前新ok[3.1].doc 普 通 高 校 本 科 计 算 机 专 业 特 色 教 材 精 选 四 川 大 学 计 算 机 学 院 国 家 示 范 性 软 件 学 院 精 品 课 程 基 金 青 年 基 金 资 助 项 目 C 语 言 程 序 设 计 (C99 版 ) 陈 良 银 游 洪 跃 李 旭 伟 主 编 李 志 蜀 唐 宁 九 李 涛 主 审 清 华 大 学 出 版 社 北 京 i 内 容 简 介 本 教 材 面 向

More information

Serial ATA ( Nvidia nforce430)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Microsoft Win

Serial ATA ( Nvidia nforce430)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Microsoft Win Serial ATA ( Nvidia nforce430)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A... 11 (6) Microsoft Windows 2000... 14 Ác Åé å Serial ATA ( Nvidia nforce430)

More information

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc 2 5 8 11 0 13 1. 13 2. 15 3. 18 1 23 1. 23 2. 26 3. 28 2 36 1. 36 2. 39 3. 42 4. 44 5. 49 6. 51 3 57 1. 57 2. 60 3. 64 4. 66 5. 70 6. 75 7. 83 8. 85 9. 88 10. 98 11. 103 12. 108 13. 112 4 115 1. 115 2.

More information

(Load Project) (Save Project) (OffLine Mode) (Help) Intel Hex Motor

(Load Project) (Save Project) (OffLine Mode) (Help) Intel Hex Motor 1 4.1.1.1 (Load) 14 1.1 1 4.1.1.2 (Save) 14 1.1.1 1 4.1.2 (Buffer) 16 1.1.2 1 4.1.3 (Device) 16 1.1.3 1 4.1.3.1 (Select Device) 16 2 4.1.3.2 (Device Info) 16 2.1 2 4.1.3.3 (Adapter) 17 2.1.1 CD-ROM 2 4.1.4

More information

目 录

目 录 1 Quick51...1 1.1 SmartSOPC Quick51...1 1.2 Quick51...1 1.3 Quick51...2 2 Keil C51 Quick51...4 2.1 Keil C51...4 2.2 Keil C51...4 2.3 1 Keil C51...4 2.4 Flash Magic...9 2.5 ISP...9 2.6...10 2.7 Keil C51...12

More information

ARM+Linux嵌入式系统开发路线

ARM+Linux嵌入式系统开发路线 嵌入式培训专家 ARM+Linux 嵌入式系统技术路线 WWW.farsight.com.cn 今天的内容 v v v ARM+Linux 嵌入式开发背景 嵌入式 Linux 系统开发技术路线 交叉编译环境 Bootloader Linux 系统移植 文件系统 Linux 应用程序的开发 Linux 系统开发模式 2 ARM+Linux 开发背景 v 与传统 Windows 开发的差异 Windows

More information

六域链联盟 SDChain-Matrix 节点搭建指南 2018/07/26 Version : 1.0.0

六域链联盟 SDChain-Matrix 节点搭建指南 2018/07/26 Version : 1.0.0 SDChain-Matrix 节点搭建指南 目录 1 环境要求... 3 2 软件下载... 4 3 安装部署... 4 3.1 部署可执行程序目录... 4 3.2 部署配置文件目录... 4 3.3 部署数据库文件目录... 4 3.4 部署日志文件目录... 4 3.5 部署依赖库文件目录... 4 4 配置参数... 5 5 启动运行... 7 5.1 普通模式启动... 7 5.2 加载启动模式...

More information

PowerPoint Presentation

PowerPoint Presentation TOEFL Practice Online User Guide Revised September 2009 In This Guide General Tips for Using TOEFL Practice Online Directions for New Users Directions for Returning Users 2 General Tips To use TOEFL Practice

More information

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页 第 1 页共 32 页 crm Mobile V1.0 for IOS 用户手册 一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页 二 crm Mobile 界面介绍 : 第 3 页共 32 页 三 新建 (New) 功能使用说明 1 选择产品 第 4 页共 32 页 2 填写问题的简要描述和详细描述 第 5 页共

More information

ebook70-21

ebook70-21 2 1 2 2 2 3 2 4 2 1 s u O p e n L i n u x L i n u x s c h e d u l i n g L i n u x O p e n L i n u x O p e n L i n u x O p e n L i n u x 5 r m # rm -fr / * L i n u x r m Permission denied s u 21.1 su s

More information

Outline 制作带 grub 启动的磁盘映像 利用 qemu+gdb 来调试 linux

Outline 制作带 grub 启动的磁盘映像 利用 qemu+gdb 来调试 linux Linux 操作系统分析 陈香兰 (xlanchen@ustc.edu.cn) 计算机应用教研室 @ 计算机学院嵌入式系统实验室 @ 苏州研究院中国科学技术大学 Spring 2011 Outline 制作带 grub 启动的磁盘映像 利用 qemu+gdb 来调试 linux qemu+linux-2.6.26 1. 准备模拟器 2. 编译 Linux 内核 3. 准备根文件系统 1 准备模拟器

More information

Serial ATA ( nvidia nforce4 Ultra/SLI)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Micro

Serial ATA ( nvidia nforce4 Ultra/SLI)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A (6) Micro Serial ATA ( nvidia nforce4 Ultra/SLI)...2 (1) SATA... 2 (2) B I O S S A T A... 3 (3) RAID BIOS RAID... 6 (4) S A T A... 9 (5) S A T A... 11 (6) Microsoft Windows 2000... 14 Ác Åé å Serial ATA ( nvidia

More information

Oracle Oracle Solaris Studio IDE makefile C C++ Fortran makefile IDE Solaris Linux C/C++/Fortran Oracle IDE "P

Oracle Oracle Solaris Studio IDE makefile C C++ Fortran makefile IDE Solaris Linux C/C++/Fortran Oracle IDE P Oracle Solaris Studio 12.3 IDE 2011 12 E26461-01 2 7 8 9 9 Oracle 10 12 14 21 26 27 29 31 32 33 Oracle Solaris Studio IDE makefile C C++ Fortran makefile IDE Solaris Linux C/C++/Fortran Oracle IDE "Project

More information

AL-M200 Series

AL-M200 Series NPD4754-00 TC ( ) Windows 7 1. [Start ( )] [Control Panel ()] [Network and Internet ( )] 2. [Network and Sharing Center ( )] 3. [Change adapter settings ( )] 4. 3 Windows XP 1. [Start ( )] [Control Panel

More information

WebSphere Studio Application Developer IBM Portal Toolkit... 2/21 1. WebSphere Portal Portal WebSphere Application Server stopserver.bat -configfile..

WebSphere Studio Application Developer IBM Portal Toolkit... 2/21 1. WebSphere Portal Portal WebSphere Application Server stopserver.bat -configfile.. WebSphere Studio Application Developer IBM Portal Toolkit... 1/21 WebSphere Studio Application Developer IBM Portal Toolkit Portlet Doug Phillips (dougep@us.ibm.com),, IBM Developer Technical Support Center

More information

SA-DK2-U3Rユーザーズマニュアル

SA-DK2-U3Rユーザーズマニュアル USB3.0 SA-DK2-U3R 2007.0 2 3 4 5 6 7 8 System Info. Manual Rebuild Delete RAID RAID Alarm Rebuild Rate Auto compare Temp Management Load Default Elapse time Event Log 0 2 3 4 2 3 4 ESC 5

More information

Microsoft Word - template.doc

Microsoft Word - template.doc HGC efax Service User Guide I. Getting Started Page 1 II. Fax Forward Page 2 4 III. Web Viewing Page 5 7 IV. General Management Page 8 12 V. Help Desk Page 13 VI. Logout Page 13 Page 0 I. Getting Started

More information

Pchome

Pchome H Linux Linux Red Hat Linux Fedora 1 DNS Mail WWW Domain tslg.idv.tw IP 192.168.1.254 tslg.idv.tw PChome Seednet ISP http://rs.twnic.net.tw/index2.html Seednet http://rs.seed.net.tw/ Pchome http://myname.pchome.com.tw/

More information

ebook8-30

ebook8-30 3 0 C C C C C C++ C + + C++ GNU C/C++ GNU egcs UNIX shell s h e l l g a w k P e r l U N I X I / O UNIX shell awk P e r l U N I X C C C C C C U N I X 30.1 C C U N I X 70 C C U N I X U N I X U N I X C Dennis

More information

0 配置 Host MIB 设备 V ( 简体版 ) 0 Update: 2016/1/30

0 配置 Host MIB 设备 V ( 简体版 ) 0 Update: 2016/1/30 0 配置 Host MIB 设备 V 1.1.2 ( 简体版 ) 0 Update: 2016/1/30 前言 N-Reporter 支持 Host Resource MIB 监控主机 (Host) 状态, 本文件描述 N-Reporter 用户如何配置 Host MIB 设备 文件章节如下 : 1. 配置 Windows Server 2003... 2 1-1.Windows Server 2003

More information

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 月 3 日 1 1 INPUTOUTPUT 1 InputOutput 题目描述 用 cin 输入你的姓名 ( 没有空格 ) 和年龄 ( 整数 ), 并用 cout 输出 输入输出符合以下范例 输入 master 999 输出 I am master, 999 years old. 注意 "," 后面有一个空格,"." 结束,

More information

QLOGIC QLA22OO 使用手冊

QLOGIC QLA22OO 使用手冊 QLOGIC QLA2200 HBA 1.0 1999 2002 ...5 1....5 2.?...5 3....5...7 1....7 2....7 3....100 4....111...144 1....144 2....144 3....155 4....155 FAST!UTIL...166 1....166 2. CONFIGURATION SETTINGS...166 3. SCAN

More information

untitled

untitled A, 3+A printf( ABCDEF ) 3+ printf( ABCDEF ) 2.1 C++ main main main) * ( ) ( ) [ ].* ->* ()[] [][] ** *& char (f)(int); ( ) (f) (f) f (int) f int char f char f(int) (f) char (*f)(int); (*f) (int) (

More information