关于作者

用户名:温英林
笔名:Daemon
地区: 广东-广州
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



Linux驱动开发

软件=程序+文档

访问统计:
文章个数:23
评论个数:9
留言条数:2




Powered by BlogDriver 2.1

以静致远

 

Welcome to SpiritDance's Blog!

文章

如果你是火柴人,你会怎么做呢?
摘要:宽恕,包容也应该有限度啊。。。但真正面对的时候,又有谁还会去计较那么多呢? 查看全文

- 作者: Daemon 2006年01月13日, 星期五 12:55  回复(1) |  引用(0) 加入博采

苏幕遮·范仲淹
摘要:碧云天,黄叶地 查看全文

- 作者: Daemon 2005年12月4日, 星期日 17:09  回复(2) |  引用(0) 加入博采

柏拉图对爱与婚姻的启示
摘要:人生就正如穿越麦田和树林,只走一次,不能回头。 查看全文

- 作者: 温英林 2005年06月6日, 星期一 13:50  回复(0) |  引用(0) 加入博采

鹊桥仙
                                          鹊桥仙
                                           秦观
纤云弄巧,飞星传恨,银汉迢迢暗度。金风玉露一相逢,便胜却人间无数。
柔情似水,佳期如梦,忍顾鹊桥归路,两情若是久长时,又岂在朝朝暮暮。

- 作者: 温英林 2005年04月20日, 星期三 00:40  回复(0) |  引用(0) 加入博采

蝶恋花

                                              蝶恋花
                                                苏轼
花褪残红青杏小。燕子飞时,绿水人家绕。枝上柳绵吹又少,天涯何处无芳草!
墙里秋千墙外道。墙外行人,墙里佳人笑。笑渐不闻声渐悄,多情却被无情恼。


- 作者: 温英林 2005年04月20日, 星期三 00:36  回复(0) |  引用(0) 加入博采

忆江南
江南好,风景旧曾谙:日出江花红胜火,春来江水绿如蓝。能不忆江南?
江南忆,最忆是杭州:山寺月中寻桂子,郡亭枕上看潮头。何日更重游?
江南忆,其次忆吴宫:吴酒一杯春竹叶,吴娃双舞醉芙蓉。早晚复相逢。

- 作者: 温英林 2005年04月20日, 星期三 00:32  回复(2) |  引用(0) 加入博采

可以用spca5xx驱动的摄像头芯片(Linux)
spca5xx-20050319.tar.gz自带的说明文件...

Currently, the following cameras are supported by this driver:

 Vendor ID Device ID Support Summary --------- --------- ---------------

{USB_DEVICE (0x0733, 0x0430)}, /* Intel PC Camera Pro */

{USB_DEVICE (0x0733, 0x0401)}, /* Intel Create and Share */

{USB_DEVICE (0x99FA, 0x8988)}, /* Grandtec V.cap */

{USB_DEVICE (0x0733, 0x0402)}, /* ViewQuest M318B */

{USB_DEVICE (0x0733, 0x0110)}, /* ViewQuest VQ110 */

{USB_DEVICE (0x040A, 0x0002)}, /* Kodak DVC-325 */

 {USB_DEVICE (0x055f, 0xc420)}, /* Mustek gSmart Mini 2 */

{USB_DEVICE (0x055f, 0xc520)}, /* Mustek gSmart Mini 3 */

{USB_DEVICE (0x041E, 0x400A)}, /* Creative PC-CAM 300 */

{USB_DEVICE (0x084D, 0x0003)}, /* D-Link DSC-350 */

 {USB_DEVICE (0x041E, 0x400B)}, /* Creative PC-CAM 600 */

 {USB_DEVICE (0x8086, 0x0630)}, /* Intel Pocket PC Camera */

{USB_DEVICE (0x8086, 0x0110)}, /* Intel Easy PC Camera */

{USB_DEVICE (0x0506, 0x00df)}, /* 3Com HomeConnect Lite */

{USB_DEVICE (0x040a, 0x0300)}, /* Kodak EZ200 */

{USB_DEVICE (0x04fc, 0x504b)}, /* Maxell MaxPocket LE 1.3 */

 {USB_DEVICE (0x08ca, 0x2008)}, /* Aiptek Mini PenCam 2 M */

{USB_DEVICE (0x08ca, 0x0104)}, /* Aiptek PocketDVII 1.3 */

{USB_DEVICE (0x08ca, 0x2018)}, /* Aiptek Pencam SD 2M */

{USB_DEVICE (0x04fc, 0x504a)}, /* Aiptek Mini PenCam 1.3 */

{USB_DEVICE (0x055f, 0xc530)}, /* Mustek Gsmart LCD 3 */

 {USB_DEVICE (0x055f, 0xc650)}, /* Mustek MDC5500Z */

{USB_DEVICE (0x052b, 0x1513)}, /* Megapix V4 */

 {USB_DEVICE (0x08ca, 0x0103)}, /* Aiptek PocketDV */

{USB_DEVICE (0x0af9, 0x0010)}, /* Hama USB Sightcam 100 */

 {USB_DEVICE (0x1776, 0x501c)}, /* Arowana 300K CMOS Camera */

{USB_DEVICE (0x08ca, 0x0106)}, /* Aiptek Pocket DV3100+ */

{USB_DEVICE (0x08ca, 0x2010)}, /* Aiptek PocketCam 3M */

{USB_DEVICE (0x0458, 0x7004)}, /* Genius VideoCAM Express V2 */

{USB_DEVICE (0x04fc, 0x0561)}, /* Flexcam 100 */

 {USB_DEVICE (0x055f, 0xc430)}, /* Mustek Gsmart LCD 2 */

{USB_DEVICE (0x04fc, 0xffff)}, /* Pure DigitalDakota */

{USB_DEVICE (0xabcd, 0xcdee)}, /* Petcam */

 {USB_DEVICE (0x04a5, 0x3008)}, /* Benq DC 1500 */

{USB_DEVICE (0x046d, 0x0960)}, /* Logitech Inc. ClickSmart 420 */

{USB_DEVICE (0x046d, 0x0901)}, /* Logitech Inc. ClickSmart 510 */

{USB_DEVICE (0x04a5, 0x3003)}, /* Benq DC 1300 */

{USB_DEVICE (0x0af9, 0x0011)}, /* Hama USB Sightcam 100 */

{USB_DEVICE (0x055f, 0xc440)}, /* Mustek DV 3000 */

{USB_DEVICE (0x041e, 0x4013)}, /* Creative Pccam750 */

{USB_DEVICE (0x060b, 0xa001)}, /* Maxell Compact Pc PM3 */

{USB_DEVICE (0x04a5, 0x300a)}, /* Benq DC3410 */

{USB_DEVICE (0x04a5, 0x300c)}, /* Benq DC1016 */

{USB_DEVICE (0x0461, 0x0815)}, /* Micro Innovation IC200 */

 {USB_DEVICE (0x046d, 0x0890)}, /* Logitech QuickCam traveler */

 {USB_DEVICE (0x10fd, 0x7e50)}, /* FlyCam Usb 100 */

{USB_DEVICE (0x06e1, 0xa190)}, /* ADS Instant VCD */

{USB_DEVICE (0x055f, 0xc220)}, /* Gsmart Mini */

 {USB_DEVICE (0x0733, 0x2211)}, /* Jenoptik jdc 21 LCD */

 {USB_DEVICE (0x046d, 0x0900)}, /* Logitech Inc. ClickSmart 310 */

 {USB_DEVICE (0x055f, 0xc360)}, /* Mustek DV4000 Mpeg4 */

{USB_DEVICE (0x08ca, 0x2024)}, /* Aiptek DV3500 Mpeg4 */

{USB_DEVICE (0x046d, 0x0905)}, /* Logitech ClickSmart820 */

{USB_DEVICE (0x05da, 0x1018)}, /* Digital Dream Enigma 1.3 */

 {USB_DEVICE (0x0c45, 0x6025)}, /* Xcam Shanga */

 {USB_DEVICE (0x0733, 0x1311)}, /* Digital Dream Epsilon 1.3 */

{USB_DEVICE (0x041e, 0x401d)}, /* Creative Webcam NX ULTRA */

{USB_DEVICE (0x08ca, 0x2016)}, /* Aiptek PocketCam 2 Mega */

{USB_DEVICE (0x0734, 0x043b)}, /* 3DeMon USB Capture aka */

 {USB_DEVICE (0x041E, 0x4018)}, /* Creative Webcam Vista (PD1100) */

 {USB_DEVICE (0x0546, 0x3273)}, /* Polaroid PDC2030*/

 {USB_DEVICE (0x041e, 0x401f)}, /* Creative Webcam Notebook PD1171*/

{USB_DEVICE (0x041e, 0x4017)}, /* Creative Webcam Mobile PD1090*/

{USB_DEVICE (0x046d, 0x08a2)}, /* Labtec Webcam Pro*/

 {USB_DEVICE (0x055f, 0xd003)}, /* Mustek WCam300A*/

{USB_DEVICE (0x0458, 0x7007)}, /* Genius VideoCam V2*/

 {USB_DEVICE (0x0458, 0x700c)}, /* Genius VideoCam V3*/

{USB_DEVICE (0x0458, 0x700f)}, /* Genius VideoCam Web V2*/

{USB_DEVICE (0x041e, 0x401e)}, /* Creative Nx Pro*/

{USB_DEVICE (0x0c45, 0x6029)}, /* spcaCam@150 */

{USB_DEVICE (0x0c45, 0x6009)}, /* spcaCam@120 */

{USB_DEVICE (0x0c45, 0x600d)}, /* spcaCam@120 */

 {USB_DEVICE (0x04fc, 0x5330)}, /* Digitrex 2110*/

{USB_DEVICE (0x055f, 0xc540)}, /* Gsmart D30*/

{USB_DEVICE (0x0ac8, 0x301b)}, /* Asam Vimicro*/

 {USB_DEVICE (0x041e, 0x403a)}, /* Creative Nx Pro 2*/

 {USB_DEVICE (0x055f, 0xc211)}, /* Kowa Bs888e Microcamera*/

{USB_DEVICE (0x0ac8, 0x0302)}, /* Z-star Vimicro zc0302*/

 {USB_DEVICE (0x0572, 0x0041)}, /* Creative Notebook cx11646*/

 {USB_DEVICE (0x08ca, 0x2022)}, /* Aiptek Slim 3200*/

{USB_DEVICE (0x046d, 0x0921)}, /* Labtec Webcam */

 {USB_DEVICE (0x046d, 0x0920)}, /* QC Express */

 {USB_DEVICE (0x0923, 0x010f)}, /* ICM532 cams */

{USB_DEVICE (0x055f, 0xc200)}, /* Mustek Gsmart 300 */

 {USB_DEVICE (0x0733, 0x2221)}, /* Mercury Digital Pro 3.1p*/

{USB_DEVICE (0x041e, 0x4036)}, /* Creative Live ! */

{USB_DEVICE (0x055f, 0xc005)}, /* Mustek Wcam300A */

{USB_DEVICE (0x041E, 0x403b)}, /* Creative Webcam Vista (VF0010) */

{USB_DEVICE (0x0545, 0x8333)}, /* Veo Stingray */

{USB_DEVICE (0x0545, 0x808b)}, /* Veo Stingray */

{USB_DEVICE (0x10fd, 0x8050)}, /* Typhoon Webshot II USB 300k */

{USB_DEVICE (0x0000, 0x0000)}, /* MystFromOri Unknow Camera */

 This list represents those cameras that are specifically supported by the driver,

and should work to some degree 'out of the box'.

A full list of the cameras known to the project maintainers can be found on the project website

 

 

- 作者: 温英林 2005年04月3日, 星期日 12:14  回复(1) |  引用(0) 加入博采

uClinux简介
介绍ucLinux的一些基本情况,包括:小型化的方法、内存管理、
开发环境、多进程等。
-----------------------------------------------------------

uClinux小型化的做法
uClinux就是Micro-Control-Linux,字面上的理解就是"针对微控制领域而设计的Linux系统"。

标准Linux可能采用的小型化方法
1. 重新编译内核
Linux内核采用模块化的设计,内核模块作为可选的选项,在编译系统内核时指定。因此一种较通用的做法是对Linux内核重新编译,在编译时仔细的选择嵌入式设备所需要的功能支持模块,同时删除不需要的功能。通过对内核的重新配置,可以使系统运行所需要的内核显著减小,从而缩减资源使用量。
2. 制作root文件系统映象
Linux系统在启动时必须加载根(root)文件系统,因此剪裁系统同时包括root文件系统的剪裁。在x86系统下,Linux可以在Dos下,使用Loadlin文件加载启动。

uClinux采用的小型化方法
1.uClinux的内核加载方式
uClinux的内核有两种可选的运行方式:可以在flash上直接运行,也可以加载到内存中运行。这种做法可以减少内存需要。
Flash运行方式:把内核的可执行映像烧写到flash上,系统启动时从flash的某个地址开始逐句执行。这种方法实际上是很多嵌入式系统采用的方法。
内核加载方式:把内核的压缩文件存放在flash上,系统启动时读取压缩文件在内存里解压,然后开始执行,这种方式相对复杂一些,但是运行速度可能更快(ram的存取速率要比flash高)。同时这也是标准Linux系统采用的启动方式。

2.uClinux的根(root)文件系统
uClinux系统采用romfs文件系统,相对于ext2文件系统要求更少的空间。空间的节省首先来自内核支持romfs文件系统需要更少的代码,其次romfs文件系统相对简单,建立文件系统超级块(superblock)需要更少的存储空间。Romfs文件系统不支持动态擦写保存,对于需要动态保存的数据采用虚拟ram盘的方法进行处理(ram盘采用ext2文件系统)。

3.uClinux的应用程序库
uClinux小型化的另一个做法是重写了应用程序库,相对于越来越大且越来越全的glibc库,uClibc对libc做了精简。
uClinux对用户程序采用静态连接的形式,这种做法会使应用程序变大,但是基于内存管理的问题,不得不这样做。

uClinux的开发环境

GNU开发套件
Gnu开发套件包括一系列的开发调试工具。主要组件:
Gcc: 编译器,可做成交叉编译的形式,即在宿主机上开发编译目标上可运行的二进制文件。
Binutils:一些辅助工具,包括objdump(可以反编译二进制文件),as(汇编编译器),ld(连接器)等等。
Gdb:调试器,可使用多种交叉调试方式,gdb-bdm(背景调试工具),gdbserver(使用以太网络调试)。

uClinux的打印终端
uClinux的默认终端通常是串口,内核启动时所有的信息都打印到串口终端(使用printk函数打印),同时也可以通过串口终端与系统交互。
uClinux在启动时启动了telnetd(远程登录服务)。至于是否允许远程登录可以通过烧写romfs文件系统时由用户决定。

交叉编译调试工具
支持一种新的处理器,必须具备一些编译,汇编工具,使用这些工具可以形成可运行于这种处理器的二进制文件。对于内核使用的编译工具同应用程序使用的有所不同。在解释不同点之前,需要对gcc连接做一些说明:
.ld(link description)文件:ld文件是指出连接时内存映象格式的文件。
crt0.S:应用程序编译连接时需要的启动文件,主要是初始化应用程序栈。
pic:position independence code ,与位置无关的二进制格式文件,在程序段中必须包括reloc段,从而使的代码加载时可以进行重新定位。

内核编译连接时,使用ucsimm.ld文件,形成可执行文件映像,所形成的代码段既可以使用间接寻址方式(即使用reloc段进行寻址),也可以使用绝对寻址方式。这样可以给编译器更多的优化空间。因为内核可能使用绝对寻址,所以内核加载到的内存地址空间必须与ld文件中给定的内存空间完全相同。
应用程序的连接与内核连接方式不同。应用程序由内核加载(可执行文件加载器将在后面讨论),由于应用程序的ld文件给出的内存空间与应用程序实际被加载的内存位置可能不同,在应用程序加载的过程中需要一个重新定位的过程,即对reloc段进行修正,使得程序进行间接寻址时不至于出错。(这个问题在i386等高级处理器上方法有所不同,本文将在后面进一步分析)。
由上述讨论,至少需要两套编译连接工具。在讨论过uClinux的内存管理后本文将给出整个系统的工作流程以及系统在flash和ram中的空间分布。

uClinux的内存管理
uClinux同标准Linux的最大区别就在于内存管理,由于uClinux的内存管理引发了一些标准Linux所不会出现的问题。本文将把uClinux内存管理同标准Linux的那内存管理部分进行比较分析。

标准Linux使用的虚拟存储器技术
标准Linux使用虚拟存储器技术,提供比计算机系统中实际使用的物理内存大得多的内存空间,从而使得编程人员在不用考虑计算机中的物理内存容量。
为了支持虚拟存储管理器的管理,Linux系统采用分页(paging)的方式来载入进程。所谓分页既是把实际的存储器分割为相同大小的段,例如每个段1024个字节,这样1024个字节大小的段便称为一个页面(page)。
虚拟存储器由存储器管理机制及一个大容量的快速硬盘存储器支持。它的实现基于局部性原理,当一个程序在运行之前,没有必要全部装入内存,而是仅将那些当前要运行的那些部分页面或段装入内存运行(copy-on-write),其余暂时留在硬盘上程序运行时如果它所要访问的页(段)已存在,则程序继续运行,如果发现不存在的页(段),操作系统将产生一个页错误(page fault),这个错误导致操作系统把需要运行的部分加载到内存中。必要时操作系统还可以把不需要的内存页(段)交换到磁盘上。利用这样的方式管理存储器,便可把一个进程所需要用到的存储器以化整为零的方式,视需求分批载入,而核心程序则凭借属于每个页面的页码来完成寻址各个存储器区段的工作。
标准Linux是针对有内存管理单元的处理器设计的。在这种处理器上,虚拟地址被送到内存管理单元(MMU),把虚拟地址映射为物理地址。
通过赋予每个任务不同的虚拟--物理地址转换映射,支持不同任务之间的保护。地址转换函数在每一个任务中定义,在一个任务中的虚拟地址空间映射到物理内存的一个部分,而另一个任务的虚拟地址空间映射到物理存储器中的另外区域。计算机的存储管理单元(MMU)一般有一组寄存器来标识当前运行的进程的转换表。在当前进程将CPU放弃给另一个进程时(一次上下文切换),内核通过指向新进程地址转换表的指针加载这些寄存器。MMU寄存器是有特权的,只能在内核态才能访问。这就保证了一个进程只能访问自己用户空间内的地址,而不会访问和修改其它进程的空间。当可执行文件被加载时,加载器根据缺省的ld文件,把程序加载到虚拟内存的一个空间,因为这个原因实际上很多程序的虚拟地址空间是相同的,但是由于转换函数不同,所以实际所处的内存区域也不同。而对于多进程管理当处理器进行进程切换并执行一个新任务时,一个重要部分就是为新任务切换任务转换表。我们可以看到Linux系统的内存管理至少实现了以下功能:
运行比内存还要大的程序。理想情况下应该可以运行任意大小的程序
◇可以运行只加载了部分的程序,缩短了程序启动的时间
◇可以使多个程序同时驻留在内存中提高CPU的利用率
◇可以运行重定位程序。即程序可以方于内存中的任何一处,而且可以在执行过程中移动。
◇写机器无关的代码。程序不必事先约定机器的配置情况。
◇减轻程序员分配和管理内存资源的负担。
◇可以进行共享--例如,如果两个进程运行同一个程序,它们应该可以共享程序代码的同一个副本。
◇提供内存保护,进程不能以非授权方式访问或修改页面,内核保护单个进程的数据和代码以防止其它进程修改它们。否则,用户程序可能会偶然(或恶意)的破坏内核或其它用户程序。
虚存系统并不是没有代价的。内存管理需要地址转换表和其他一些数据结构,留给程序的内存减少了。地址转换增加了每一条指令的执行时间,而对于有额外内存操作的指令会更严重。当进程访问不在内存的页面时,系统发生失效。系统处理该失效,并将页面加载到内存中,这需要极耗时间的磁盘I/O操作。总之内存管理活动占用了相当一部分cpu时间(在较忙的系统中大约占10%)。

uClinux针对NOMMU的特殊处理
对于uClinux来说,其设计针对没有MMU的处理器,即uClinux不能使用处理器的虚拟内存管理技术。uClinux仍然采用存储器的分页管理,系统在启动时把实际存储器进行分页。在加载应用程序时程序分页加载。但是由于没有MMU管理,所以实际上uClinux采用实存储器管理策略(real memeory management)。这一点影响了系统工作的很多方面。
uClinux系统对于内存的访问是直接的(它对地址的访问不需要经过MMU,而是直接送到地址线上输出),所有程序中访问的地址都是实际的物理地址。操作系统对内存空间没有保护(这实际上是很多嵌入式系统的特点),各个进程实际上共享一个运行空间(没有独立的地址转换表)。
一个进程在执行前,系统必须为进程分配足够的连续地址空间,然后全部载入主存储器的连续空间中。标准Linux系统在分配内存时只要保证虚存地址空间连续就可以了。另外一个方面程序加载地址与预期(ld文件中指出的)通常都不相同,这样relocation过程就是必须的。此外磁盘交换空间也是无法使用的,系统执行时如果缺少内存将无法通过磁盘交换来得到改善。
从易用性这一点来说,uClinux的内存管理是一种倒退,退回了到了UNIX早期或是Dos系统时代。开发人员不得不参与系统的内存管理。从编译内核开始,开发人员必须告诉系统这块开发板到底拥有多少的内存,从而系统将在启动的初始化阶段对内存进行分页,并且标记已使用的和未使用的内存。系统将在运行应用时使用这些分页内存。
由于应用程序加载时必须分配连续的地址空间,而针对不同硬件平台的可一次成块(连续地址)分配内存大小限制是不同(目前针对ez328处理器的uClinux是128k,而针对coldfire处理器的系统内存则无此限制),所以开发人员在开发应用程序时必须考虑内存的分配情况并关注应用程序需要运行空间的大小。另外由于采用实存储器管理策略,用户程序同内核以及其它用户程序在一个地址空间,程序开发时要保证不侵犯其它程序的地址空间,以使得程序不至于破坏系统的正常工作,或导致其它程序的运行异常。
从内存的访问角度来看,开发人员的权利增大了(开发人员在编程时可以访问任意的地址空间),但与此同时系统的安全性也大为下降。此外,系统对多进程的管理将有很大的变化,这一点将在uClinux的多进程管理中说明。
虽然uClinux的内存管理与标准Linux系统相比功能相差很多,但应该说这是嵌入式设备的选择。在嵌入式设备中,由于成本等敏感因素的影响,普偏的采用不带有MMU的处理器,这决定了系统没有足够的硬件支持实现虚拟存储管理技术。从嵌入式设备实现的功能来看,嵌入式设备通常在某一特定的环境下运行,只要实现特定的功能,其功能相对简单,内存管理的要求完全可以由开发人员考虑。

标准Linux系统的进程、线程

进程:进程是一个运行程序并为其提供执行环境的实体,它包括一个地址空间和至少一个控制点,进程在这个地址空间上执行单一指令序列。进程地址空间包括可以访问或引用的内存单元的集合,进程控制点通过一个一般称为程序计数器(program counter,PC)的硬件寄存器控制和跟踪进程指令序列。

fork:由于进程为执行程序的环境,因此在执行程序前必须先建立这个能"跑"程序的环境。Linux系统提供系统调用拷贝现行进程的内容,以产生新的进程,调用fork的进程称为父进程;而所产生的新进程则称为子进程。子进程会承袭父进程的一切特性,但是它有自己的数据段,也就是说,尽管子进程改变了所属的变量,却不会影响到父进程的变量值。

父进程和子进程共享一个程序段,但是各自拥有自己的堆栈、数据段、用户空间以及进程控制块。换言之,两个进程执行的程序代码是一样的,但是各有各的程序计数器与自己的私人数据。

当内核收到fork请求时,它会先查核三件事:首先检查存储器是不是足够;其次是进程表是否仍有空缺;最后则是看看用户是否建立了太多的子进程。如果上述说三个条件满足,那么操作系统会给子进程一个进程识别码,并且设定cpu时间,接着设定与父进程共享的段,同时将父进程的inode拷贝一份给子进程运用,最终子进程会返回数值0以表示它是子进程,至于父进程,它可能等待子进程的执行结束,或与子进程各做个的。

exec系统调用:该系统调用提供一个进程去执行另一个进程的能力,exec系统调用是采用覆盖旧有进程存储器内容的方式,所以原来程序的堆栈、数据段与程序段都会被修改,只有用户区维持不变。

vfork系统调用:由于在使用fork时,内核会将父进程拷贝一份给子进程,但是这样的做法相当浪费时间,因为大多数的情形都是程序在调用fork后就立即调用exec,这样刚拷贝来的进程区域又立即被新的数据覆盖掉。因此Linux系统提供一个系统调用vfork,vfork假定系统在调用完成vfork后会马上执行exec,因此vfork不拷贝父进程的页面,只是初始化私有的数据结构与准备足够的分页表。这样实际在vfork调用完成后父子进程事实上共享同一块存储器(在子进程调用exec或是exit之前),因此子进程可以更改父进程的数据及堆栈信息,因此vfork系统调用完成后,父进程进入睡眠,直到子进程执行exec。当子进程执行exec时,由于exec要使用被执行程序的数据,代码覆盖子进程的存储区域,这样将产生写保护错误(do_wp_page)(这个时候子进程写的实际上是父进程的存储区域),这个错误导致内核为子进程重新分配存储空间。当子进程正确开始执行后,将唤醒父进程,使得父进程继续往后执行。

uClinux的多进程处理

uClinux没有mmu管理存储器,在实现多个进程时(fork调用生成子进程)需要实现数据保护。

uClinux的fork和vfork:uClinux的fork等于vfork。实际上uClinux的多进程管理通过vfork来实现。这意味着uClinux系统fork调用完程后,要么子进程代替父进程执行(此时父进程已经sleep)直到子进程调用exit退出,要么调用exec执行一个新的进程,这个时候将产生可执行文件的加载,即使这个进程只是父进程的拷贝,这个过程也不能避免。当子进程执行exit或exec后,子进程使用wakeup把父进程唤醒,父进程继续往下执行。

uClinux的这种多进程实现机制同它的内存管理紧密相关。uClinux针对nommu处理器开发,所以被迫使用一种flat方式的内存管理模式,启动新的应用程序时系统必须为应用程序分配存储空间,并立即把应用程序加载到内存。缺少了MMU的内存重映射机制,uClinux必须在可执行文件加载阶段对可执行文件reloc处理,使得程序执行时能够直接使用物理内存。

--------------------------------------------------------------------------------------------------------------------------------------
转载自华术论坛,相关链接http://www.techincn.com/cgi-bin/topic.cgi?forum=12&topic=28&show=0

- 作者: 温英林 2005年04月3日, 星期日 01:57  回复(1) |  引用(0) 加入博采

4510 学习开发板
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together


lumit4510 学习开发板
uClinux & SkyEye 实验手册
Version 1.1
[lumit] - let us make it together
htpp://www.lumit.org
2004年11月
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together
目录
lumit4510 uClinux & SkyEye 实验手册................................................................................1
Version 1.1 ......................................................................................................1
目录..............................................................................................................2
预备知识...........................................................................................................3
第一节 ARM7开发板简介................................................................................................3
第二节 硬件部分......................................................................................................5
2.1 整体布局.......................................................................................................5
2.2 电源...........................................................................................................5
2.3 CPU模块........................................................................................................6
2.4 Nor Flash.....................................................................................................6
2.5 外围器件........................................................................................................7
2.6 SDRAM .........................................................................................................7
2.7 串口............................................................................................................7
2.8 网络............................................................................................................8
2.9 USB............................................................................................................8
2.10 Nand Flash ...................................................................................................8
2.11 LCD...........................................................................................................8
第三节 软件部分......................................................................................................9
3.1 uClinux简介....................................................................................................9
3.2 SkyEye 简介....................................................................................................10
软件实验――操作系统移植与应用程序开发.............................................................................12
实验一 在 ARM7 开发板上下载和运行uClinux 内核....................................................12
Step 1: 开发主机与开发板软硬件连接................................................................12
Step 2: 设置开发板ip地址...................................................................................12
Step 2: 准备相关文件............................................................................................13
Step 3: 设置主机 ip ..............................................................................................13
Step 4: 下载内核并执行........................................................................................14
实验二 uClinux 内核的交叉编译和 SkyEye 仿真调试....................................................23
Step 1 : 安装交叉编译器 GNU Toolchain ...........................................................23
Step 2 : 交叉编译 uClinux 内核..........................................................................23
Step 3 : 在 SkyEye 上仿真调试内核..................................................................26
实验三 添加新的 uClinux 应用程序..................................................................................31
Step 1 : 编写应用程序代码...................................................................................31
Step 2 : 修改相关 Makefile 文件........................................................................31
Step 3 : 修改相关 config.in 文件........................................................................32
Step 4 : 重新编译内核和文件系统.......................................................................32
附录 - uCLinux FAQs .............................................................................................36
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 3 -
预备知识
第一节 ARM7开发板简介
lumit4510是基于三星S3C4510的ARM7开发板,主要面向嵌入式初学者.
该开发板的外观如下:
lumit 4510开发板具有以下资源:
处理器:
S3C4510B ARM7TDMI
运行频率50MHz
存储器:
16x1M字节NOR Flash
32x4M字节SDRAM
16M字节NAND Flash
通信接口:
两个串口
一个10M/100M以太网口
一个USB 1.1 device接口
其他资源:
4个LED
一个7段数码管
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 4 -
实时时钟
拨断开关
蜂鸣器
外部中断
16x2字符型液晶接口
lumit4510开发套件包括如下部分:
1) 一块已测试好的lumit4510开发板
2) 一个JTAG调试头(带调试线)
3) 一根串口线 (公母延长线)
4) 一根并口延长线
5) 一条1.5米网线 (交叉线)
6) 一个 +5V 直流电源
7) 一张lumit4510光盘
在 lumit4510 的网站 http://www.lumit.org 上提供的嵌入式开发资料有:
1) 所用主要芯片的数据手册资料
(s3c4510/sst39vf160 /PDIUSBD12/HY57V641620/K9F2808Q0B)
2) 开发板原理图
(OrCad 格式第三版原理图和 wiggler 调试器sch和pcb图)
3) uclinux for S3C4510的源代码
(20030522 版.和20040408 版全部移植代码)
4) 支持 SkyEye 软件仿真协同开发(没有硬件的可以用 SkyEye 来学习)
5) Bootloader 源代码,支持通过网络 tftp 协议下载 uClinux 内核.
6) uC/OS-II 实时多任务操作系统内核移植源码
7) VxWorks on lumit4510 移植
8) 板子的详细使用说明(如何交叉编译,如何烧写 Flash,如何DIY焊接
等)
9) 开发工具下载
(包含 GNU 交叉编译器,ARM 公司的集成开发工具 ADS/SDT等)
lumit 开源项目正在进行的工作有:
1) 实时时钟 RTC 驱动调试
2) 液晶屏 LCD (2×16)字符驱动显示
3) 基于 Nand Flash 的文件系统移植
4) 开发板使用说明,源码分析,开发手册等相关技术文档工作
www.lumit.org 是一个软硬件资料可以完全免费下载的开源项目,目前主要
目标是制作一个基于arm7tdmi s3c4510开发板的可以实用的u盘,未来我们希望
还能做出 mp3,pda 甚至是 dc,dv 等.
关于 lumit4510 开发板更多相关资料,可以到 http://www.lumit.org 下载.
同时欢迎对此感兴趣的朋友加入!
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 5 -
第二节 硬件部分
2.1 整体布局
网络模块
电源
RTC电池
蜂鸣器
复位 JTAG液晶模块NAND Flash模块
USB
模块
串口 LED与7段数码管拨段开关实时时钟
SDRAM
S3C4510模块
外部中断
Nor Flash
2.2 电源
开发板电源分两部分:
系统电源
系统需要DC +5V和+3.3V电源,5V直接采用外接直流稳压电源,3.3V
通过5V进行DC-DC转换而来.
实时时钟电池电源
实时时钟由于要保存时钟信息,所以在掉电时采用电池供电,系统上电
时使用系统的电源供电
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 6 -
2.3 CPU模块
2.3.1 CPU
S3C4510B是三星公司基于ARM7TDMI的处理器,芯片本身具有资源如下:
ARM7TDMI核
2个UART
2个HDLC
2个GDMA
2个32位定时器
18个可编程IO
8K字节cache/SRAM
1个IIC接口
中断控制器
网络控制器
2.3.2 复位
复位电路采用IMP811芯片
2.3.3 晶振
处理器外接10MHz有源晶振,通过处理器内部PLL倍频到50MHz
2.3.4 JTAG
20针标准JTAG接口
JTAG是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真,
调试.目前大多数处理器都支持JTAG.
2.4 Nor Flash
SST39VF160 16x1M字节
Flash存储器是一种可以在线进行擦写,掉电数据不丢失的存储器.具有低
功耗,大容量等特点.主要用在存储程序代码和一些需要保存的数据.
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 7 -
2.5 外围器件
2.5.1 LED
4个LED灯PIO控制
2.5.2 七段数码管
数据总线D0-D7和一些逻辑控制的七段数码管
2.5.3 拨段开关
4位拨断开关,接至IO口
2.5.4 外部中断
外部中断按键
2.5.5 实时时钟
实时时钟PCF8563芯片,使用IIC接口
2.5.6 蜂鸣器
PIO控制蜂鸣器
2.6 SDRAM
两片K4S641632组成32位数据总线宽度
SDRAM运行速度大大快于FLASH存储器,并且单位面积存储容量大和价
格相对低廉,但是掉电数据就会丢失,所以,SDRAM主要用作程序运行空
间,数据区和堆栈区.
2.7 串口
提供两个串口
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 8 -
2.8 网络
以太网接口主要由MAC控制器和物理层接口(PHY)两部分组成,S3C4510B
自带网络控制器,外部结PHY芯片RTL8021B接入以太网
S3C4510B自带的以太网控制器可以在半双工或全双工模式下提供
10M/100M以太网的接入
2.9 USB
采用PDIUSBD12,提供USB1.1 device接口
2.10 Nand Flash
采用K9F2808,数据Flash,可以做文件系统
2.11 LCD
提供16x2字符型液晶接口
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 9 -
第三节 软件部分
3.1 uClinux简介
uClinux 是在 Linux kernel 2.0 之后出现的一个 Linux 的变种,它的目标是将 Linux
应用于没有内存管理单元(Memory Management Units)的处理器.uClinux 中u就是 Micro,
表示微,小的意思;C 就是 Control,即控制.因此可以说,uClinux是针对"微控制领域
而设计的Linux系统".
由于uClinux 是在 Linux 的基础之上添加了对没有 MMU 的微处理器的支持,所以它
一方面继承了 Linux 的大部分优点:例如稳定性,各种网络协议栈的支持以及不同类型的
文件系统支持等等,另一方面,它广泛地应用于嵌入式领域,内核精简(一般小于 512k),
并支持很多常用的嵌入式微控制器系列,例如 Motorola Dragon Ball,ColdFire,ARM7TDMI
( Atmel AT91x,Samsung S3C4510x)等.
与标准Linux操作系统相比,uClinux 最大的区别就在于内存管理.标准 Linux 是针对
有内存管理单元的处理器而设计的,使用虚拟存储器技术通过分页的方式来载入进程.这样
每个进程在其虚拟地址空间上相互独立,通过 MMU 实现从虚拟地址到物理地址的映射.
现代操作系统的内存管理大多采用这种方式,这种做法带来的好处有很多,比如:
1) 可以使用比实际物理内存大得多的内存空间,程序在运行时不必全部装入内存,只
加载需要的部分程序,这样既节省了内存空间,又缩短了程序启动的时间.
2) 可以运行重定位的程序,同时也可以使多个程序驻留在内存中.
3) 可以方便地实现程序代码的共享.即多个进程共享程序的同一个副本.
4) 由于每个进程只在自己的虚拟地址空间上运行,通过 MMU 做虚拟地址->物理地
址的转换,进程的虚拟空间被映射到了不同的内存区域中,因而一个进程不能随意访问和修
改其他进程空间的内容,有利于不同进程之间的保护.
但是,在嵌入式领域 NOMMU 的处理器是相当普遍的,这是因为,一方面 MMU 在
处理器中会占用相当大比例的硅片面积,基于成本和尺寸的考虑,没有 MMU 会更适合于
嵌入式设备的应用;另一方面,当发生页面失效时,从磁盘加载进程的页面到内存中,会相
当消耗时间和处理器资源,这对系统工作的影响很大,容易带来不稳定的因素.
基于上述原因,uClinux 对 NOMMU 的处理器采用了实存储器管理策略(real memory
management).这样一个进程在执行前,系统必须为之分配足够的连续地址空间,然后全部
载入主存储器中.因为在嵌入式开发中,通常都是针对特定环境下的应用,所以这样的实现
也是可行的,从执行效率上讲也更会高一些.
uClinux 的官方网站是 http://www.uclinux.org ,基本上 uClinux 的发布是和 Linux 的
版本发布保持同步更新的.
目前最新支持的内核版本是 2004-04-08 发布的uClinux-dist-20040408.tar.gz.
在本实验指导书的附录中,有关于 uClinux 的常见问题及其解答,可供参阅.
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 10 -
3.2 SkyEye 简介
SkyEye是一个开源软件(OpenSource Software)项目,中文名字是"天目".SkyEye的
目标是在通用的Linux和Windows平台实现一个纯软件集成开发环境,模拟常见的嵌入式
计算机系统(这里假定"仿真"和"模拟"的意思基本相同);可在SkyEye上运行 CLinux以及
C/OS-II等多种嵌入式操作系统和各种系统软件(如TCP/IP,图形子系统,文件子系统
等),并可对它们进行源码级的分析和测试.
3.2.1 SkyEye的起源和发展
2002年11月,一个偶然的机会,一群操作系统的爱好者在网上进行聊天,成立了一个
TM-Linux兴趣小组,希望要做一些感兴趣的事情.当时在清华大学计算机系做博士后的
陈渝提出做一个用软件实现的嵌入式开发板硬件模拟器,可以在模拟器上运行各种操作系
统,这样就可以在没有开发板的情况下学习和研究操作系统.一开始就陈渝一人做,首先他
了解了当前国际上的一些类似的项目,发现著名的 CLinux组织实现了一个armulator模拟
器软件(在Linux系统上运行),可以模拟Ateml AT91(基于ARM7TDMI CPU)开发板,
CLinux可以在armulator(其网址为http://www.uclinux.org/pub/uCLinux/utilities/armulator/)
上运行.于是陈渝以此为基点,借鉴armulator的实现,提出了SkyEye项目,其目标是让
SkyEye仿真多种主流的嵌入式开发板和外设,实现一个可扩展的硬件模拟框架,让更多的
嵌入式操作系统可以在SkyEye上运行.SkyEye项目是在2002年12月1日正式建立后,陈
渝完成的第一件工作是把armulator移植到了cygwin/windows环境下,其成果被 CLinux组
织接收.接下来清华大学计算机系硕士生李明加入到SkyEye的开发中,8天后,SkyEye的
第一个版本推出,再过了4天, C/OS-II for SkyEye推出.在这期间,SkyEye的网站也建
立起来了.紧接着,杨晔,王利明,尹首一等在校学生也加入到SkyEye的开发中,给SkyEye
带来了新的活力,SkyEye进入了新的发展阶段.
3.2.2 SkyEye的的目标和意义
纯软件的模拟器有许多种,如模拟一个芯片时序逻辑的模拟器,只模拟CPU指令的模
拟器,模拟整个硬件开发板的模拟器,模拟一个PDA的模拟器等.存在一些纯软件的仿真
器或模拟器,如Stanford大学的SimOS模拟器,它仿真的是MIPS系列CPU和相关外设,
可以在其上运行SGI公司的Irix操作系统和软件,目前基本上停止了进一步的开发;PSIM
是一个仿真PowerPC指令集的模拟器,目前只支持简单的命令行应用程序;xcopilot是一个
PDA模拟器,它是由Greg Hewgill出于个人喜好编写的,它仿真的是M68K CPU,通过它
可以给基于PalmOS的软件开发者提供一个模拟开发环境.Bochs是一个仿真x86 CPU的开
源项目,目前还支持AMD64 CPU,在它上面可以运行Linux操作系统.其它一些商业的仿
真软件如vmware和virtualPC可以仿真一个真实的x86计算机,而Virtutech Simics仿真器
可以仿真多种CPU和硬件,功能强大,可用于硬件和系统软件的评测.
SkyEye是一个指令级模拟器,可以模拟多种嵌入式开发板,可支持多种CPU指令集,
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 11 -
在SkyEye上运行的操作系统意识不到它是在一个虚拟的环境中运行,而且开发人员可以通
过SkyEye调试操作系统和系统软件.由于SkyEye的目标不是验证硬件逻辑,而是协助开
发,调试和学习系统软件,所以在实现上SkyEye与真实的硬件环境相比还是有一定差别
的.SkyEye在时钟节拍的时序上不保证与硬件完全相同,对软件透明的一些硬件仿真进行
了一定的简化,这样带来的好处是SkyEye的执行效率更高.SkyEye的推出具有下面三方面
的意义:
通过SkyEye仿真集成环境可以很方便地进入到嵌入式系统软件学习和开发的广阔天地
中.尤其对于缺少嵌入式硬件开发环境和软件开发环境的用户来说,它将是一个非常有
效的学习工具和开发手段,因为SkyEye的整个软件系统都是Open Source的,且基于
GPL协议( COS-II除外).因此,如果要学习Linux操作系统或者进行嵌入式系统开
发,但苦于没有硬件支持,SkyEye仿真环境软件是一个很好的选择!
如果想研究与具体硬件无关的系统软件(如TCP/IP协议栈等),采用SkyEye可以有效
地提高工作效率,因为你可以直接在 COS-II和 CLinux for SkyEye上进行开发和调试,
而与具体硬件打交道的各种driver已经存在,且有源码级调试环境,只需关心高层的逻
辑设计和实现就可以了.
SkyEye本身作为一个开放式的项目体系,可以划分为多个独立的子项目系统.通过参
与SkyEye的各个子项目,与大家共同交流,协作,可以进一步学习,分析,精通Linux
内核,掌握ARM嵌入式CPU编程.
在32位嵌入式CPU领域中,ARM系列CPU所占比重很大,而ARM7TDMI是其中最
广泛的一种ARM CPU核,因此SkyEye首先选择了ARM7TDMI作为仿真的目标CPU核,
当然将来SkyEye会支持更多种类的CPU.目前在SkyEye上可运行并进行源码级调试ARM
Linux, CLinux, C/OS-II操作系统和LwIP(一个嵌入式TCP/IP实现)等系统软件,将来
还要支持GUI系统软件.SkyEye可用于学习,分析,开发这些系统软件的实现,了解
ARM嵌入式CPU编程.而这一切都可在一个纯软件的环境中完成.通过分析SkyEye本身
实现,则系统软件开发人员对ARM,8019AS以太网络芯片等硬件的了解也会更深入.
SkyEye并不能取代开发板等硬件的功能,但通过它可以比较容易进入到嵌入式软件的
广阔天地中.由于SkyEye建立在GDB基础之上,使用者可以方便地使用GDB提供的各种
调试手段对SkyEye仿真系统上的软件进行源码级的调试,还可以进行各种分析,如执行热
点分析,程序执行覆盖度分析等.由于SkyEye提供了源代码和相关文档,有经验的用户完
全可以修改和扩充SkyEye来满足自己的需求.
SkyEye 项目的主页: http://www.skyeye.org
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 12 -
软件实验――操作系统移植与应用程序开发
实验一 在 ARM7 开发板上下载和运行uClinux 内核
Step 1: 开发主机与开发板软硬件连接
1,连接 pc 串口0 与 开发板串口0 (即 uart0)
2,连接 pc 网口与开发板网口
3,连接 5v 电源与开发板电源接头
4,在主机端使用串口终端软件和开发板建立通讯,串口设置如下:
端口com1,波特率19200,数据位8,奇偶校验none,停止位 1,流量控制none
比较常用的串口终端软件有 Windows 下的超级终端,Terminal 或者 Linux下的 MiniCom 等工具.
在本节后面有使用这几个软件进行连接的截图,可以帮助大家建立自己需要的连接.
5,通过开发板上 Reset 按钮进行复位,开发板的 Bootloader 会输出如下启动信息:
*************************************************************

lumit4510 ARM7 Board Fireware ( Release 1.3 )
Build date : Oct 17 2004 Time : 17:00:32
[lumit] - let us make it together
To find us at http://www.lumit.org
Type 'help' for more commands.
\>
6,到这里,我们成功地将开发板和主机建立了软硬件的连接并启动了开发板.
Step 2: 设置开发板ip地址
1,通过输入 help 命令可以看到
\>help
help ------ show help
------ = help
load ------ Load file to memory
prog ------ Program flash
boot ------ Boot from flash
ap ------ Auto load image flie and program flash
copy ------ Copy flash from src to dst address
ipcfg ------ Show or set IP address ( ipcfg 192.168.168.101 )
go ------ Go at 0x8000
dn ------ Ev-7t bootloader download
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 13 -
play ------ Play sample music
2,通过输入 ipcfg 命令可以获得开发板的 ip 地址 (缺省即 192.168.168.101)
\>ipcfg
IP address : 192.168.168.101
\>
3,这里我们设置开发板的 ip 为 192.168.0.101 ,大家可以根据自己开发板上的 ip 地址进
行设置,注意尽量避免和别人有 ip 地址冲突,以免影响后面的实验.
\>ipcfg 192.168.0.101
Set IP address : 192.168.0.101
\>
4,这里再次输入 ipcfg 命令查看ip,以确保刚才的设置正确无误.
\>ipcfg
IP address : 192.168.0.101
\>
Step 2: 准备相关文件
1,如果主机是 Windows 操作系统,请到如下地址下载 tftp 工具:
http://www.lumit.org/download/tools/tftp.exe
如果主机是 Linux 操作系统,请确认安装了 tftp 应用程序:
[lumit@localhost lumit]$ which tftp
/usr/bin/tftp
[lumit@localhost lumit]$
2,下载 http://www.lumit.org/download/software/image.ram.rar
3,解压缩image.ram.rar获得image.ram,该文件就是uClinux kernel image
4,检查下载的 image.ram 文件大小是否正确
[lumit@localhost Exp1]$ ls -l
总用量 2020
-rw-r----- 1 lumit lumit 1563584 10月 17 20:45 image.ram
-rw-r----- 1 lumit lumit 493133 10月 17 20:45 image.ram.rar
[lumit@localhost Exp1]$
Step 3: 设置主机 ip
1,检查pc 主机的ip地址设置( 下面以 192.168.0.100 为例进行说明).
2,使用开发套件中的"网络对连线"连接 pc 主机的网口和 lumit 4510 开发板的网口.
3,此时应该看到 D1, D2 led 亮了,说明网络连接正常.

lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 14 -
Step 4: 下载内核并执行
1,在开发板上执行 load 命令,表示从网络下载内核
\>load
No begin address for download, use default address 0x8000
Mini TFTP Server 1.0 (IP : 192.168.0.101 PORT: 69)
Load image file from host
Type tftp -i 192.168.0.101 put filename at the host PC
Press ESC key to exit

2,此时开发板开始等待主机发送 image.ram

3,在 Windows 主机上的下载目录中输入 tftp -i 192.168.0.101 put image.ram
tftp -i 192.168.0.101 put image.ram
Transfer successful: 1563584 bytes in 3 seconds, 521194 bytes/s

如果是 Linux 主机,则同样在下载目录下输入 tftp 命令:
[lumit@localhost Exp1]$ tftp
tftp> connect 192.168.0.101
tftp> binary
tftp> put image.ram
Sent 1563584 bytes in 12.3 seconds
tftp>

4,最后一行表示通过 tftp 传输成功,下载 uClinux kernel 完毕.

5,此时在开发板上显示如下信息,表示下载完毕等待启动
Starting the TFTP download...
.........................................
Received 17dbc0 Bytes, END...
Boot Image (y/n) y

6,输入 y 表示确认希望运行 uClinux Kernel image

7,uClinux Kernel 开始输出,显示如下信息:
Linux version 2.4.22-uc0 (root@dailzh) (gcc version 2.95.3 20
010315 (release)(ColdFire patches - 20010318 from http://fiddes.net/coldfire/)(u
Clinux XIP and shared lib patches from http://www.snapgear.com/)) #24 9 17
18:54:45 CST 2003
Processor: Samsung S3C4510B revision 6
Architecture: SNDS100
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 15 -
On node 0 totalpages: 4096
zone(0): 0 pages.
zone(1): 4096 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/rom0
Calibrating delay loop... 49.76 BogoMIPS
Memory: 16MB = 16MB total
Memory: 14512KB available (1454K code, 156K data, 40K init)
Dentry cache hash table entries: 2048 (order: 2, 16384 bytes)
Inode cache hash table entries: 1024 (order: 1, 8192 bytes)
Mount cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 4096 (order: 2, 16384 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
Starting kswapd
Samsung S3C4510 Serial driver version 0.9 (2001-12-27) with no serial options en
abled
ttyS00 at 0x3ffd000 (irq = 5) is a S3C4510B
ttyS01 at 0x3ffe000 (irq = 7) is a S3C4510B
Blkmem copyright 1998,1999 D. Jeff Dionne
Blkmem copyright 1998 Kenneth Albanowski
Blkmem 1 disk images:
0: C4358-17DB57 [VIRTUAL C4358-17DB57] (RO)
RAMDISK driver initialized: 16 RAM disks of 1024K size 1024 blocksize
Samsung S3C4510 Ethernet driver version 0.1 (2002-02-20)
eth0: 00:40:95:36:35:34
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 1024 bind 1024)
VFS: Mounted root (romfs filesystem) readonly.
Freeing init memory: 40K
Shell invoked to run file: /etc/rc
Command: hostname Samsung
Command: /bin/expand /etc/ramfs.img /dev/ram0
Command: /bin/expand /etc/ramfs2048.img /dev/ram1
Command: mount -t proc proc /proc
Command: mount -t ext2 /dev/ram0 /var
Command: mount -t ext2 /dev/ram1 /ramdisk
Command: chmod 777 /ramdisk
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 16 -
Command: mkdir /var/config
Command: mkdir /var/tmp
Command: mkdir /var/log
Command: mkdir /var/run
Command: mkdir /var/lock
Command: ifconfig lo 127.0.0.1
Command: route add -net 127.0.0.0 netmask 255.255.255.0 lo
Command: ifconfig eth0 192.168.168.101 netmask 255.255.255.0 up
Command: cat /etc/motd
Welcome to
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ \| | | |\ \/ /
| |_| | |__| || |
| ___\____|_||_|_| |_|\____|\_/\_/
| |
|_|

For further information check:
http://www.uclinux.org/

Execution Finished, Exiting

Sash command shell (version 1.1.1)
/>

8,使用 ifconfig 命令查看 uClinux 的 ip 地址:
/> ifconfig
eth0 Link encap:Ethernet HWaddr 00:40:95:36:35:34
inet addr:192.168.168.101 Bcast:192.168.168.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:64 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:17

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 17 -
collisions:0 txqueuelen:0

/>

9,修改 ip 地址为 192.168.0.101
/> ifconfig eth0 192.168.0.101
/> ifconfig
eth0 Link encap:Ethernet HWaddr 00:40:95:36:35:34
inet addr:192.168.0.101 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:67 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:17

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0

/>

10,进入 /bin 目录,执行下面的应用程序,例如 ping/telnet/ftp/mount 等
例如:
/> cd bin
/bin> ping 192.168.0.100
PING 192.168.0.100 (192.168.0.100): 56 data bytes
64 bytes from 192.168.0.100: icmp_seq=0 ttl=128 time=0.0 ms
64 bytes from 192.168.0.100: icmp_seq=1 ttl=128 time=0.0 ms
64 bytes from 192.168.0.100: icmp_seq=2 ttl=128 time=0.0 ms

--- 192.168.0.100 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms
/>

可以看出 pc 主机与开发板的连接正常

另外如果在 pc 主机端启动 telnet/ftp server,还可以测试 telnet/ftp 等应用.
可以自己测试一下,telnet 到自己的 pc 上看看目录文件,举例如下:
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 18 -
/bin> telnet 192.168.0.18
Trying 192.168.0.18(5888)...
Connected to 192.168.0.18.
Escape character is '^]'.
Red Hat Linux release 9 (Shrike)
Kernel 2.4.20-8 on an i686
login: lumit
Password: lumit
Last login: Sun Oct 17 21:36:42 from 192.168.0.101
[lumit@localhost resources]$ ls -l
总用量 16
drwxr-x--- 2 lumit lumit 4096 10月 17 20:45 Exp1
drwxr-x--- 3 lumit lumit 4096 10月 17 21:14 Exp2
drwxr-x--- 2 lumit lumit 4096 10月 17 21:40 Exp3
drwxrwxr-x 4 lumit lumit 4096 10月 17 21:33 uClinux
[lumit@localhost resources]$

实验一附录:
下面的图是在 Windows 下使用 Terminal 工具进行设置的界面:
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 19 -



下面的图是使用 Windows 下的超级终端进行设置的界面.

lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 20 -



lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 21 -


下面是在 Linux 下使用 minicom 进行设置的界面:
[root@localhost root]# minicom –s


lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 22 -




lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 23 -
实验二 uClinux 内核的交叉编译和 SkyEye 仿真调试
Step 1 : 安装交叉编译器 GNU Toolchain
1. 下载 arm-elf-tools-20030314.sh
http://159.226.40.150/lumit/resources/uClinux/Toolchain/arm-elf-tools-20
030314.sh

2. arm-elf-tools-20030314.sh 是一个可以自动安装的脚本文件,改变属性为可执行文件:
chmod 755 arm-elf-tools-20030314.sh

3. 执行脚本即可完成交叉编译器的安装
./arm-elf-tools-20030314.sh

4. 测试一下,输入 arm-elf-gcc 看看是否能够自动补齐
[admin@localhost admin]$ arm-elf-gcc -v
Reading specs from /usr/local/lib/gcc-lib/arm-elf/2.95.3/specs
gcc version 2.95.3 20010315 (release)(ColdFire patches - 20010318 from
http://fiddes.net/coldfire/)(uClinux XIP and shared lib patches from
http://www.snapgear.com/)

[admin@localhost admin]$ which arm-elf-gcc
/usr/local/bin/arm-elf-gcc

表明 arm-elf-gcc 已经安装在 /usr/local/bin/ 目录下了.

Step 2 : 交叉编译 uClinux 内核
1. 下载 uClinux-dist-20040408.tar.gz 到当前工作目录下
http://159.226.40.150/lumit/resources/uClinux/uClinux-dist-20040408.tar.gz

2. 解压 uClinux-dist-20040408.tar.gz 文件到 uClinux-dist 目录
tar xvzf uClinux-dist-20040408.tar.gz
此时当前工作目录下增加了一个名为 uClinux-dist 的目录.

3. 进入 uClinux-dist 目录
cd uClinux-dist
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 24 -

4. 修改 vmlinux-armv.lds.in 文件,
vi linux-2.4.x/arch/armnommu/vmlinux-armv.lds.in
在 65 行处添加三条语句,如下 所示:
65 *(.got) /* Global offset table
*/
66
67 /* add by lumit - http://www.lumit.org */
68 romfs_data = .;
69 romfs.o
70 romfs_data_end = .;

5. 修改 vendors/Samsung/4510B/Makefile 文件,
vi vendors/Samsung/4510B/Makefile
在 image 目标的第三行,增加一条语句,如下所示:
63 image:
64 [ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)
65 genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)
66 arm-elf-ld -r -o $(ROOTDIR)/$(LINUXDIR)/romfs.o -b binary $(ROMFSIMG)
67 $(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec \
68 --remove-section=.text --remove-section=.ramvec \
69 --remove-section=.init \
70 --remove-section=.bss --remove-section=.eram \
71 $(ROOTDIR)/$(LINUXDIR)/linux $(IMAGEDIR)/linux.data

6. make menuconfig
在 Vendor/Product Selection ---> 中选择
--- Select the Vendor you wish to target
(Samsung) Vendor
--- Select the Product you wish to target
(4510B) Samsung Products

在 Kernel/Library/Defaults Selection ---> 中选择
(linux-2.4.x) Kernel Version
(uClibc) Libc Version

其他选项都不变,按照缺省设置,选择退出,保存配置.

7. make dep

8. make lib_only
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 25 -

9. make user_only
[说明] 编译login,boa程序时可能出现 undefined reference to 'crypt_old'的错误,
boa.elf2flt: In function `auth_check_userpass':
./uClinux-dist/user/boa/src/auth.c:281: undefined reference to `crypt_old'
可以修改
vi config/.config
注释掉第25行的 CONFIG_USER_OLD_PASSWORDS
如下:
24 CONFIG_USER_LOGIN_LOGIN=y
25 # CONFIG_USER_OLD_PASSWORDS=y
26 # CONFIG_USER_ONLY_ROOT is not set
然后再
cd user/boa/src/
rm -rf *.o
cd ../../../
重新编译 make user_only 一下这个目录里面的 obj 文件就可以了.

10. make romfs

11. make
注意这里可能会报错 romfs.o 文件没有找到,没有关系,忽略这个错误往下做12步.

12. make image
13. 此时仍会报错,没有关系,再依次重复步骤10,11,12 就可以通过
[说明] 编译程序时可能出现如下错误提示:
arch/armnommu/mm/mm.o: In function `free_initmem':
./uClinux-dist/linux-2.4.x/arch/armnommu/mm/init.c:240: undefined reference to
`machine_is_ta7v'
这个错误只要注释该文件的相关代码即可.
655 void free_initmem(void)
656 {
657 if (!machine_is_integrator() &&
658 !machine_is_p52() &&
659 !machine_is_cx821xx() &&
660 !machine_is_atmel() &&
661 !machine_is_netarm() &&
662 // !machine_is_ta7v() &&
663 !machine_is_ta7s()) {
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 26 -
664 free_area((unsigned long)(&__init_begin),
665 (unsigned long)(&__init_end),
666 "init");
14.此时得到 ./uClinux-dist/linux-2.4.x/linux 文件
和 ./uClinux-dist/images/image.bin
Step 3 : 在 SkyEye 上仿真调试内核
在开始第三步之前,先简要介绍 Exp3/release 目录下几个文件之间的关系:
[admin@localhost release]$ ll
total 13832
-rw-rw-rw- 1 admin admin 1809372 9月 14 17:52 image.ram
-rw-rw-rw- 1 admin admin 1842436 9月 14 17:36 linux
-rw-rw-rw- 1 admin admin 77 9月 14 17:51 Makefile
-rwxr-xr-x 1 admin admin 10476890 9月 14 17:27 skyeye
-rw-rw-rw- 1 admin admin 177 9月 14 17:29 skyeye.conf

其中 skyeye 是可在 RedHat9.0 下执行的 SkyEye 模拟器;
skyeye.conf 是 skyeye 执行需要的配置文件,主要是指定 cpu 类型;
linux 是 uClinux Kernel Source 编译之后得到的 linux-2.4.x/linux 文件
image.ram 是 uClinux Kernel Source 编译之后得到的 image/image.ram 文件
Makefile 是一个简单说明 linux 和 image.ram 之间关系的文件,
即 linux 通过 arm-elf-objcopy 得到 image.ram

【注意】
下载 skyeye 或者 解压 rar 压缩文件包之后,需要通过 chmod 命令改变 skyeye 的
属性.
chmod 755 skyeye (这样 skyeye 就可以在 redhat9.0 以上版本中执行了)
否则,直接执行 ./skyeye 会报错:
-bash: ./skyeye: Permission denied


Exp 3:
在 SkyEye 模拟环境中运行 linux 的输出显示
[admin@localhost release]$ ./skyeye linux
***************************************************************
**** ****
**** SkyEye Simulator Ver 0.8.0 with GDB 5.3 Interface ****
**** ****
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 27 -
***************************************************************
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This SkyEye was configured as "--host=i686-pc-linux-gnu --target=arm-elf"...(no
debugging symbols found)...
(SkyEye) target sim
cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0
mach info: name s3c4510b, mach_init addr 0x813e884
SKYEYE: use arm7100 mmu ops
Connected to the simulator.
(SkyEye) load
Loading section .init, size 0xa000 vma 0x8000
Loading section .text, size 0x1a60b8 vma 0x12000
Loading section .data, size 0x7bdc vma 0x1ba000
Start address 0x8000
Transfer rate: 14410912 bits in ls
bin
dev
etc
home
lib
mnt
proc
sbin
tmp
usr
var
/> cd bin
/bin> ls
arp
basename
boa
busybox
date
dhcpcd
dmesg
du
expand
ftp
hostname
ifconfig
inetd
init
kill
killall
login
mount
ping
route
sh
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 30 -
telnet
telnetd
umount
uptime
/bin> hostname
Samsung
/bin> 【此处输入 Ctrl + c 退出 uClinux 运行状态,进入 SkyEye 调试界面】
Program received signal SIGINT, Interrupt.
0x00015dec in ()
(SkyEye) quit
The program is running. Exit anyway (y or n) y
[admin@localhost release]$



特别提示:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
从 linux (elf 格式文件) 得到 image.ram (bin 格式文件)
请执行命令 :
arm-elf-objcopy -O binary -R .note -R .comment -S linux image.ram
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 31 -
实验三 添加新的 uClinux 应用程序
Step 1 : 编写应用程序代码
1. cd uClinux-dist
2. cd user
3. mkdir myapp
4. cd myapp
5. vi demo.c

#include
#include

int main(void)
{
printf("Hello world! \n");
printf("[lumit] - let us make it together \n");
printf("--------------------\n");
printf("http://www.lumit.org\n");
return 0;
}

Step 2 : 修改相关 Makefile 文件
6. vi Makefile
EXEC = demo
OBJS = demo.o

all: $(EXEC)
$(EXEC): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS)

romfs:
$(ROMFSINST) /bin/$(EXEC)

clean:
rm -f $(EXEC) *.elf *.gdb *.o

lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 32 -
7. vi uClinux-dist/user/Makefile
在 324 行再添加一行 dir_$(CONFIG_USER_MYAPP_DEMO) += myapp

324 # add by lumit
325 dir_$(CONFIG_USER_MYAPP_DEMO) += myapp
326

Step 3 : 修改相关 config.in 文件
8. vi uClinux-dist/config/config.in
增添以下内容到文件最后
#####################################################################

mainmenu_option next_comment
comment 'My New Application'

bool 'demo' CONFIG_USER_MYAPP_DEMO
bool 'app1' CONFIG_USER_MYAPP_APP1
bool 'app2' CONFIG_USER_MYAPP_APP2
bool 'app3' CONFIG_USER_MYAPP_APP3
comment "My New Application"

endmenu

#####################################################################

Step 4 : 重新编译内核和文件系统
9. 进行重新编译内核和文件系统的步骤
make menuconfig
在 Kernel/Library/Defaults Selection ---> 中选择
(linux-2.4.x) Kernel Version
(uClibc) Libc Version
[ ] Default all settings (lose changes)
[ ] Customize Kernel Settings
[*] Customize Vendor/User Settings
[ ] Update Default Vendor Settings
然后退出并保存,此时会在 Main Menu 界面中出现新的一项:
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 33 -
Debug Builds --->
My New Application --->
---
进入后,选择 demo 应用,此时也可以看到刚才添加的 app1,app2,app3 也
出现在 demo 下面,大家可以类似地添加新的应用.
[*] demo
[ ] app1
[ ] app2
[ ] app3
退出保存之后,重复刚才的步骤如下:注意如果前面已经编译成功过一次,那么
后面只需进行 make user_only; make romfs; make
make dep
make clean
make lib_only (这三步可以只做1次,不必要每次都来)
(每次修改过你的应用程序之后,这一步后面的都必须重来)
make user_only
make romfs
make
make image

10. 下载内核,运行看看:
\>load
No begin address for download, use default address 0x8000
Mini TFTP Server 1.0 (IP : 192.168.168.101 PORT: 69)
Load image file from host
Type tftp -i 192.168.168.101 put filename at the host PC
Press ESC key to exit
Starting the TFTP download...
................................................
Received 18baec Bytes, END...
Boot Image (y/n) y
Linux version 2.4.20-uc0 (liming@hpclab.cs.tsinghua.edu.cn) (gcc
version 2.95.3 20010315 (release)(ColdFire patches - 20010318 from
http://fiddes.net/coldfire/)(uClinux XIP and shared lib patches from
http://www.snapgear.com/)) #7 Wed Aug 25 22:07:14 HKT 2004
Processor: Samsung S3C4510B revision 6
Architecture: SNDS100
On node 0 totalpages: 4096
zone(0): 0 pages.
zone(1): 4096 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/rom0
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 34 -
Calibrating delay loop... 49.86 BogoMIPS
Memory: 16MB = 16MB total
Memory: 14452KB available (1510K code, 157K data, 40K init)
Dentry cache hash table entries: 2048 (order: 2, 16384 bytes)
Inode cache hash table entries: 1024 (order: 1, 8192 bytes)
Mount-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 4096 (order: 2, 16384 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
Starting kswapd
Samsung S3C4510 Serial driver version 0.9 (2001-12-27) with no serial
options enabled
ttyS00 at 0x3ffd000 (irq = 5) is a S3C4510B
ttyS01 at 0x3ffe000 (irq = 7) is a S3C4510B
Blkmem copyright 1998,1999 D. Jeff Dionne
Blkmem copyright 1998 Kenneth Albanowski
Blkmem 1 disk images:
0: BE7E8-18BBE7 [VIRTUAL BE7E8-18BBE7] (RO)
RAMDISK driver initialized: 16 RAM disks of 1024K size 1024 blocksize
Samsung S3C4510 Ethernet driver version 0.1 (2002-02-20)

eth0: 00:40:95:36:35:34
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 1024 bind 1024)
VFS: Mounted root (romfs filesystem) readonly.
Freeing init memory: 40K
Shell invoked to run file: /etc/rc
Command: hostname Samsung
Command: /bin/expand /etc/ramfs.img /dev/ram0
Command: /bin/expand /etc/ramfs2048.img /dev/ram1
Command: mount -t proc proc /proc
Command: mount -t ext2 /dev/ram0 /var
Command: mount -t ext2 /dev/ram1 /ramdisk
Command: chmod 777 /ramdisk
Command: mkdir /var/config
Command: mkdir /var/tmp
Command: mkdir /var/log
Command: mkdir /var/run
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 35 -
Command: mkdir /var/lock
Command: ifconfig lo 127.0.0.1
Command: route add -net 127.0.0.0 netmask 255.255.255.0 lo
Command: ifconfig eth0 192.168.168.101 netmask 255.255.255.0 up
Command: cat /etc/motd
Welcome to
____ _ _
/ __| ||_|
_ _| | | | _ ____ _ _ _ _
| | | | | | || | _ \| | | |\ \/ /
| |_| | |__| || | | | | |_| |/ \
| ___\____|_||_|_| |_|\____|\_/\_/
| |
|_|

For further information check:
http://www.uclinux.org/

Execution Finished, Exiting

Sash command shell (version 1.1.1)
/> ls
bin
dev
etc
home
lib
mnt
proc
ramdisk
sbin
tmp
usr
var
/>
/> cd bin
/bin> ./demo
Hello world!
[lumit] - let us make it together
--------------------
http://www.lumit.org
/bin>
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 36 -
附录 - uCLinux FAQs
Q: 请问uclinux启动时最先执行哪一个程序文件中的代码
A: 如果是不压缩的内核,则执行 linux-2.4.x/arch/armnommu/kernel/head-armv.S
如果是压缩的内核,则先执行解压的程序
linux-2.4.x/arch/armnommu/boot/compressed/head.S
当然,如果是其他的 arch ,应该可以依此类推.
Q: 程序在 ram 中运行和在 rom 中运行有什么不同
A: 至少有以下这些情况是需要 ram 的 :
程序中定义了全局变量,并进行了赋值. 例如 int a; a = 1;
程序中进行了函数调用,使用了堆栈. 例如 function();
在函数内部使用了局部变量,同样也会使用堆栈. 例如 void f() { int a = 5; }
程序中对某内存地址进行了写操作.例如 str r1, [r2]; *paddr = 1;
如果一个程序没有上面的这些,那么 rom 中也是可以跑的,比如点led的小汇编.
Q: uclinux中,与具体的cpu相关的代码都分布在哪几个目录中
A: 以 Samsung 4510B 为例,以下目录的相关文件比较重要.
uClinux-Samsung\linux-2.4.x\arch\armnommu\mach-samsung\* 芯片级
uClinux-Samsung\vendors\Samsung\4510B\makefile 如何生成 image, romfs
uClinux-Samsung\linux-2.4.x\drivers\char\serial_samsung.c 串口驱动
uClinux-Samsung\linux-2.4.x\include\asm-armnommu\arch-samsung 头文件定义
Q: 编译之后在 images 目录下生成的那些文件都是什么意思
A: 对于一些可能出现的文件,这里做一个解释:
romfs.img: 这个文件是通过 tools/romfs-inst.sh 脚本,生成 romfs 目录及其
下面的文件,然后通过 genromfs 程序打包成一个文件 romfs.img
romfs.img 既可以放在 flash 中,也可以放在 ram 中,但需要在
编译内核时在 driver/block/blkmem.c 里指定地址,以便内核找到.
linux.text: 编译后的内核中 text 段,一般放在 flash 中,只读.
linux.data: 编译后的内核中 data,init 段,一般放在 sdram 中,读写.
image.bin: 上面三个文件顺序连接而生成的 = linux.text + linux.data + romfs.img
有的时候还会得到:
image.rom: 通常 image.rom 的文件大小要比 image.ram 小很多,这是因为 image.rom 是
一个压缩过的内核,前面加上一个小的解压程序负责把内核解压后搬到指定位置.
这个文件可以直接烧进 flash 中,当然也可以在 ram 中运行.这个文件实际上
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 37 -
就是通常 linux 生成的 zImage 文件.
image.ram: 这个内核没有压缩过,而且必须在 ram 里运行.所以需要通过板子上的 bootloader
将它下载到指定位置后开始执行.相对 image.rom 而言,从 ram 里启动内核,则
代码段和数据段都在 ram 里面.这个文件是编译生成的 elf 格式的linux内核,通过
arm-elf-objcopy 工具生成的二进制映像文件.
可以这样形象的说: image.rom = gunzip program + gzipped(image.ram)
boot.rom: 其实就是 uClinux 编译完成后的文件 images/romfs.img,可以看一下它就是一个
连接.
Q: 在 make menuconfig 时读取的配置文件是什么
A: make menuconfig 是用的的配置文件主要有以下几个:
vi config.in
主要是处理 top level config ,包括 vendor/product, linux-2.4.x 版本选择,
Libc version,还有是否选择配置 Kernel Settings,Vendor/User Settings 等.
这个 config.in 文件是通过执行 config/mkconfig > config.in 脚本自动生成的.
( 因此修改 config.in 不起作用哟! )
vi arch/armnommu/config.in
主要是处理和 kernel settings 相关的配置,比如 选择 cpu 类型,选择设备驱动,
文件系统支持,网络支持 等等.这些也是裁减内核最重要的配置文件.
可以修改 arch/armnommu/config.in 来调整 make menuconfig 时的选项设置.
vi config/config.in
主要是处理 Vendor/User Settings 相关的部分,也就是 romfs 中添加的应用程序,
可以修改 config/config.in 来改变相关的选项设置.
vi vendors/Samsung/4510B/config.linux-2.4.x
Q: kernel 链接时用的 vmlinux.lds 是怎么得到的
A: vi linux-2.4.x/arch/armnommu/vmlinux-armv.lds.in 这个是原始文件,
vi arch/armnommu/Makefile 在这里定义了如何通过 sed 命令生成 lds.
其实就是把 Makefile 里面定义的 TEXTADDR 替换到 lds.in 文件里.
Q: kernel 链接时的起始地址 TEXTADDR 在哪里指定
A: vi arch/armnommu/Makefile 在相应的 ARCH 下找,
一般缺省的是 0xC0008000 .但不同的芯片会有不同的定义,例如
148 ifeq ($(CONFIG_ARCH_ATMEL),y)
149 TEXTADDR = 0x1000000
150 MACHINE = atmel
151 endif
166 ifeq ($(CONFIG_ARCH_SAMSUNG),y)
lumit4510 学习开发板 -- uClinux & SkyEye 实验手册
http://www.lumit.org
[lumit] - let us make it together - 38 -
167 TEXTADDR = 0x00008000
168 MACHINE = samsung
169 endif

- 作者: 温英林 2005年04月3日, 星期日 00:40  回复(1) |  引用(151) 加入博采

uClinux操作系统移植
一篇有关uClinux系统移植的文章......
uClinux操作系统移植

--------------------------------------------------------------------------------
来源:BIPLIP.com 作者:沈沙

(复旦大学电子工程系沈沙,欢迎转载,转载时请保留此行作者信息)

l uClinux简介
l 硬件体系结构简介
l 编译环境和编译工具。
l uClinux启动过程
l 系统源码的修改

1. uClinux简介

uClinux这个英文单词中u表示Micro,小的意思,C表示Control,控制的意思,所以uClinux就是Micro-Control-Linux,字面上的理解就是"针对微控制领域而设计的Linux系统"。

uclinux是一个源码开放的操作系统,面向没有MMU(Memory Management Unit)的硬件平台。它是linux的一个变种,主要的区别在于两者的内存管理机制和进程调度管理机制,同时为了适应嵌入式应用的需求,它的采用了romfs文件系统,并对linux上的c语言库glibc做了简化。

2. 硬件体系结构简介

运行uClinux的硬件平台主要包括如下几个部分:cpu(ARMv4指令集兼容)、uart、memory controller、定时器、flash存储器,sdram存储器,中断控制器和DMA。


3. 编译环境和编译工具

uclinux操作系统源码绝大部分是用c语言开发的,有一些与硬件直接相关的代码则用特定于某一CPU体系结构的汇编来实现。这些源码只能用GNU的gcc编译工具来进行编译、链接。

GNU gcc可以运行于Linux/Unix操作系统上。如果要在Windows平台上运行gcc,则必须安装Cygwin。Cygwin可以在Windows中安装一个linux的运行环境,这样就可以在windows下运行原本只能在linux下运行的程序。

为了在PC上编译得到运行于目标CPU上的操作系统内核,还必须安装一个合适的交叉编译器。Gcc 提供了现成的针对MIPS、ARM、M68K、Sharc、PowerPC的交叉编译器。如果没有现成的交叉编译器,则需要自行设计。GNU网站提供了一些如何开发新的交叉编译器的文章。开发一个新的编译器,一般需要如下几个步骤:

(1)、编写机器描述脚本。采用gcc的RTL(Register Tansfer Language)语言描述针对某一CPU体系结构的机器指令与寻址方式、CPU浮点处理方式、endianess、c语言中各种数据类型的位宽、寄存器的个数和使用规则、堆栈和函数调用规则等体系结构的细节。
(2)、设计代码生成器。Gcc在对c语言源文件进行了词法和语法分析后,将产生一种中间格式文件(intermediate representation)。为了把这种中间格式文件转化为针对具体CPU体系结构的机器码,需要自行设计一个代码生成器。
(3)、设计汇编器
(4)、设计链接器


4. uClinux启动过程

uClinux系统的启动可以分为两个步骤:
(1). 运行bootloader初始化程序

SRAM、SDRAM等存储设备属于挥发性的存储器,掉电以后其中的内容就会全部丢失,所以必须把操作系统的内核镜像存放在Flash等不挥发性存储介质上。但是操作系统在运行时,需要动态的创建一些如数据段、堆栈、页表(针对使用虚拟地址的操作系统)等内容,所以需要在RAM中运行操作系统。因此,就需要一个引导程序把操作系统的内核镜像从Flash存储器拷贝到RAM中,然后再从RAM中执行操作系统的内核。Bootloader就是可以完成这样一种功能的程序。

从本质上来讲,bootloader不属于操作系统内核。它采用汇编语言编写,因此针对不同的cpu体系结构,这一部分代码不具有可移植性。在移植操作系统时,这部分代码必须加以改写。

具体来讲,bootloader在系统启动时主要完成以下几项工作:
· 将操作系统内核从flash拷贝到sdram中,如果是压缩格式的内核,还要将之解压缩。
· 改写系统的memory map,原先flash起始地址映射为0地址,这时需要将RAM的起始地址映射为0。
· 设置堆栈指针并将bss段清零。将来执行c语言程序和调用子函数时要用到。
· 改变pc值,使得cpu开始执行真正的操作系统内核。
(2) 运行操作系统内核
bootloader程序执行完上述的各项工作后,通过一条跳转指令,转而执行ini目录下c语言源文件main.c中的函数start_kernel()。因为在此之前bootloader已经创建好一个初始化环境,
c函数可以开始执行了。整个操作系统内核的初始化工作从这里才算是真正开始。这个函数的长度比较短,代码如下:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
asmlinkage void __init start_kernel(void)
{
char * command_line;
unsigned long mempages;
extern char saved_command_line[];

/*
* Interrupts are still disabled. Do necessary setups, then
* enable them
*/
lock_kernel();
printk(linux_banner);
setup_arch(&command_line);
printk("Kernel command line: %s\n", saved_command_line);
parse_options(command_line);
trap_init();
init_IRQ();
sched_init();
softirq_init();
time_init();

/*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
console_init();
#ifdef CONFIG_MODULES
init_modules();
#endif
if (prof_shift) {
unsigned int size;
/* only text is profiled */
prof_len = (unsigned long) &_etext - (unsigned long) &_stext;
prof_len >>= prof_shift;

size = prof_len * sizeof(unsigned int) + PAGE_SIZE-1;
prof_buffer = (unsigned int *) alloc_bootmem(size);
}

kmem_cache_init();
sti();
calibrate_delay();
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok &&
initrd_start < min_low_pfn << PAGE_SHIFT) {
printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
"disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT);
initrd_start = 0;
}
#endif
mem_init();
kmem_cache_sizes_init();
pgtable_cache_init();

mempages = num_physpages;

fork_init(mempages);
proc_caches_init();
vfs_caches_init(mempages);
buffer_init(mempages);
page_cache_init(mempages);
#if defined(CONFIG_ARCH_S390)
ccwcache_init();
#endif
signals_init();
#ifdef CONFIG_PROC_FS
proc_root_init();
#endif
#if defined(CONFIG_SYSVIPC)
ipc_init();
#endif
check_bugs();
printk("POSIX conformance testing by UNIFIX\n");

/*
* We count on the initial thread going ok
* Like idlers init is an unlocked kernel thread, which will
* make syscalls (and thus be locked).
*/
smp_init();
rest_init();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


5. 系统源码的修改

移植一个操作系统到新的硬件平台,比较好的办法是寻找一个架构相近并且已经做好操作系统移植的硬件平台。然后,对原先的操作系统做一定修改。系统源码修改的工作量取决于自行设计的硬件平台与现有的硬件平台之间差异程度。此设计中的硬件平台与三星4510芯片较为接近,并且也可以下载到针对4510b的uclinux系统源码。所以可以从此源码入手,根据我们的硬件平台与4510b的不同之处,在源码中找到相应的文件并加以修改。下面介绍如何修改系统源码。


需要修改的系统源码主要有如下几处:
(1) bootloader相关代码。此代码位于\uClinux\linux-2.4.x\arch\armnommu\boot\compressed\目录下名为head.s的文件中。此处程序用汇编语言实现,需要修改的地方主要是设置memory map的代码,与memory controller的硬件实现相关。
(2) UART相关代码。UART相关代码位于\uClinux\linux-2.4.x\drivers\char目录下的serial.c
(3) 定时器相关代码。uClinux中有如下函数调用star_kernel()->time_init()->setup_timer(),需要修改setup_timer()函数中的相关代码。
(4) 中断控制器相关。\uClinux\linux-2.4.x\arch\armnommu\irq.c

除了上述的代码,还有其他多处需要修改。在修改源代码时,可按照uclinux启动和执行顺序依次修改整个平台。熟悉linux内核源码结构对操作系统移植有很大帮助。

- 作者: NetNiu 2004年07月9日, 星期五 17:12

- 作者: 温英林 2005年04月3日, 星期日 00:36  回复(0) |  引用(0) 加入博采