在移植uClinux之前要做一些准备工作,比如调试器是否可以正常工作,交叉编译环境的建立等。然后,再开始启动代码的移植和uClinux的移植。
①要保证硬件和JTAG接口正常以及正确的跳线。看调试器是否可以正确操作JTAG口;是否可以正确设置CPU寄存器的值,并可以通过设置LED地址的值来点灯。这一步保证了硬件的正确。
②检查调试器和JTAG是否可以正常工作。我们可以通过用JTAG调试器编译一个最简单的LED程序并让它在S3C44BOX的SDRAM中运行来进行测试。这一步的难点是正确设置与S3C44BOX的SDRAM相关的寄存器。这一步保证了调试器和JTAG的正确工作以及S3C44BOX的正常状态,并且在SDRAM中运行了第一个程序。
③S3C44BOX寄存器的设置。有时候尽管CPU在启动时会将这些寄存器赋予初始缺省值,很多缺省值恰恰是正确可用的,但许多寄存器也必须需要自己改动设置。
只有这些寄存器都设置正确了,程序才可以在SDRAM中长时间地运行,这是下一步工作的基础。需要手工设置的主要寄存器有:
u CPU WRAPPER SPECIALR EGISTERS寄存器。这部分有三个寄存器,管理着CPU的CACHE、WRITEBUF以及ARM7TDMI内核。
u WATCHDOG TIMER SPECIALR EGISTERS寄存器。通过这部分要暂时关掉WATCHDOG计数器,否则会使程序无法稳定地运行。
u CLOCK GENERATOR&POWER MANAGEMENT SPECIALR EGISTERS寄存器。这部分是时钟和电源管理寄存器,主要管理CPU的主频和电源;可以通过三星提供的工具计算出相对应的CPU主频的数值。
u MEMORY CONTROLLER SPECIALR EGISTERS寄存器。主要管理开发板中SDRAM的参数,刷新速度等。
这一步的最后为了测试CPU的SDRAM的稳定性。我们可以通过用JTAG调试器来编译运行给整个SDRAM存储空间赋值的测试程序, 并用LED来监测程序的运行情况。这样,就可以稳定地使用S3C44BOX的SDRAM了,这是今后工作的基础。
④Flash的编程。如果没有现成的Flash编程工具,这一步就需要自己来完成;有了上面的基础这一步就不难了。通过JTAG调试器编写Flash写程序和擦除程序,编译后通过JTAG把它下载到SDRAM中并运行,就可以成功完成Flash的擦写了。
至此准备工作基本完成,即为下一步引导代码的移植以及uClinux的移植打下了一个稳定的基础。
http://www.start-web.net/tpu 下载blob-mba44b0.tgz。这个blob-mba44bO.tgz是为一个叫mba44b0的开发板移植的BLOB,mba44b0也使用S3C44B0作为其处理单元,所以这个blob-mba44b0是需要改动最少的版本。我们就由这个blob-mba44b0.tgz开始BLOB的移植。
(3)选择适当的uClinux版本并安装uClinux源代码
因为在编译BLOB的时候BLOB需要uClinux的SOURCECODE所以我们现在就需要将uClinux的源代码下载并安装在这台宿主机上。uClinux也要选择一个需要改动最少的版本进行移植,同样,我们选择的是http://www.start-web.aet/tpu/上下载的uClinxu-2.4.17.tgz。将它安装在宿主机上的某一个目录上/path/to/armlinux/source。这个uClinux-2.4.17.tgz就是我们选择的要进行移植的uClinux版本。
(4)通过BLOB的Configure检验BLOB编译环境是否建立
根据BLOB的README,我们试图在宿主机上先将BLOB build起来。这一步我们将要用configure命令检查宿主机上的BLOB交叉编译环境是否正确的安装配置,并且通过configure文件的内容对BLOB各子目录的makefile进行修改。也许最后的make会报错,但这在此并不重要。这一步只要保证/configure通过就可以了。
(5)用建立起来的交叉编译环境编译最初的BLOB
这一步要编译通过BLOB生成初始的BLOB。因为编译器的不同,所以允许编译器对arm指令的解释有所不同。我们用arm-elf-gcc来编译这个blob-mba44b0,可能会出现一些语法错误。比如trampoline.S文件中的cpsr-cxsf(寄存器的cxsf位)arm-elf-gcc无法理解,在这里只需要将cpsr-cx sf改为cpsr即可。编译通过后,就建立好了BLOB的编译环境,下一步可开始针对开发板的特殊情况进行移植工作了。
(6)修改BLOB源代码进行移植
这一步是向开发板移植BLOB。上面的工作建立起编译BLOB的环境,下面要修改与开发板相关的源文件,然后编译得到BLOB即可。这一步需要参考./doc/port文件的内容,这里讲的就是如何移植BLOB。大概需要修改以下文件。
u . /congiure,是可执行的脚本文件,里面有arm-elf-gc。的编译选项。由于CPU不是strongARM的,要将-march=,-mtun=,等编译选项针对S3C44BOX进行修改。
u ./src/lib/led.c中的点灯和关灯函数需要针对自己的板卡中LED的地址进行修改。
u ./src/lib/serial-s3c44bO.c,是相关串行口的。如果S3C44BOX的主频设置为
60MHz,那么这个文件基本不用修改。
u ./src/blob/ledasm.s,需要根据板卡中LED的地址来修改,同led.c。
u ./src/blob/memsetup-s3c44b0.s,主要是CPU关于,dram的控制寄存器的值。
u ./src/blob/start.s,是系统加电后最开始运行的部分,也是将要写到零地址的内容。里面将要对一系列S3C44BOX的寄存器进行填充。这一步可以参考前面准备工作中的寄存器的填充,需要仔细阅读S3C44BOX手册。
u ./src/blob/main.c,相当于BLOB的核心主控程序,我们关心的是int main(void)函数它提供给用户一个简单的命令行,控制着BLOB的行为。
u ./src/blob/linux.c,是启动Linux内核BLOB的最后的代码,由它跳离BLOB然1A跳转到Linux核心。这里我们关心的是static int boot_linux(int argc,char*argv[])函数,它首先设置Linux启动参数,做好最后启动的准备,然后跳转到the Kernel。
以上便是需要修改的大部分文件。修改后,参考README中的内容重新把BLOB build起来,最终编译出来的./src/blob/目录下的BLOB,就是我们最终需要的可以直接运行在Flash中的执行代码。
(7)编译后的BLOB下载到开发板中完成BLOB移植
这是最后一步,将修改并编译后的BLOB通过Flash编程下载到开发板中Flash的零地址,这样BLOB的移植工作就完成了。此时只要将开发板重新加电或者RESET系统就将从Flash中零地址的BLOB开始执行。
此时,我们可以通过串口(windows的超级终端或Linux的minicom)来观察控制开发板上的BLOB,将来就可以通过这个开发板上的BLOB下载编译好的uClinux内核以及ramdisk。这一步为uClinux的移植开发打下了非常好的基础。BLOB的具体使用可以参考BLOB的README中的using blob。
5.3.2 uClinux针对硬件的改动
目前,uClinux己被成功移植到S3C44BOX及其他多款ARM芯片上,但由于嵌入式操作系统的运行是与嵌入式系统的硬件密切相关的,而硬件的设计则会因为使用场合的不同而千差万别。因此,在uClinux内核源代码中和硬件紧密相关的部分就应该针对特定的硬件作出适当的修改。由于uClinux内核源代码包含很大一部分的硬件驱动程序,不可能一一列举,在此,就基于S3C44BOX的最小系统的设计与运行相关的部分作简单的介绍。
uClinux内核源代码中对S3C44BOX片内特殊功能寄存器以及其他相关硬件信息的定义位于uClinux-SamsunglLinux-2.4.xlincludelasm-armnommularch-samsung/hardware.h文件中,其中有几个地方值得注意:
/*
*define S3C44BOX CPU master clock
*/
#define MHz 1000000
#define fMCLK_MHz (60*MHz)
#define fMCLK (fMCLK_MHz/MHz)
#define MCLK2 (fMCLK_MHz/2)
以上定义了系统工作的主时钟频率为60MHz,若用户系统的工作频率不同,应在此处修改,若串行口采用内部时钟信号用于波特率生成,该频率同时还与串行通信波特率有关。
/*********************************/
/* System Memory Control Register */
/**********************************/
#define DSRO (0<<2O)/*ROM BankO*/
#define DSR1 (0<<2)/*0:Disable,1:Byte;2:Half-Word;3:Word */
#define DSR2 (0<<4)
#define DSR3 (0<<6)
#define DSR4 (0<<8)
#define DSR5 (0<<10)
#define DSDO (2<<12)/*RAM Bank0*/
#define DSD1 (0<<14)
#define DSD2 (0<<16)
#define DSD3 (0<<18)
#define DSXO (0<<20)/* EXTIO0*/
#define DSX1 (0<<22)
#define DSX2 (0<<24)
#define DSX3 (0<<26)
#define rEXTDBWTH(DSR0|DSR1|DSR2|DSR3|DSR4|DSR5|DSD0|DSD1|DSD2|DSD3|DSXO|DSX1|DSX2|DSX3)
以上定义了系统存储器控制寄存器,按照以上定义,ROM/SRAM/FLASH Bank0定义为16位数据宽度(事实上,ROM/SRAM/FLASH Bank0的数据宽度由B0SIZE[1:0]的状态决定),而ROM/SRAM/FLASH Bank1~ROM/SRAM/FLASH Bank5禁用;DRAM/SDRAM Bank0定义为16位数据宽度,DRAM/SDRAM Bankl~DRAM/SDRAM Bank3禁用;外部I/O组全部禁用;若用户系统的存储器系统配置不同,应在此处修改。而且对各个寄存器的操作注意需要把它定义成volatile,避免编译器对相应的程序进行优化。这在对Flash进行编程的时候非常重要。
之后还做了其他一些改动,包括对ROM/SRAM/FLASH Bank0控制寄存器的设置,Flash容量的设置,DRAM/SDRAM Bank0控制寄存器的设置,SDRAM容量的设置等,这些设置均应该与用户系统对应。在修改SDRAM和Flash空间大小的时候不能忘的是还需要做的一个步骤是修改linux2.4.x/arch/arm/config.in中相应的宏定义。
5.3.3 uClinux的移植
BLOB 移植成功后,就开始移植uClinux。我们己经在移植BLOB的时候将uClinux的源代码安装在/path/to/armlinux/source目录下了。我们需要针对这个uClinux版本做必要的修改和配置,以适应我们的硬件平台。
uClinux内核采用模块化的组织结构,通过增减内核模块的方式来增减系统的功能,因此,正确合理的设置内核的功能模块,从而只编译系统所需功能的代码,会对系统的运行进行如下几个方面的优化:
l 用户根据自身硬件系统的实际情况定制编译的内核因为具有更少的代码,一般会获得更高的运行速度。
l 由于内核代码在系统运行时会常驻内存,因此,更短小的内核会获得更多的用户内存空间。
l 减少内核中不必要的功能模块,可以减少系统的漏洞,从而增加系统的稳定性和安全性。
下面是uClinux移植的过程。
(Ⅰ)uClinux的内核配置
在编译uClinux内核之前,首先要对内核进行配置。可以用make menuconfig进行内核的配置,要根据我们的板卡将必要的选项选中,将没有必要的选项去掉。
(1)系统类型的配置
在SystemType中,选定(S3C44BO)ARM system type,然后设置SDRAM/Flash的地址。
(2)通用内核选项General setup的配置
我们针对将来的应用选择了System V IPC等选项。
(3)块设备Block devices的选择和配置
我们选定RAM disk support并且设置RAMDISK的大小(Default RAM disk size)为1024KB,同时将它设置为Initial RAM disk(initrd)support。这样它就可以作为根文件系统的块设备。引导程序BLOB提供了RAMDISK的支持,使得使用和调试RAMDISK更加方便容易。
(4)文件系统的选择和配置
有了块设备,还要选择它上面的文件系统。首先选定/proc file system support,这是/proc文件系统,记录着系统运行时的信息。还要选定ROM file system support,这里我们选择ROM fs作为RAMDISK块设备上面的根文件系统(可以直接genromfs,即可生成所需大小的romfs,而不像RAMDISK一定要生成1024KB的映像)。然后选择Second extend fs support,这是设备ram0 ram1上所用的文件系统。
(5)选择字符设备驱动Character devices
这一步要选择串行口驱动,进入Serial drivers选项,然后选定S3C44B0 serial port support,选定Support for console on S3C44B0 serial port,将Default S3 C44B0 serial baudrate设置为115200。这样在内核中加入了对S3C44B0的串行口的支持, 就可以通过串口将内核打印的信息传递给主机。
至此完成了初步的uClinux内核的配置。
(Ⅱ)修改内核
这是uClinux内核移植中最关键的一步。下面我将列举出必要的文件,说明它们的用途以及应该怎么修改这些文件。其实这类文件的修改大部分只是需要修改些数值而已。现在己有众多的平台被uClinux支持,一些不得不写代码的修改也可以从一个类似的平台那得到参考。所以移植前,一般先找到一个类似的己经被内核支持的体系结构是十分重要的,这将简化uClinux内核的移植过程。
1)linux2.4.x/arch/$(ARCH)/Makefile
在这个文件中插入如下内容:
ifeq (( CONFIG_ARCH XXX),y )
MACHINE=xxx
endif
2)linux2.4.x/arch/$(ARCH)/boot/Makefile
在这里,将指定ZTEXTADDR(内核解压程序的开始地址)的值。一般uClinux内部针对某个平台都有一个解压程序,这个地址就决定了这个解压缩程序的存放的地址。如果想使用另外的程序来引导内核(如Bootload司则需要把此地址和Bootloade加载内核的地址保持一致。
3)linux2.4.x/arch/$(ARCH)/kernel/entry-armv.S
这里包含的是一些和平台有关的中断函数。在这里,得提供以下汇编宏:
disable_fiq、get_irgnr_and_base、irq_prio_table。通常disable_fiq宏和irq_ prio_table宏是空的。但是get_irgnr_and_base必须要小心实现,具体可以参看其他平台是怎么编写的。
4)linux2.4.x/arch/$(ARCH)/kernel/debug-armv.S
这个文件里提供的函数是一些底层的调试函数。这些函数直接和串口打交道, 而 不依赖于任何其他的内核功能或中断。当内核不启动的时候,可以利用这些函数。需要实现的函数有:adduart、senduart、waituart。adduart提供了串口的地址,senduart则是发送一字节数据到串口,waituart则提供的功能是等待串口把数据发送完毕。
5)linux2.4.x/arch/$(ARCH)/mach-xxxIMakefile
在这里添加在相同目录下的文件的编译的目标文件。范例文件如下:
+O_TARGET: = MACHINE.o
+obj-y : = arch.o irq.o mm.o
6)linux2.4.x/arch/$(ARCH)Imach-xxx/arch.c
这里包含的是一些体系相关的I/0初始化代码。具体可以参看其他平台下此文件的注释。
7)linux2.4.x/arch/$(ARCH)/mach-xxx/irq.c
提供一下函数的定义:
void xxx_mask_irq(unsigned int irq )
void xxx_unmask_irq(unsigned int irq )
void xxx_init_init()
8)linux2.4.x/arch/$(ARCH)/mach-xxx/mm.c
这个文件的实现的功能现在己经归并到arch.c中去了。
9)linux2.4.x/include/asm/$(ARCH)/dma.h
定义DMA通道和可以DMA访问的内存区域。在不支持DMA的平台上,可以把通道定义为0。文件内容如下:
#define MAX_DMA_ADDRESS OXFFFFFFFF
#define MAX_DMA_CHANNELS 0
10)linux2.4.x/include/asm/$(ARCH)/hardware.h
这是一个非常重要的文件,在这个文件中,我们定义了内存地址和大小,以及I/O地址等。所有和硬件相关的配置参数都在此定义。
11)linux2.4.x/include/as/$(ARCH)/io.h
这里定义如下宏:IO_SPACE_LIMIT、_io(addr)、_arch_getw(addr)、_arch_getw(data,addr)和一些其他的相关宏。
12)linux2.4.x/include/$(ARCH)/arch/irq.h
提供初始化中断的函数。这里,可能会用到在arch/arm/mach-xxx/irq.c中定义的宏。
13)linux2.4.x/include/asm/$(ARCH)/irgs.h
各个中断的中断号的定义处。
14)linux2.4.x/include/asm/$(ARCH)/memory.h
在这个文件中,有如下宏定义:_virt_to_bus(x),_bus_to_virt(x),_virt_to_ phys(x),_phys_to_virt(x),TASK_SIZE,TASK_SIZE_26,PHYS_OFFSET, PAGE_O FFSET,END_MEM等。一般来说,这个文件的内容各个平台的基本相同。所以可以参照其他平台的实现。
15)linux2.4.x/include/asm/$(ARCH)/param.h
在这定义时钟滴答频率HZ,以及NGROUPS,M AXHOSTNAMELEN等的值。如果这些参数没有被定义,那么就将在include/asm/param.h中定义。
16)linux2.4.x/include/asm/$(ARCH)/system.h
这个头文件将在arch/arm/kernel/process.c中被引用。在这个文件中,必须定义arch_idle()和arch_reset()两个函数。函数arch_idle()在处理器没有其他的线程的时候将被调用。而arch_reset则是在系统重启的时候被调用。这两个函数的实现依据硬件情况而定的。如果处理器有几种电源模式,则有可能需要更改arch_idle()的实现。在arch-idle()中把处理器的模式更改为低功耗模式,然后调用普通的CPU函数CPU_do_idle来处理CPU的一些常用事情。
这里,我们只改写了函数arch_reset(void)函数,使之正确跳转到Flash上的0地址重新执行。为了减少Cache的影响,在挑战以前,需先清空了Cache的内容, 解决重起后系统不能正确启动的错误。
17)linux2.4.x/include/asm/$(ARCH)/timex.h
这文件在include/asm/timex.h文件被引用。而include/asm/timex.h则又被inc lude/linux/timex.h引用。在include/asm/arch/timex.h中,我们需要定义时钟变量CLOCK_TICK_RATE。此变量决定了多少个时钟周期产生一个时间中断。一般这个变量需满足下面这个等式:
CLOCK_TICH_RATE=晶振频率/HZ
18)linux2.4.x/include/asm/$(ARCH)/uncompress.h
此文件中包含了几个串口操作函数,这些函数被内核解压程序(linux2.4.x/arch/$(ARCH)/boot/compressed/misc.c)利用来向串口输出信息。在这个文件中,要求提供两个函数,一个是arch_decompress_setup用来初始化串口;二是puts(),用来向串口输出信息。
19)linux2.4.x/include/asm/$(ARCH)/vmalloc.h
这个文件通常所有的平台都是一样的,一般只需要从别的平台那拷贝过来就行了。
20)linux2.4.x/arch/$(ARCH)/boot/compressed/xxx-head.S
在此文件中,初始化CPU和各种外围器件的配置。然后跳转到misc.c文件中进行内核解压。此文件和misc.c合在一起完成Bootloader的功能。在编译内核的时候可以把这两个文件单独编译成一个映像文件,并还可以在这两个文件中添加一些其他的功能。这样,一个Bootloader就完成了。
21)linux2.4.x/arch/$(ARCH)/boot/compressed/linux.lds.in
此链接控制文件控制着Bootloader和内核映像文件的链接过程。有时还会把Root文件系统的链接控制也放在此完成。
22) linux2.4.x/arch/$(ARCH)/vmlinux.lds.in
此文件控制内核映像文件的链接。引用了Symbol:TEXTADDR。
23) linux2.4.x/arch/$(ARCH)/Makefile
此文件控制着如何链接各个目录下的目标文件形成一个镜像文件,在这个文件中调用相应的程序,并给被调用的程序传递相应的配置文件,控制被调用的程序的行为。
24) linux2.4.x/arch/$(ARCH)/config.in
此文件控制了在配置内核参数的时候的各个候选项被选中之后的操作,如定义一些和某个平台相关的一些宏。
经过对上述文件的一些修改,一个基本的内核移植过程就算完成了,如果在编译内核的时候编译入适当的程序,应该可以看到内核启动信息了。这个内核的功能是不完全的,内核的移植还包括其他方面,如驱动程序的编写和修改等。
(Ⅲ)编译uClinux内核
对于编译uClinux,不能简单地通过make来实现。我们需要有一些特定的步骤才能保证编译的正确。这是因为uClinux所需要支持的硬件平台太多了,不能考虑的很周到。
为了编译最后得到的镜像文件,我们需要linux的内核以及romfs。对于我们的S3C44BOX的移植来说,romfs是被编译到内核里面去的。因此,在编译内核前需要一个romfs。为了得到romfs的image,我们又需要编译用户的应用程序。而为了编译用户的应用程序,我们又需要编译C运行库,这里我们用的C运行库是uClibc。
根据上面的分析,我们编译uClinux的步骤如下:
make dep
这个仅仅是在第一次编译的时候需要,以后就不用了,为的是在编译的时候知道文件之间的依赖关系,在进行了多次得编译后,make会根据这个依赖关系来确定哪些文件需要重新编译、哪些文件可以跳过。
make lib_only
编译uClibc。以后我们编译用户程序的时候需要这个运行库。
make user_only
编译用户的应用程序,包括初始化进程init,和用户交互的bash以及集成了很多程序的busybox(这样对一个嵌入式系统来说可以减少存放的空间,因为不同的程序共用了一套C运行库),还有一些服务,如boa(一个在嵌入式领域用的很多的Web服务器)和telnetd(telnet服务器,我们可以通过网络来登录我们的uClinux而不一定使用串口)。
make romfs
在用户程序编译结束后,因为我们用到的是romfs(一种轻量的、只读的文件系统)作为uClinux的根文件系统,所以首先需要把上一步编译的很多应用程序以uClinux所需要的目录格式存放起来。原来的程序是分散在user目录下.现在例如可执行文件需要放到bin目录、配置文件放在etc目录下等等,这些事就是make romfs所做的。它会在uClinux的目录下生成一个romfs目录并且把user目录下的文件、以及vendors目录下特定系统所需要的文件(我们的vendors目录是vendors/Samsung/44BOX )组织起来,以便下面生成romfs的单个镜像所用。
make image
它的作用有两个,一个是生成romfs的镜像文件,另一个是生成Linux的镜像。因为原来的Linux编译出来是elf格式的,不能直接用于下载或者编译(不过那个文件也是需要的,因为如果你需要,那个elf格式的内核文件里面可以包含调试的信息)。因此在这个时候由于还没有编译过Linux,因此在执行这一步的时候会报错。但是没
有关系,因为我们在这里需要的仅仅是romfs的镜像,以便在下面编译Linxu内核的
时候使用。
make linux
有了romfs的镜像我们就可以编译Linux了。因为我们的romfs是嵌入到linux内核中去了,所以在编译Linux内核的时候就要一个romfs.o文件。这个文件是由上面的make image生成的。
make image
这里再一次make image就是为了得到uClinux的可执行文件的镜像了。执行了这一步之后,就会在image、目录下找到3个文件:image.ram, image.rom, romfs.img。其中,image.ram和image.rom就是我们需要的镜像文件。其中,image.ram是直接下载到RAM执行的文件。如果你还处于调试阶段,那么就没有必要把文件烧写到FLASH里面。这个时候我们可以使用image.ram。对于image.rom来说,它是一个zlmage文件,也就是自解压的内核。由于它使用了gzip将内核压缩过,所以可以减小文件的大小。这个image应该烧写到FLASH的0x10000的位置,而不能直接下载到RAM并执行。
为了方便起见,在uClinux-dist目录下有两个文件:build_first.sh和build_f inal.sh先执行build_first.sh再执行build_final.sh就可以得到所需的镜像文件。之所以没有把两个合并,是因为第一次使用make image会出错。
(Ⅳ)配置生成uClinux的文件系统
在内核启动之后,就会将romfs作为根文件系统;而romfs中的应用程序需要保证有init和sh。这样在内核运行的最后,将有一个简单的shell界面,我们也可以向romfs中添加自己的应用。
将下载的uClinux-dist-20030305.tar.gz解压缩到宿主机上的一个目录下,准备配置编译使用这个uClinux-dist中的文件系统。在/uClinux-dist/目录下运行make menuconfig。
①选择配置选项。进入Target Platform Selection,选定Customize Vendor/User
Settings(NEW),然后exit保存,这样就可以只配置User setings了。
②配置User settings。在上一步之后,menuconfig进入到一个新的Main Menu-User settings的配置。首先进入Core Applications,选定init, enable console shell、 Sash等需要的应用程序,这一步至少要选上in然it和shell程序。后可以继续进入BusyBox,Filesystem Applications等选项进行配置, 最后退出保存。
③编译make clean dep linux。这一步我们只需要里面的文件系统部分。最后在./uClinux-dist目录下生成了romfs目录。里面的内容就是我们所需要的。
④查看编译结果的文件系统部分并进行修改。查看一下romfs目录下的每个目录,看看里面是不是所需要的文件,有没有缺少的文件。进入./romfs/dev/目录下,用MAKEDEV生成我们需要的设备文件console、ram0、ram1、ttyS0、ttyS1。再修改一些文件:/etc/rc和/etc/motd等。
⑤生成文件系统romfs.img。当修改结束后,就用genromfs生成文件系统romfs.img。这个romfs.img大小为几百KB,不应大于RAM DISK的大小(这里是1024KB),这个romfs.img就是我们所需要的文件系统了。
(Ⅴ)在开发板上运行uClinux
给开发板加电,系统自动开始运行BLOB。超级终端或者minicom显示了BLOB运行的信息,然后回车进入命令行状态,得到提示符blob>,用xdownload kernel下载zlmage。下载结束后,用xdownload ramdisk下载romfs.img。下载都结束后运行blob> boot会出现starting kernel,然后便是UncompressingLinux.......done,booting the kernel。内核正在开始启动。在启动的最后便是uClinux的欢迎信息和简单的shell提示符。
(Ⅵ)下载到开发板上的Flash中
目前,我们已经成功地在开发板上运行uClinux操作系统了。当uClinux内核比较稳定并不需要经常修改的时候,可以将它下载到开发板中的Flash中。此时可以继续为开发板开发它的应用,然后将应用加入到romfs中。当romfs不需要经常修改的时候它也被下载到开发板中的Flash中。这样便完成了开发板uClinux的移植。