显示标签为“嵌入式系统”的博文。显示所有博文
显示标签为“嵌入式系统”的博文。显示所有博文

2009年5月9日星期六

u-boot移植到mini2440,u-boot版本2008.10 - 转自hugerat的专栏

u-boot移植到mini2440,u-boot版本2008.10: "这篇文章写于2008.12.28日,主要记录了我移植u-boot-2008.10的过程,并附上了移植好的patch文件。移植好的u-boot-2008.10适用友善公司的mini2440和阳初公司的yc2410。其它的开发板,可能要根据相应的电路配置做稍许修改。我的移植是使用非nand-leagcy方法的,移植好的u-boot-2008.10功能除了基本功能外,加上了yaffs1映像的写入功能,加入了从nand flash启动的功能,改善了一些操作感受,往nand写入数据时,可以显示进度。在使用上要注意的是使用nand wirte.yaffs 命令写入yaffs1映像时,文
件长度参数一定要与yaffs1映像的大小完全一致,否则有可能产生假坏块。我的开发环境是vmware,kubuntu8.04。交叉编译是用crosstool0.43编译生成的arm-linux-gcc 4.1.0,libc 2.3.2。
(本人也成功移植了linux2.6.27.9到mini2440开发板上,有需要源码的,可以和我联系。EMAIL:nanjinrat@sohu.com,映像文件在此下载http://blog.chinaunix.net/u2/75270/showart.php?id=1796658)
一直想自已移植一套u-boot,但因为工作忙,一直都没有做,最近时间比较多,买了一套友善之臂的mini2440开发板,此板电路与该公司之前的QQ2440基本一至。而该开发板自带的u-boot的移植的还不很完善,于是下决心自已移植u-boot。要移植就用最新版的u-boot移植,于是决定在u-boot.2008.10版上进行移植,此版是2008年10月的新版,于之前的版本有较大改动,所以版本号也没有延续以前的编号方式,而改为2008.10。我的移植目的,是要能同时持S3C2440,S3C2410(手中还有一块阳初公司出的S3C2410开发板),从nand flash启动u-boot,因为目前大多数应用都是只有nand flash的,所以没打算从nor flash启动。支持tftp的使用,也就说要移植网卡的驱动,mini2440和阳初的s3c2410自带的linux都是使用yaffs文件系统作为根文件系统的,因此,u-boot还要能支持yaffs映像的烧写。在此我将移植过程记录下来,以方便大家在移植此版u-boot时参考。为了方便整个移植过程中的调试,我把移植过程分为0~6共7个阶段。每个阶段完成时,u-boot都是可以正常运行的,因此,你可以根据自已的要求,决定移植工作做到哪一阶段。为了同时支持S3C2440和S3C2410,我在移植时,同时加入两种代码,使用config_s3c2440,config_s3c2410这样的宏定义来决定编译哪种代码。如果你不需要同时支持两个CPU,你可以只加入一种代码。所有代码不在此列出,大家可以看我上传的移植好的u-boot。我在下面给出针对S3C2440移植的详细说明,S3C2410的移植比较简单,参考2440的移植即可,不另说明了。不同阶段的详细代码可以阅读patch文件。
第0阶段:
本阶段任务,是在u-boot系统中,建立起自已的开发板体系。我先建立mini2440板的体系。方法如下。hugerat是我的网名,你可以根据需要更改。
1 打开u-boot主目录下的makefile,找到smdk2410_config,在其下,仿照它的格式加入如下语句
rat2440_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t rat2440 hugerat s3c24x0
各项的意思如下:
arm: CPU的架构(ARCH)
arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。
rat2440: 开发板的型号(BOARD),对应于board/hugerat/rat2440目录。
hugerat: 开发者/或经销商(vender)。
s3c24x0: 片上系统(SOC)。
此步是为了加入自已的开发板,非必须也可以在现有的开发板基础上修改。
2修改CROSS_COMPILE为自已的arm gcc编译器,我使用的是系统默认的arm-linux-gcc,故不必再修改相应的CROSS_COMPILE项。
3 在/board子目录中建立自己的开发板rat2440目录由于我在上一步板子的开发者/或经销商(vender)中填了 hugerat ,所以开发板rat2440目录一定要建在/board子目录中的hugerat
目录下 ,否则编译会出错。
然后,将smdk2410目录下的文件考入此目录中。
并将其中的smdk2410.c改名为rat2440.c

还要记得修改自己的开发板rat2440目录下的Makefile文件,不然编译时会出错:
COBJS := rat2440.o flash.o
4 在include/configs/中建立配置头文件
将smdk2410的相应头文件复制一份在相同目录下。并改名为rat2440.h
5 回到u-boot主目录,make rat2440_config,再make,编译生成u-boot.bin成功。
建立S3C410板的方法同上,仅将2440改为2410即可。不重复了。
第0阶段完成。
第1阶段
本版u-boot依然没有提供对S3C2440的支持,因此本阶段任务是加入S3C2440相关的代码,使得u-boot可以在s3c2440上正常工作。但
没有增加任何附加功能。
在下列文件中加入标注为/*by hugerat,phase 1---*/的代码。其中,被注释掉的代码为原代码。
/cpu/arm920t/start.s (加入S3C2440的时钟相关的寄存器定义,加入时钟初始化代码,以使S3C2440工作在405MHz)
board/hugerat/rat2440/lowlevel_init.s(加入S3C2440内存控制寄存器的定义)
board/hugerat/rat2440/rat2440.c (修改GPIO,PLL的设置,应注意GPBCON的设置,不要让蜂鸣器响)
include/configs/rat2440.h(设定环境变量)
以下文件主要加入CONFIG_S3C2440宏定义以使得编译一些S3C2410的代码,和加入led灯的控制。以指示u-boot程序进程。
/inlcude/s3c24x0.h
cpu/arm920t/s3c24x0/interrupts.c(这里还要加入CONFIG_rat2440和CONFIG_rat2410)
/cpu/arm920t/s3c24x0/serial.c
cpu/arm920t/s3c24x0/speed.c
cpu/arm920t/s3c24x0/usb_ohci.c
/cpu/arm920t/s3c24x0/usb.c cpu/arm920t/s3c24x0/i2c.c
drivers/usb/usb_ohci.c
drivers/rtc/s3c24x0_rtc.c
/lib_arm/board.c
编译成功。将u-boot.bin烧入nor-flash即可运行。
但是为方便使用,同时,也是方便u-boot的调试。因此,我要将此u-boot代码再做一修改,使其可以在内存中运行。这样,可以用
开发板自带的vivi将其下载到内存中,再在内存中运行u-boot。要想它在内存中运行,方法很简单,将/root/u-boot-
1.3.1/cpu/arm920t中的start.s中
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
此段代码中的bl cpu_init_crit注释掉,即不进行CPU的初始化工作(此工作,当前在板子上运行的vivi已完成,故不能再次进行)
,即改为
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
@bl cpu_init_crit
#endif
修改/board/hugerat/rat2440/config.mk中text_base 值为0x33000000
使用vivi命令load ram 0x33000000 0x17ea8 x将u-boot.bin装入内存。再用go 0x33000000命令,即可。
至此,第1阶段工作完成。
第2阶段
本阶段任务,是给u-boot移植dm9000的网卡驱动。
u-boot自带网卡驱动,所以只要做些设置即可。
在下列文件中加入标志为/*by hugerat,phase 2----*/的代码.
/include/configs/rat2440.h (加入dm9000定义,加入ping命令定义)
此时,编译通过,但ping时,报`ethaddr' not set错误。
研究原代码,发现#define CONFIG_ETHADDR 08:00:3e:26:0a:5b被注释掉,恢复,并改变原来默认的IP地址。重新编译后,可以
ping通网络了。(也可以在u-boot启动后,修改相关参数,但因为现阶段还没有支持nandflash,参数无法保存,故在此改变较为方
便)
又发现,ping是能ping通了,但报could not establish link(不能建立链接)的错。不影响使用。参考网上的资料,发现这是因为
在网卡驱动中,/home/lijin/u-boot-rat/drivers/net/dm9000.c,有一段程序试图连接网卡的MII接口,而实际上MII接口并未使用
,所以有十秒的等待时间,且报错,将此段程序注释掉即可。
到此,本阶段任务完成。
第3阶段
本阶段任务,移植nand-flash驱动,注意此阶段工作仅是让u-boot可以操作读写nand flash。还不能让它从nand flash启动。
首先,要说明一下CFG_NAND_LEGACY的使用。在u-boot的/drivers/mtd/下有两个目录,分别是nand和nand_legacy。在nand目录下的
是nand的初始化函数和nand的操作读写函数,是使用linux的mtd构架的。此目录下的文件,只有在定义了CFG_CMD_NAND宏和没有定
义CFG_NAND_LEGACY宏的情况下才会被编译。在nand_leagcy目录下的文件也是是实现nand相关操作命令,如read,write等命令的功
能,但不是使用linux的mtd构架。此目录下的文件,只有在定义了CFG_CMD_NAND和定义了CFG_NAND_LEGACY宏的情况下才会定义。此
目录下的文件u-boot组织已不推荐使用。事实上,此版中,S3C2410构架已不支持对nand_leagcy,因此,我在移植中,是用的不定
义CFG_NAND_LEGACY的方式,即非nand_leagcy方式。
在/include/configs/rat2440.h中加标注为by hugerat,phase3的代码段,这段代码是让u-boot启用其自带nand flash驱动,并设置
相应的nand flash参数。
此时,试编译一下,通过。要说明的是,此版的u-boot已自带board_nand_init(),此函数在/cpu/arm920t/s3c24x0/nand.c中实现
。并且此版已不支持定义CFG_NAND_LEGACY,如定义此宏,则编译是会报 #error 'U-Boot legacy NAND support not available
for S3C2410'的错误。故此版已不能使用网上流传非nand_leagcy方式的自加nand flash初始化函数的方法,只能用其自带的初始化
函数
下载到内存中运行,报None nand devices!!!,这是当然的。因为S3C2410和S3C2440在FLASH控制器上,差别较大,必须改写代码。
改写主要在/cpu/arm920t/s3c24x0/nand.c中进行。(此文件内是与芯片紧密相关的代码),一是board_nand_init函数,一是
s3c2410_hwcontrol,参照2440的手册,改写相关代码。还要在此文件的开始部分加入S3C2440 nand flash控制器相关寄存器的定义
。改写的代码标注同上。改写完毕后,u-boot可以识别出nand flash芯片是64MB的,但还不能识别是什么芯片。
在/driver/mtd/nand/nand_base.c中的nand_get_flash_type函数结尾,修改MTDDEBUG语句,改为printf,再编译,可以正常显示芯
片了。但nand write功能不正常,即没报错,实际上也没有写进去。
探讨原因后发现,原来是u-boot自带的nand-flash驱动(不定义nand_leagcy),是基于mtd驱动的。在默认情况下,不进行写入正
确与否的校验。要定义CONFIG_MTD_NAND_VERIFY_WRITE宏才能进行写入校验。关于ECC校验,mtd驱动默认是用sotf_ecc的。加入宏
定义后,u-boot报write error了。
在此我卡了很久,最后才发现是u-boot.2008.10自带的S3C2410的s3c2410_hwcontrol函数有错。在此函数中,把chip->IO_ADDR_W值
改写了,导致在写数据时出现错误。将此错误修正后,nand write正常了。修正方法是使用一全局变量替代chip->IO_ADDR_W。
接下来,在rat2440.h中加入#define CONFIG_ENV_IS_IN_NAND 1注掉原来的#define CONFIG_ENV_IS_IN_FLASH 1,加入
#define CONFIG_ENV_OFFSET 0x30000 注掉原来的#define CFG_ENV_OFFSET 0x30000。编译。saveenv功能也正常了。
至此,nand-flash驱动移植完成。
测试,nand write 0x30000000 0x40000 0x40000时,成功。用nand read也成功读出。此处要说明的,如果用vivi烧写信息到nand
中,再用u-boot读取,会报错,应该是ECC校验不是由同一软件产生所至。
此阶段完成。
第4阶段
本阶段任务是将u-boot改写为从nand-flash启动。
首先,将/cpu/arm920t/start.s中第一阶段中为了从内存中启动而屏蔽掉的语句恢复。加入标注为/*by hugerat,phase 4----*/的
语句,为了兼容S3C2410,同时也加入S3C2410 nand boot 相关代码。同时,在/board/hugerat/rat2440/lower_init.s中,根据开
发板电路,对内存相关的几个寄存器定义进行调整。整个启动代码参考了vivi的代码。因此,将vivi的nand_read.c(支持S3C2440
的vivi,此文件中的读nand函数是直接操作nand flash的,与u-boot自带,适合用于启动时用。)考入/board/hugerat/rat2440目
录下。并修改目录下的makefile,使nand_read.c被编译。
编译,成功,将u-boot烧入nand flash,能成功从nand启动了。
第5阶段
本阶段任务是实现u-boot通过nfs引导友善提供的linux2.6.13的内核。
友善的linux并没有提供make uImage命令,需要添加。将u-boot的tools目录下的mkimage拷到开发机linux系统下的/usr/bin目录下
。在linux的/arch/arm/makefile中和/arch/arm/boot/makefile中,可以找到zImage的项目,仿照它添加uImage项目。
这个问题解决后,就是要用u-boot引导linux内核了,我用的是扬创提供的linux2.6.13的内核,扬创提供的内核,loadaddress和
entry都是30008000,我用u-boot1.2中的bootcmd参数,u-boot1.3.1 bootm却不能引导,报bad magic number,看了bootm的相关资
料,得知,如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核
运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。

2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm
xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去
运行之
(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。
Bootm在没有参数时,是采用rat2440.h中的#define CFG_LOAD_ADDR 的地址的,而我用bootm就是没有使用参数,所以出错了。正确
的做法应该是用nand read命令将内核从nand flash中读到内存的某一地址中(注意不要与其它已分配的内存冲突),然后再用
bootm 加地址参数,即可引导,也可以在上述的文件中,将CFG_LOAD_ADDR的地址定义为此地址,再用bootm就可以了.
我设定bootcmd环境变量为tftp 0x31000000 uImage; bootm 0x31000000,注意地址不能为0x30008000,否则报错.
做完这此,内核可以引导了,但却停在starting kernel不动了,好在我以前做过vivi+linux2.6.22的移植,知道此问题多半是由于
mach_type不同而造成的。在u-boot中,此mach_type是由rat2440.c中的这段代码定义的
#if defined(CONFIG_S3C2440)
/* arch number of S3C2440 -Board */
//gd->bd->bi_arch_number = 5244 ; //改为和内核的MACH_TYPE一至
gd->bd->bi_arch_number = MACH_TYPE_MINI2440 ;
#endif
你可以直接在这里改数字,也可以在include/asm-arm/mach_types.h的文件中,改MACH_TYPE_S3C2440的数值。将数值改为和内核的
mach_type一至。至于内核的mach_type可以在内核linux源代码下的arch/arm/tools中的mach_types文件查看到。
此时,又发现内核不能通过nfs引导。查资料后得知是因为u-boot没有传递参数给内核。原来是rat2440.h中少定义了几个宏。补上
。
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_INITRD_TAG 1
至此,u-boot已能正常引导linux启动了。第5阶段完成。
第6阶段
本阶段任务,是给u-boot加入烧写yaffs映像文件的功能。
网上有很多文章已经有介绍如何加入此功能,方法也不复杂。但我移植的u-boot.2008.10版,在nand flash的操作上与之前的版本
有了很大的区别。这些文章介绍的方法已不能在此版中应用。于是我只好自已根据u-boot的源代码,yaffs映像文件的格式,自已编
修改了u-boot.2008.10的代码,让它可以实现yaffs的烧写,因为我用的开发板的nand flash是k9f1208,只能使用yaffs1,所以我
的修改代码暂时只能支持yaffs1格式的映像。(要支持yaffs2也不难,但因为无法验证,所以就没有做尝试。)
修改方法如下:
在/common/com_nand.c中do_nand函数中,加入三段/*by hugerat,phase6---*/标注的代码,实现对nand write.yaffs命令的支持。
此代码中,要用到mtd_info结构中的两个变量,这两个变量本来是没有的,所以要在include/linux/mtd/mtd.h的mtd_info结构体定
义中加入。
在/drivers/mtd/nand/nand_util.c的nand_write_skip_bad函数中,两段程序,一段是为了计算正常数据的长度,一段是为了在写
入一段数据后,数据指针能正常跳到下一段数据。
在/drivers/mtd/nand/nand_base.c的nand_write函数中,加入一段把正常数据与oob数据分离的代码,再加入页写时的模式设置为
MTD_OOB_RAW,使页写时,不进行ECC的校验和加入。(ECC的校验在yaffs的oob数据中已自带了,不能重写。)此模式下,写入正常
数据后,会把oob数据缓存的数据写入nand的oob区。
至此,u-boot.2008.10的移植工作全部完成。
最后说明一下,关于阳初2410的移植,因为上面的代码中已加入S3C2410相关代码,移植时,只需参考S3C2440,新建一个开发板体
系,新建时,将rat2440目录下的文件拷贝到rat2410下,将重命名S3C2440.c为S3C2410.c,修改makefile,加上s3c2410.o 去掉
s3c2440.o,拷贝rat2440.h为rat2410.h,将其中的CONFIG_S3C2440注掉,加上CONFIG_S3C2410。在u-boot总目录下的makefile中
rat2440_config下添加
rat2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t rat2410 hugerat s3c24x0
因为阳初的板用的是cs8900,因此要在rat2410.h中注掉DM9000的定义,添加CS8900的。
再make rat2410_config,再make,即可。
文章最后,为方便网友,我把patch文件附上。patch文件使用方法是下载u-boot-2008.10.tar.bz2,在这里下载ftp://ftp.denx.de/pub/u-boot/,用tar -xvf u-bot-
2008.19.tar.bz2解压到u-boot-2008.10目录,把u-boot-rat.patch文件拷贝到此目录所在同级目录下。执行patch -p0 < u-boot-
rat.patch。完成后,进u-boot-2008.10目录,执行make rat2440_config,再make即可生成u-boot.bin,如是2410,则执行make
rat2410_config即可,我在mini2440,阳初的2410上试过,功能正常。其它开发板的也可一试。
附patch文件:
可以在此下载全部补丁"

u-boot 1.3.1移植,调试心得 - 转自hugerat的专栏

u-boot 1.3.1移植,调试心得: "u-boot 1.3.1移植,调试心得收藏



公司的项目用的是扬创的2440开发板。此板仅有u-boot.bin提供,而没有u-boot的源码,我依照开发板提供的电路图,根据公司项目的要求,对其电路进行了修改,添加,并重新绘制了印制板,用的是扬创的核心板加自已的底板的构架。硬件调试完毕后,问题来了,我需要在硬件一启动时,就要对某些口线进行初始化,可是因为扬创没有提供U-boot的源码,只好自已动手去移植一套源码了。

移植过程主要是根据网上一名为tekkaman(日本动画,宇宙骑士的主角,看来,此兄是一动漫迷)的高手提供的方法进行的,他不仅提供了方法,还把移植好的u-boot 1.3.1放在网上供人下载,真是要感谢他了。移植过程基本顺利。不过还是有一些问题,我将这此记录下来,以供参考。

移植时,tekkaman提供的代码解压,用其中的文件拷贝到原版的u-boot1.3.1目录中,如提示是否覆盖原文件,选覆盖。按照他的方法,对其进行编译配置,这步顺利完成。然后,编译,我用的是arm-linux 3.4.1,编译报错,又试用了3.3.2,2.95.3,均报错。查了资料,知道这是u-boot的浮点数类型引起,于是自已编译了一新的arm-linux 4.1版,是用crosstool0.43编译的。编译过程很顺利。完了,再用新编译的arm-linux4.1版对u-boot1.3.1编译,顺利通过。因为我的板子上是可以正常运行u-boot1.2的(扬创公司提供的u-boot),为了方便u-boot1.3.1调试,我想将u-boot1.3.1用1.2下载到内存中运行。查了网上的相关资料,试了多次,总算可以在内存中运行了,方法很简单,将/root/u-boot-1.3.1/board/tekkaman/tekkaman2440目录下的u-boot.lds文件中的text_base改为0x33000000,再将/root/u-boot-1.3.1/cpu/arm920t中的start.s中

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

bl cpu_init_crit

#endif

此段代码中的bl cpu_init_crit注释掉,即不进行CPU的初始化工作(此工作,当前在板子上运行的u-boot1.2已完成,故不能再次进行),即改为

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

@bl cpu_init_crit

#endif

在下面一段代码中增加一些语句

#ifdef CONFIG_S3C2440_NAND_BOOT





@ reset NAND

mov r1, #NAND_CTL_BASE

ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )

str r2, [r1, #oNFCONF]

ldr r2, [r1, #oNFCONF]



ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control

str r2, [r1, #oNFCONT]

ldr r2, [r1, #oNFCONT]



ldr r2, =(0x6) @ RnB Clear

str r2, [r1, #oNFSTAT]

ldr r2, [r1, #oNFSTAT]



mov r2, #0xff @ RESET command

strb r2, [r1, #oNFCMD]



mov r3, #0 @ wait

nand1:

add r3, r3, #0x1

cmp r3, #0xa

blt nand1



nand2:

ldr r2, [r1, #oNFSTAT] @ wait ready

tst r2, #0x4

beq nand2





ldr r2, [r1, #oNFCONT]

orr r2, r2, #0x2 @ Flash Memory Chip Disable

str r2, [r1, #oNFCONT]



@ get read to call C functions (for nand_read())

ldr sp, DW_STACK_START @ setup stack pointer

mov fp, #0 @ no previous frame, so fp=0



//增加的语句

adr r0, _start /* r0 <- current position of code */

ldr r1, _TEXT_BASE /* test if we run from flash or RAM */

cmp r0, r1 /* don't reloc during debug */

beq stack_setup

//////////////////////////////

@ copy U-Boot to RAM

ldr r0, =TEXT_BASE

mov r1, #0x0

mov r2, #0x30000

bl nand_read_ll

tst r0, #0x0

beq ok_nand_read

增加的语句是为判断是否是已在内存中运行u-boot,如是,则不进行下面一段将nand flash中的程序拷贝到内存中的操作(此操作在从nand flash中启动时,是必须的,而在内存中运行时,则不能使用,因为此时,nand flash中不一定是要调试的u-boot代码)

编译。完成后,使用tftp将u-boot.bin下载到板子的内存中,注意,内存地址一定是0x33000000,再用u-boot命令go 0x33000000,即可在内存中运行u-boot。解释一下为什么要这么做,u-boot的启动分两个阶段,第一阶段完成一些必须初始工作,此阶段是汇编写的,第二阶段则是进行一些较高级的操作,比如初始化板上的网卡芯片了,引导内核了什么的,这部分是用C写的。第一阶段的汇编程序在编写时,采用的是代码位置无关的方式,即无论代码的开头放在内存的哪一个地址,都可以从这个位置正常运行程序,而不管编译器在编译时认可的代码起始地址是什么。实际上,前面修改的text_base地址,就是编译器所认为的代码起始地址。U-boot中,第一阶段进入第二阶段是直接转入第二阶段的起始地址,而第二阶段的代码编写是与位置有关的,即代码起始地址必须与编译器认可的起始地址一至,才能正常运行。第二阶段的起始地址在编译完成后,即已确定,是相对于text_base的地址。那么我们将代码下载到text_base指定的地址中时,第二阶段代码的头就是在它应该在的位置上了。当我们从此text_base的地址处运行程序时,没有任何问题。而当此代码是从nand flash中运行时,第一阶段的起始地址为0,但因为第一阶段代码是位置无关,所以第一阶段代码可以正常运行,但第二阶段代码的头却不在它应该在的位置了,所以,第二阶段不能正常运行,因为,在第一阶段中,必须将u-boot自身拷贝到text_base的地址处,这样,第二阶段的代码就在它应该在的位置了,此时,第一阶段的程序可以顺利跳转到第二阶段运行了。这个过程,是我看了很资料后总结出来的。

完成此工作后,即可以在内存中运行u-boot了,但因为tekkaman的程序中,用的网卡芯片是DM9000,我用的是CS8900,所以要在tekkaman.h中,将DM9000的宏注释掉,将CS8900的宏开放。在此我犯了个错误,因为我一开始没有修改此处的宏编译的程序,而我在修改过宏以后,没有执行make clean就直接make,结果,网卡不能正常工作,总是报告cs8900 not found,试了多次不能解决,耽搁了一些时间。后来,在make clean后,再make,想不到问题解决了,想来是有些与cs8900想关的文件在修改过宏后没有重新编译所置。真是无语了。

这个问题解决后,就是要用u-boot引导linux内核了,我用的是扬创提供的linux2.6.13的内核,扬创提供的内核,loadaddress和entry都是30008000,我用u-boot1.2中的bootcmd参数,u-boot1.3.1 bootm却不能引导,报bad magic number,看了bootm的相关资料,得知,如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。

2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
(1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
(2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。

Bootm在没有参数时,是采用tekkaman.h中的#define CFG_LOAD_ADDR 的地址的,而我用bootm就是没有使用参数,所以出错了。正确的做法应该是用nand read命令将内核从nand flash中读到内存的某一地址中(注意不要与其它已分配的内存冲突),然后再用bootm 加地址参数,即可引导,也可以在上述的文件中,将CFG_LOAD_ADDR的地址定义为此地址,再用bootm就可以了,我最终就是这么用的。

做完这此,内核可以引导了,但却停在starting kernel不动了,好在我以前做过vivi+linux2.6.22的移植,知道此问题多半是由于mach_type不同而造成的。在u-boot中,此mach_type是由tekkaman.c中的这段代码定义的

#if defined(CONFIG_S3C2440)

/* arch number of S3C2440 -Board */

gd->bd->bi_arch_number = 5244 ; //改为和内核的MACH_TYPE一至

//gd->bd->bi_arch_number = MACH_TYPE_S3C2440 ;

#endif

你可以象我一样直接在这里改数字,也可以在include/asm-arm/mach_types.h的文件中,改MACH_TYPE_S3C2440的数值。将数值改为和内核的mach_type一至。至于内核的mach_type可以在内核linux源代码下的arch/arm/tools中的mach_types文件查看到。

重新编译下载u-boot1.3.1后,内核正常引导了。到此,u-boot1.3.1的移植告一段落。下面,我要做的是移植yaffs,使u-boot1.3.1可以支持yaffs文件的烧写。"

2009年5月7日星期四

C-Kermit安装和使用及下载内核方法

C-Kermit安装和使用及下载内核方法

C-Kermit的安装和使用过程。

1、先到http://www.columbia.edu/kermit/ck80.html#download来下载C-Kermit。如果你下载的是cku211.tar.gz的话,执行:

gunzip cku211.tar.gz

tar xvf cku211.tar

rm -rf cku211.tar

make linux

mv wermit /usr/local/bin/kermit

执行以上命令,就可以在终端上输入kermit就可运行了。

2. 运行kermit后要对其配置才能下载内核,如:

set line /dev/ttyS0

set speed 115200

set carrier-watch off

set handshake none

set flow-control none

robust

set file type bin

set file name lit

set rec pack 1000

set send pack 1000

set window 5

使用以下命令:connect

就可以使用串口了,进入串口和minicom一样。

切换:按下Ctrl + \ ,再按c 就跳回kermit。跳回串口控制,可以输入c,即connect命令。

发送文件:

kermit中输入connect后,跳到u-boot串口界面。

输入loadb 0x0c008000 回车

按下 ctrl + \ ,再按c,切换到kermit。

输入命令:send /home/zImage

kermit开始传送数据了,并可以看到传送进度,发送完后,输入c,再回到u-boot界面,然后,再输入:go 0x0c008000

内核开始运行了

kermit在启动时会查找~/.kermrc文件,调用里面的命令来初始化kermit。只要将你所需的命令写到~/.kermrc文件里,启动后就不这么麻烦了。

# vi ~/.kermrc

set line /dev/ttyS0
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set file name lit
set rec pack 1000
set send pack 1000
set window 5
c

保存后退出即可。然后启动kermit,你会看到:

# kermit
Connecting to /dev/ttyS0, speed 115200
Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options."

ELDK开发手册 - 自由的风

ELDK开发手册 - 自由的风:

1. 概要
这是嵌入式PowerPC, ARM和MIPS系统中使用DENX U-Boot和Linux的指导手册。文档中描述了如何在嵌入式PowerPC, ARM和MIPS系统上配置、编译、使用Das U-Boot(常常缩写为“U-Boot”)和Linux操作系统。文档中涵盖了所有你可能需要的用于配置、编译、运行U-Boot和Linux的工具。

2. 绪论
首先,我们介绍如何安装交叉编译开发工具Embedded Linux Development Kit(ELDK),这个开发套件你很有可能会用到——至少当你在标准的x86 PC上使用Linux或者Sun Solaris系统作为开发环境的时候,你会需要它的。
然后,我们会阐述通过串口与你的目标板连接:你需要配置一个终端控制程序,如cu或者kermit。
你常常需要通过网线把映像文件下载到你的目标板上。为了实现这个目的,你需要TFTP和DHCP/BOOTP服务器。文档中提供了简要的相关配置说明。
接下来则是描述如何配置和编译U-Boot使之适用于某个特定的平台,以及如何安装和在该硬件平台上运行。
下一步的工作是配置、建立和安装Linux。我们使用SELF(Simple Embedded Linux Framework)来展示如何建立一个开发环境(包括通过NFS挂载的根文件系统)和一个嵌入式目标板配置(从基于busybox的ramdisk映像文件中运行)。
本文档不会给出如何把U-Boot或者Linux移植到一个新的硬件平台,而是默认你的开发板已经被U-Boot和Linux所支持。
本手册各种文档格式的最新版本可以从以下网址获取:
· HTML http://www.denx.de/wiki/publish/DULG/DULG-canyonlands.html
· plain ASCII text http://www.denx.de/wiki/publish/DULG/DULG-canyonlands.txt
· PostScript European A4 format http://www.denx.de/wiki/publish/DULG/DULG-canyonlands.ps
· PDF European A4 format http://www.denx.de/wiki/publish/DULG/DULG-canyonlands.pdf

3. 嵌入式Linux开发工具套件
嵌入式Linux开发工具套件(ELDK)包括GNU交叉开发工具,如编译器、binutils、gdb等工具,和一些已经编译好的目标工具以及负责提供在目标平台上函数调用的库文件。还免费提供了所有的源代码,包括全部补丁、扩展文件、以及用于编译开发工具使用的程序和脚本。安装包都是基于RPM包管理器。
3.1 获取ELDK
可以通过以下方式获得ELDK。
·DENX计算机系统光盘
·从以下服务器中下载
FTP方式
ftp://mirror.switch.ch/mirror/eldk/eldk/
ftp://sunsite.utk.edu/pub/linux/eldk/
ftp://ftp.sunet.se/pub/Linux/distributions/eldk/
ftp://ftp.leo.org/pub/eldk/
HTTP方式
http://mirror.switch.ch/ftp/mirror/eldk/eldk/
http://ftp.sunet.se/pub/Linux/distributions/eldk/
http://archiv.leo.org/pub/comp/os/unix/linux/eldk/
3.2 初始安装
初始安装可以使用放在ELDK目录树根目录下的安装工具。安装工具使用语法如下;
$ ./install [-d <dir>] [<cpu_family1>] [<cpu_family2>] …
-d <dir> 确定ELDK安装在哪个目录。如果省略ELDK会安装在当前目录。
<cpu_family> 确定目标平台的CPU。如果此项设置了一项以上的参数,则会将这些CPU的支持都安装。如果省略将会安装所有CPU的支持。你也可以把ELDK安装到任何空目录下,这么做的唯一条件是你有那个目录的写和执行权限。安装过程并不需要超级用户的特权。由安装时的参数决定安装几个目标组件集合。ELDT包是肯定会安装的。
$ export CROSS_COMPILE=ppc_4xx- //加入环境变量
$ PATH=$PATH:/opt/eldk/usr/bin:/opt/eldk/bin //加入PATH
这样加入的话,每次重启系统后必须重新加入,一劳永逸的办法是编辑/root/.bashrc
加上
export CROSS_COMPILE=ppc_4xx-
export PATH=$PATH:/opt/eldk/usr/bin:/opt/eldk/bin
重启系统后即可使用ELDK。

4. 系统设置
在目标平台上安装和配置U-Boot和Linux需要一些工具。特别是在开发过程中,你需要和目标平台保持联系。这一节将告诉你如何配置你的主机以达到上述目的。
4.1 设置串口
为了更好地使用U-Boot和Linux,你需要通过串口将目标板和你的主机连接。U-Boot和Linux可以配置成自动执行而不需要任何用户的干涉。
通过串口有很多种方法来控制你的目标板,比如说使用终端服务器。不过最常见的做法是使用你本机的串口,这时,你主机需要安装一个终端程序,如cu或者kermit。
4.2 配置“kermit”
kermit这个名字就代表了它是连接串口和网络的通信软件。事实上在很多计算机和操作系统上使用它,能够很好地满足我们的目的。
kermit在执行其它命令之前,会执行你的用户目录下的初始文件.kermrc,所以可以非常简单的通过初始化命令来定制kermit。下面是使用U-Boot和Linux时推荐配置:
~/.kermrc:
set line /dev/ttyS0
set speed 115200
set carrier-watch off
set handshake none
set flow-control none
robust
set file type bin
set file name lit
set rec pack 1000
set send pack 1000
set window 5
这个设置假定你使用的是主机第一个串口(/dev/ttyS0),以115200这个波特率与目标板的串口连接。
然后你可以连接目标板了:
$ kermit -c
Connecting to /dev/ttyS0, speed 115200.
The escape character is Ctrl-\ (ASCII 28, FS)
Type the escape character followed by C to get back,
or followed by ? to see other options.
—————————————————-
下载kermit这个软件时,你会发现有两个kermit包。你只需要安装ckermit。其中gkermit仅仅是实现kermit传输协议的一个命令行工具。如果你主机上的Linux系统没有安装kermit,你可以到kerimt的官方网站 http://www.columbia.edu/kermit/ 下载。
4.3 使用minicom
minicom是另外一种非常流行的串口通信终端。很遗憾的是,很多用户发现在使用U-Boot和Linux时,minicom有很多问题,尤其是试图使用它来下载image的时候。因此,不推荐大家使用minicom。
4.4 配置TFTP服务器
使用U-Boot下载Linux内核或者应用程序的最快捷的方法是通过网络传输。为了这一目的,U-Boot实现了TFTP协议(参见U-Boot中的tftpboot命令)。为了使主机支持TFTP,你必须确保TFTP后台程序/usr/sbin/in.tftpd已经安装。在RedHat系统中,你可以运行下面的命令来确认:
$ rpm -q tftp-server
如果没有安装,请从你的Linux安装盘或者其它媒介安装。
大多数的Linux发行版都默认关闭TFTP服务。以RedHat系统为例,如果要使能TFTP服务,编辑文件/etc/xinetd.d/tftp,移除这一行:
disable = yes
或者注释掉它,或者修改disable = no
此外,确保/tftpboot目录存在,而且有访问权限(至少应该'dr-xr-xr-x')。

5. Das U-Boot
5.1 当前版本
Das U-Boot(或者简称“U-Boot”)是针对嵌入式PowerPC, ARM, MIPS和x86处理器的开放源代码软件。U-Boot项目已经在Sourceforge设立,你可以访问这个官方网站:http://www.denx.de/wiki/UBoot
U-Boot最新版的源代码可以在Sourcefoge通过匿名CVS得到。当要求输入匿名用户anonymous的密码时只需要直接按下回车键。
$ cvs -d:pserver:anonymous@www.denx.de:/cvsroot login
$ cvs -z6 -d:pserver:anonymous@www.denx.de:/cvsroot co -P u-boot
官方发布的U-Boot也可以通过FTP方式获取。你可以到ftp://ftp.denx.de/pub/u-boot/下载tar形式的压缩包。
或者通过git的方式获取:
git clone git://www.denx.de/git/u-boot.git u-boot/
git clone http://www.denx.de/git/u-boot.git u-boot/
git clone rsync://www.denx.de/git/u-boot.git u-boot/
5.2 源代码包的解压
如果你是通过CVS得到的U-Boot源代码,你可以跳过这一步,因为你得到的已经是解压后的目录树了。如果你是从FTP服务器上下载的tar压缩包,那么你需要按照以下步骤解压:
$ cd /opt/eldk/usr/src
$ wget ftp://ftp.denx.de/pub/u-boot/u-boot-1.3.2.tar.bz2
$ rm -f u-boot
$ bunzip2 < u-boot-0.4.5.tar.bz2 | tar xf -
$ ln -s u-boot-0.4.5 u-boot
$ cd u-boot
5.3 配置
$ export BUILD_DIR=/opt/eldk/build //指定编译的输出目录
进入U-Boot源代码根目录后,可以先使用如下命令确保已经清除以前编译的结果:
$ make distclean
下一步是为Makalu板配置U-Boot:
$ make makalu_config
(译者注:应该根据你自己的具体开发板配置,如$ make <yourboard>_config,如果没有相应的开发板,应该自己照着建立相应的目录和配置文件。)
最后我们可以开始编译U-Boot了:
$ make all
5.4 安装
5.4.1 动手之前
5.4.1.1 安装所需
以下的章节假定你的开发板使用flash作为存储设备。如果不是,则以下的指令不会工作。如果你想使用U-Boot,需要换掉存储设备。
5.4.1.2 开发板识别数据
所有的Makalu开发板使用一个序列号加以识别。而且开发板需要分配一个以太网MAC地址。如果这些数据丢失,你可能会失去授权。在安装U-Boot或者改变开发板的配置之前,你需要搜集足够的信息。
5.4.2 使用BDM/JTAG调试器安装U-Boot.bin
把数据烧入flash中的一个简单而又快速的办法是通过BDM或者JTAG接口的调试器或者flash烧写器。当flash中没有任何数据(比如说一块新的开发板),这种方法是唯一的选择。
我们(强烈推荐)使用Abatron公司的BDI2000(见http://www.abatron.ch/BDI/bdiGDB.html )。
其它的BDM/JTAG调试器也可以使用,但是如何操作它们不是本文档要讨论的范围。如果你想使用别的工具请参照它们的说明文档。(我没有使用BDI2000,故略去操作BDI2000的方法。我烧写u-boot.bin就是简单地通过JTAG口。)
5.4.3 使用U-Boot安装U-Boot.bin
如果U-Boot已经在你的板子上安装运行,你可以使用这些命令来下载新的U-Boot映像来代替当前的。
警告:在你安装新的映像之前,你必须擦除当前的u-boot.bin。如果出现什么差错,你的开发板将不能运行。因此强烈建议:
做一个能工作的U-Boot映像文件的备份;
你清楚如何在一个新的开发板上安装u-boot.bin。
过程如下:
=> tftp 100000 /tftpboot/uboot.bin
ARP broadcast 1
TFTP from server 10.0.0.2; our IP address is 10.0.0.100
Filename ””/tftpboot/uboot.bin””.
Load address: 0×100000
Loading: ###############################
done
Bytes transferred = 155376 (25ef0 hex)
=> protect off 40000000 4003FFFF
Un-Protected 5 sectors
=> era 40000000 4003FFFF
Erase Flash from 0×40000000 to 0×4003ffff
……… done
Erased 5 sectors
=> cp.b 100000 40000000 $(filesize)
Copy to Flash… done
=> setenv filesize
=> saveenv
Saving Enviroment to Flash…
Un-Protected 1 sectors
Erasing Flash…
.. done
Erased 1 sectors
Writing to Flash… done
Protected 1 sectors
=> reset
5.5 工具的安装
U-Boot加载Linux内核、Ramdisk或者其它映像时使用一种特殊的映像格式。这种格式包含了一些信息,如创建时间、操作系统、压缩格式、映像类型、映像名和CRC32校验和。
mkimage用来创建这种格式的映像文件或者显示它包含的信息。如果使用ELDK,那么mkimage这个命令已经包含在ELDK中。
如果你不想使用ELDK,你应该把mkimage安装在某个能够直接执行的目录里,比如:
$ cp tools/mkimage /usr/local/bin/
5.6 初始化
初始化你的Makalu板上的U-Boot,你需要通过终端连接板子的串口。
Makalu板的串口默认配置是波特率为115200/8N1(115200bps,每个字符8bit,无奇偶校验,1bit停止位,无握手)。
如果你的主机是Linux操作系统,我们建议你用kermit或者cu作为终端控制程序。确定硬件和软件控制流都已经关闭。
5.7 开始的步骤
在默认配置中,U-Boot运行在一种互动模式,它通过串口“UART1”提供命令行形式的用户接口。
这意味着U-Boot显示一个提示符(默认是:=>),等待着接受用户的输入。然后你输入一个命令,按下回车键。U-Boot将运行这个命令,然后又出现提示符等待下一条命令。
你可以使用help(或者简单地一个?)来查看所有的U-Boot命令。它将会列出在你当前配置下所有支持的命令。[请注意到尽管U-Boot提供了很多配置选项,并不是所有选项都支持各种处理器和开发板,有些选项可能在你的配置中并没有被选上。]
=> help
? - alias for ‘help’
askenv - get environment variables from stdin
autoscr - run script from memory
base - print or set address offset
bdinfo - print Board Info structure
boot - boot default, i.e., run ‘bootcmd’
bootd - boot default, i.e., run ‘bootcmd’
bootelf - Boot from an ELF image in memory
bootm - boot application image from memory
bootp - boot image via network using BootP/TFTP protocol
bootstrap - program the I2C bootstrap EEPROM
bootvx - Boot vxWorks from an ELF image
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
date - get/set/reset date & time
dhcp - invoke DHCP client to obtain IP/boot params
dtt - Digital Thermometer and Thermostat
echo - echo args to console
eeprom - EEPROM sub-system
erase - erase FLASH memory
exit - exit script
ext2load- load binary file from a Ext2 filesystem
ext2ls - list files in a directory (default /)
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls - list files in a directory (default /)
fdt - flattened device tree utility commands
flinfo - print FLASH memory information
getdcr - Get an AMCC PPC 4xx DCR’s value
getidcr - Get a register value via indirect DCR addressing
go - start application at address ‘addr’
help - print online help
icrc32 - checksum calculation
iloop - infinite loop on address range
imd - i2c memory display
iminfo - print header information for application image
imls - list all images found in flash
imm - i2c memory modify (auto-incrementing)
imw - memory write (fill)
imxtract- extract a part of a multi-image
inm - memory modify (constant address)
iprobe - probe to discover valid I2C chip addresses
irqinfo - print information about IRQs
isdram - print SDRAM configuration information
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loady - load binary file over serial line (ymodem mode)
loop - infinite loop on address range
loopw - infinite write loop on address range
md - memory display
mdc - memory display cyclic
mii - MII utility commands
mm - memory modify (auto-incrementing)
mtest - simple RAM test
mw - memory write (fill)
mwc - memory write cyclic
nand - NAND sub-system
nboot - boot from NAND device
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
pci - list and access PCI Configuration Space
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
rarpboot- boot image via network using RARP/TFTP protocol
reginfo - print register information
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setdcr - Set an AMCC PPC 4xx DCR’s value
setenv - set environment variables
setidcr - Set a register value via indirect DCR addressing
sleep - delay execution for some time
test - minimal test like /bin/sh
tftpboot- boot image via network using TFTP protocol
usb - USB sub-system
usbboot - boot from USB device
version - print monitor version
=>使用help <command>你可以得到更多的命令信息:
=> help tftpboot
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
=>
=> help setenv printenv
setenv name value …
- set environment variable ‘name’ to ‘value …’
setenv name
- delete environment variable ‘name’
printenv
- print values of all environment variables
printenv name …
- print value of environment variable ‘name’
=>
大多数命令可以缩写,只要字符串的内容仍然可以被确定:
=> help fli tftp
flinfo
- print information for all FLASH memory banks
flinfo N
- print information for FLASH memory bank # N
tftpboot [loadAddress] [[hostIPaddr:]bootfilename]
=>
5.8 首次上电
把主机指定的串口和在Makalu板上标有UART1的端口连接,运行终端程序,给Makalu板接上电源。你可以看到如下信息:
=> reset
U-Boot 1.3.3-rc2-01466-g4f27098 (May 1 2008 - 13:57:57)
CPU: AMCC PowerPC 460EX Rev. A at 600 MHz (PLB=200, OPB=100, EBC=100 MHz)
Security/Kasumi support
Bootstrap Option H - Boot ROM Location I2C (Addr 0×52)
Internal PCI arbiter disabled
32 kB I-Cache 32 kB D-Cache
Board: Canyonlands - AMCC PPC460EX Evaluation Board, 2*PCIe, Rev. 13
I2C: ready
DTT: 1 is 48 C
DRAM: 256 MB (ECC not enabled, 400 MHz, CL3)
FLASH: 64 MB
NAND: 32 MiB
PCI: Bus Dev VenId DevId Class Int
PCIE0: link is not up.
PCIE0: initialization as root-complex failed
PCIE1: link is not up.
PCIE1: initialization as root-complex failed
Net: ppc_4xx_eth0, ppc_4xx_eth1
Type run flash_nfs to mount root filesystem over NFS
Hit any key to stop autoboot: 0
=>
=>
你可以按下任意键来中止倒计数。如果你不那么做,你可能会看到一些(无关紧要的)错误,因为系统没有初始化。
有时你可能会看到一种信息:
*** Warning - bad CRC, using default environment
这条信息没有害处,只要你初始化和保存环境变量之后,它就不会出现了。
首先,你必须输入你的开发板的序列号和网卡地址。需要特别注意的是,这些参数是写保护的,一旦保存了就无法改变(通常制造商已经设置好了)。使用U-Boot的setenv命令可以输入数据,命令后面跟上变量名和值,参数之间用空格(或者Tab符)隔开。例如,使用变量名serial#设置开发板的ID或者说序列号,变量名ethaddr用于设置以太网地址:
=> => setenv ethaddr !!!!!!FILL_THIS!!!!!!
=> setenv serial# CF56-216F-400A
使用printenv确认你已经输入正确的值:
=> printenv serial# ethaddr
## Error: 'serial#' not defined
ethaddr=5e:ed:18:38:81:85
=>
请仔细核查显示值是否正确!等保存之后你将不能更正任何错误。如果发现错误,请重新启动开发板。如果检查无误,你可以使用saveenv命令永久保存这些参数。
=> saveenv
Saving Environment to Flash…
Un-Protected 1 sectors
Un-Protected 1 sectors
Erasing Flash…
. done
Erased 1 sectors
Writing to Flash… done
Protected 1 sectors
Protected 1 sectors
=>
5.9 U-Boot命令介绍
这一节将介绍U-Boot中最重要的指令。U-Boot可配置性非常强,所以并不是所有的命令都已经在你的硬件平台上安装,此外可能也有这儿没提到的命令。你可以使用help命令来显示根据你的配置所有可用的命令列表。
对于大多数命令,你不必打全这些命令,只需输入一些字符足以。比如,help可以简写为h。
一些命令的执行依赖于U-Boot的配置以及U-Boot中一些环境变量的定义。
所有的U-Boot命令都把输入的数字当作十六进制的格式。
不要使用除了退格键之外的其它编辑键,因为在诸如环境变量中隐藏的字符是很难被发现的。
具体命令略

6. Linux内核的编译
6.1 下载Linux内核
可以通过git下载到最新的内核,命令如下:
$ cd /opt/eldk/usr/src
$ git clone git://www.denx.de/git/linux-2.6-denx.git linux-2.6-denx
$ cd linux-2.6-denx
6.2 内核的配置及编译
下面的步骤需要powerpc的交叉开发工具,所以您必须确认您的PATH变量中有ELDK的编译工具的地址。
首先使用下面的命令清除以前的编译信息:
$ make mrproper
使用下面的命令导入适合Makalu开发板的默认配置,这些配置是经过官方多次测试的:
$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- makalu_defconfig //导入默认配置
注:这些默认的配置文件位于arch/powerpc/configs/XXX_defconfig ,根据您的开发板的型号选择。如果找不到相应的配置文件,可以去arch/ppc/configs/中寻找相应的配置文件,那里还有一些。makalu_defconfig这个就是位于arch/ppc/configs/下面,而arch/powerpc/configs/中没有。
当然您还可以自己去修改内核的配置,使用如下命令:
$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- config //手动改动配置
或者
$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- menuconfig //手动改动配置
注:因为一些问题(尤其是老版本的内核),'make xconfig'这个命令不被推荐
使用下面的命令编译内核:
$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- uImage //编译
编译生成的目标文件uImage是通过mkimage(位于U-Boot包中) 创建的,位于/opt/eldk/usr/src/linux-2.6-denx/arch/powerpc/boot/uImage,它可以通过U-Boot来下载和引导
配置和安装模块使用如下命令:
$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- modules
$ make ARCH=powerpc CROSS_COMPILE=ppc_4xx- INSTALL_MOD_PATH=/opt/eldk/ppc_4xx modules_install
6.3 安装
将文件复制到tftpboot目录下面,然后通过tftp烧写:
$ cp arch/powerpc/boot/uImage /tftpboot/uImage

7. 根文件系统的设计与编译
7.1 根文件系统的设计
嵌入式开发中根文件系统的设计并不是很容易的事,主要的问题是:
(1)里面要包括哪些内容
(2)使用哪种文件系统类型
(3)怎样存储和引导
现在假设根文件系统中的内容我们已经知道,那么我们主要关注后面两点。
我们使用ELDK安装时生成的镜像 SELF (Simple Embedded Linux Framework),它位于 /opt/eldk/<architecture>/images/ 文件夹下,ramdisk_image.gz这个文件便是。
(1)解压ramdisk:
$ gzip -d -c -v /opt/eldk/ppc_4xx/images/ramdisk_image.gz >/tmp/ramdisk_image //解压
(2)挂载ramdisk
$ mount -o loop /tmp/ramdisk_image /mnt/tmp //挂载
(3)创建压缩文件,为了避免下面步骤需要root权限,不包括设备文件
$ cd /mnt/tmp
$ tar -zc –exclude=’dev/*’ -f /tmp/rootfs.tar.gz * //创建tarball,为了避免下面步骤需要root权限,不包括设备文件
(4)将设备文件创建成单独的压缩文件(使用cramfs)
$ tar -zcf /tmp/devices.tar.gz dev/ //将设备文件创建成单独的tarball
$ cd /tmp
(5)取消挂载
$ umount /mnt/tmp //取消挂载
7.2 根文件系统的编译
我们使用ramdisk的形式来生成根文件系统的镜像文件,一般情况下,它使用ext2文件系统。
(1)创建目录,解压压缩文件
$ cd /opt/eldk/
$ mkdir rootfs
$ cd rootfs
$ tar zxf /tmp/rootfs.tar.gz
(2)我们使用genext2fs来创建ramdisk镜像文件,因为它使用一个简单的文本文件来描述设备,因而不需要root权限。使用设备表rootfs_devices.tab:
#<name> <type> <mode> <uid> <gid> <major> <minor> <start> <inc> <count>
/dev d 755 0 0 - - - - -
/dev/console c 640 0 0 5 1 - - -
/dev/fb0 c 640 0 0 29 0 - - -
/dev/full c 640 0 0 1 7 - - -
/dev/hda b 640 0 0 3 0 - - -
/dev/hda b 640 0 0 3 1 1 1 16
/dev/kmem c 640 0 0 1 2 - - -
/dev/mem c 640 0 0 1 1 - - -
/dev/mtd c 640 0 0 90 0 0 2 16
/dev/mtdblock b 640 0 0 31 0 0 1 16
/dev/mtdr c 640 0 0 90 1 0 2 16
/dev/nftla b 640 0 0 93 0 - - -
/dev/nftla b 640 0 0 93 1 1 1 8
/dev/nftlb b 640 0 0 93 16 - - -
/dev/nftlb b 640 0 0 93 17 1 1 8
/dev/null c 640 0 0 1 3 - - -
/dev/ptyp c 640 0 0 2 0 0 1 10
/dev/ptypa c 640 0 0 2 10 - - -
/dev/ptypb c 640 0 0 2 11 - - -
/dev/ptypc c 640 0 0 2 12 - - -
/dev/ptypd c 640 0 0 2 13 - - -
/dev/ptype c 640 0 0 2 14 - - -
/dev/ptypf c 640 0 0 2 15 - - -
/dev/ram b 640 0 0 1 0 0 1 2
/dev/ram b 640 0 0 1 1 - - -
/dev/rtc c 640 0 0 10 135 - - -
/dev/tty c 640 0 0 4 0 0 1 4
/dev/tty c 640 0 0 5 0 - - -
/dev/ttyS c 640 0 0 4 64 0 1 8
/dev/ttyp c 640 0 0 3 0 0 1 10
/dev/ttypa c 640 0 0 3 10 - - -
/dev/ttypb c 640 0 0 3 11 - - -
/dev/ttypc c 640 0 0 3 12 - - -
/dev/ttypd c 640 0 0 3 13 - - -
/dev/ttype c 640 0 0 3 14 - - -
/dev/ttypf c 640 0 0 3 15 - - -
/dev/zero c 640 0 0 1 5 - - -
具体的格式描述请参见genext2fs的帮助文档。
(3)使用genext2fs来创建一个ext2文件系统的镜像:
$ ROOTFS_DIR=/opt/eldk/rootfs # 路径
$ ROOTFS_SIZE=8192 # 文件系统镜像的大小,如果此值太小,当生成的文件超过此值时,会报错
$ ROOTFS_FREE=100 # free space wanted
$ ROOTFS_INODES=380 # number of inodes
$ ROOTFS_DEVICES=rootfs_devices.tab # device description file
$ ROOTFS_IMAGE=ramdisk.img # generated file system image
$ genext2fs -U \
-d ${ROOTFS_DIR} \
-D ${ROOTFS_DEVICES} \
-b ${ROOTFS_SIZE} \
-r ${ROOTFS_FREE} \
-i ${ROOTFS_INODES} \
${ROOTFS_IMAGE}
(4)压缩文件
$ gzip -v9 ramdisk.img
(5)创建适合U-Boot的images:
$ mkimage -T ramdisk -C gzip -n ‘Test Ramdisk Image’ \>
-d ramdisk.img.gz uRamdisk

至此,ELDK的开发环境便基本搭建完成。"

我的ARM学习计划

目前状态:
1)硬件utu2440-s v4.1 ARM9开发板
2)usb串口线一条,经测试可正常运行
3)文档教材若干

--------------
第一阶段:
用Jtag烧写bootload到开发板,已完成
用串口+网口重复load bootload 未开始
重复load bootload后,加载linux内核
并尝试加载不同内核,反复测试开发板,并记录各状态数据以便参考

第二阶段:
移植自己的bootload(采用最新版本的uboot),不用棒子的vivi
移植成功后,编译最新linux内核,并加载

第三阶段:
运行硬件例程,尝试编写硬件驱动,并开始后续学习

2009年5月6日星期三

utu2440-S-V4.1开发板

utu2440-S-V4.1开发板: "utu2440-S 三星2440开发板采用6层板单板设计形式
外引总线,地址线,GPIO,IIC,SPI等接口,方便用户使用。
400M主频,64M bytes Flash,64M bytes SDRAM,尺寸:长132mm,宽100mm

开发板资源:
(1)S3C2440A:32bit ARM920T内核,标称工作频率:400MHz
(2)系统时钟:内部PLL产生400MHz CPU内核工作频率,外部总线频率:100~133MHz
(3)LCD控制器:CPU内置STN/CSTN/TFT LCD控制器,支持1024*768分辨率以下的各种液晶
(4)触摸屏控制器:CPU内置4线制电阻式触摸屏控制器
(5)100MHz 以太网控制器
(6)1通道5线制串口,2通道3线制串口
(7)1通道USB1.1 主机接口,可接usb hub,扩充多个usb主口
(8)1通道USB1.1设备接口
(9)SD/MMC卡接口
(10)音频输入输出接口
(12)LCD接口,可接3.5寸/7寸/4.3寸/2.8寸/10寸等等尺寸TFT真彩液晶屏
(13)专用复位电路
(16)触摸屏控制器
(17)RTC实时时钟及大容量后备锂电池
(18)标准20pin JTAG调试接口
(20)4只自定义功能LED指示灯
(21)电源指示灯
(22)6只自定义按键,用户可以组合为“上”“下”“左”“右”“确认”“取消”6个常见功能键
(23)电源开关
(24)复位按键
(29)SPI接口
(31)标准配置64MBytes Nand-Flash
(32)标准配置64MBtyes SDRAM
(33)5V电源
(34)支持的操作系统:WINCE /Linux"

u-boot命令解释-转

u-boot命令解释: "U-Boot上电启动后,敲任意键能够退出自动启动状态,进入命令行。

U-Boot 1.1.2 (Apr 26 2005 - 12:27:13)
U-Boot code: 11080000 -> 1109614C BSS: -> 1109A91C
RAM Configuration:
Bank #0: 10000000 32 MB
Micron StrataFlash MT28F128J3 device initialized
Flash: 32 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
U-Boot>

在命令行提示符下,能够输入U-Boot的命令并执行。U-Boot能够支持几十个常用命令,通过这些命令,能够对研发板进行调试,能够引导Linux内核,还能够擦写Flash完成系统部署等功能。掌控这些命令的使用,才能够顺利地进行嵌入式系统的研发。
输入help命令,能够得到当前U-Boot的任何命令列表。每一条命令后面是简单的命令说明。

=> help
? - alias for 'help'
autoscr - run from memory
base - print or set address offset
bdinfo - print Board Info structure
boot - boot default, i.e., run 'bootcmd'
bootd - boot default, i.e., run 'bootcmd'
bootm - boot application image from memory
bootp - boot image via network using BootP/TFTP protocol
cmp - memory compare
coninfo - print console devices and information
cp - memory copy
crc32 - checksum calculation
dhcp - invoke DHCP client to obtain IP/boot params
echo - echo args to console
erase - erase FLASH memory
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print online help
iminfo - print header information for application image
imls - list all images found in flash
itest - return true/false on integer compare
loadb - load binary file over serial line (kermit mode)
loads - load S-Record file over serial line
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing)
mtest - simple RAM test
mw - memory write (fill)
nfs - boot image via network using NFS protocol
nm - memory modify (constant address)
printenv - print environment variables
protect - enable or disable FLASH write protection
rarpboot - boot image via network using RARP/TFTP protocol
reset - Perform RESET of the CPU
run - run commands in an environment variable
saveenv - save environment variables to persistent storage
setenv - set environment variables
sleep - delay execution for some time
tftpboot - boot image via network using TFTP protocol
version - print monitor version
=>

U-Boot还提供了更加周详的命令帮助,通过help命令还能够查看每个命令的参数说明。由于研发过程的需要,有必要先把U-Boot命令的用法弄清楚。接下来,根据每一条命令的帮助信息,解释一下这些命令的功能和参数。

=> help bootm
bootm [addr [arg ...]]
- boot application image stored in memory
passing arguments 'arg ...'; when booting a Linux kernel,
'arg' can be the address of an initrd image

bootm命令能够引导启动存储在内存中的程式映像。这些内存包括RAM和能够永久保存的Flash。
第1个参数addr是程式映像的地址,这个程式映像必须转换成U-Boot的格式。
第2个参数对于引导Linux内核有用,通常作为U-Boot格式的RAMDISK映像存储地址;也能够是传递给Linux内核的参数(缺省情况下传递bootargs环境变量给内核)。

=> help bootp
bootp [loadAddress] [bootfilename]
bootp命令通过bootp请求,需要DHCP服务器分配IP地址,然后通过TFTP协议下载指定的文档到内存。
第1个参数是下载文档存放的内存地址。
第2个参数是要下载的文档名称,这个文档应该在研发主机上准备好。

=> help cmp
cmp [.b, .w, .l] addr1 addr2 count
- compare memory

cmp命令能够比较2块内存中的内容。.b以字节为单位;.w以字为单位;.l以长字为单位。注意:cmp.b中间不能保留空格,需要连续敲入命令。
第1个参数addr1是第一块内存的起始地址。
第2个参数addr2是第二块内存的起始地址。
第3个参数count是要比较的数目,单位按照字节、字或长字。

=> help cp
cp [.b, .w, .l] source target count
- copy memory

cp命令能够在内存中复制数据块,包括对Flash的读写操作。
第1个参数source是要复制的数据块起始地址。
第2个参数target是数据块要复制到的地址。这个地址假如在Flash中,那么会直接调用写Flash的函数操作。所以U-Boot写Flash就使用这个命令,当然需要先把对应Flash区域擦干净。
第3个参数count是要复制的数目,根据cp.b cp.w cp.l分别以字节、字、长字为单位。

=> help crc32
crc32 address count [addr]
- compute CRC32 checksum [save at addr]

crc32命令能够计算存储数据的校验和。
第1个参数address是需要校验的数据起始地址。
第2个参数count是要校验的数据字节数。
第3个参数addr用来指定保存结果的地址。

=> help echo
echo [args..]
- echo args to console; \c suppresses newline

echo命令回显参数。

=> help erase
erase start end
- erase FLASH from addr 'start' to addr 'end'
erase N:SF[-SL]
- erase sectors SF-SL in FLASH bank # N
erase bank N
- erase FLASH bank # N
erase all
- erase all FLASH banks

erase命令能够擦Flash。
参数必须指定Flash擦除的范围。
按照起始地址和结束地址,start必须是擦除块的起始地址;end必须是擦除末尾块的结束地址。这种方式最常用。举例说明:擦除0x20000 – 0x3ffff区域命令为erase 20000 3ffff。
按照组和扇区,N表示Flash的组号,SF表示擦除起始扇区号,SL表示擦除结束扇区号。另外,还能够擦除整个组,擦除组号为N的整个Flash组。擦除全部Flash只要给出一个all的参数即可。

=> help flinfo
flinfo
- print information for all FLASH memory banks
flinfo N
- print information for FLASH memory bank # N

flinfo命令打印全部Flash组的信息,也能够只打印其中某个组。一般嵌入式系统的Flash只有一个组。

=> help go
go addr [arg ...]
- start application at address 'addr'
passing 'arg' as arguments

go命令能够执行应用程式。
第1个参数是要执行程式的入口地址。
第2个可选参数是传递给程式的参数,能够不用。

=> help iminfo
iminfo addr [addr ...]
- print header information for application image starting at
address 'addr' in memory; this includes verification of the
image contents (magic number, header and payload checksums)

iminfo能够打印程式映像的开头信息,包含了映像内容的校验(序列号、头和校验和)。
第1个参数指定映像的起始地址。
可选的参数是指定更多的映像地址。

=> help loadb
loadb [ off ] [ baud ]
- load binary file over serial line with offset 'off' and baudrate 'baud'

loadb命令能够通过串口线下载二进制格式文档。

=> help loads
loads [ off ]
- load S-Record file over serial line with offset 'off'

loads命令能够通过串口线下载S-Record格式文档。

=> help mw
mw [.b, .w, .l] address value [count]
- write memory

mw命令能够按照字节、字、长字写内存,.b .w .l的用法和cp命令相同。
第1个参数address是要写的内存地址。
第2个参数value是要写的值。
第3个可选参数count是要写单位值的数目。

=> help nfs
nfs [loadAddress] [host ip addr:bootfilename]

nfs命令能够使用NFS网络协议通过网络启动映像。

=> help nm
nm [.b, .w, .l] address
- memory modify, read and keep address

nm命令能够修改内存,能够按照字节、字、长字操作。
参数address是要读出并且修改的内存地址。

=> help printenv
printenv
- print values of all environment variables
printenv name ...
- print value of environment variable 'name'

printenv命令打印环境变量。
能够打印全部环境变量,也能够只打印参数中列出的环境变量。

=> help protect
protect on start end
- protect Flash from addr 'start' to addr 'end'
protect on N:SF[-SL]
- protect sectors SF-SL in Flash bank # N
protect on bank N
- protect Flash bank # N
protect on all
- protect all Flash banks
protect off start end
- make Flash from addr 'start' to addr 'end' writable
protect off N:SF[-SL]
- make sectors SF-SL writable in Flash bank # N
protect off bank N
- make Flash bank # N writable
protect off all
- make all Flash banks writable

protect命令是对Flash写保护的操作,能够使能和解除写保护。
第1个参数on代表使能写保护;off代表解除写保护。
第2、3参数是指定Flash写保护操作范围,跟擦除的方式相同。

=> help rarpboot
rarpboot [loadAddress] [bootfilename]

rarboot命令能够使用TFTP协议通过网络启动映像。也就是把指定的文档下载到指定地址,然后执行。
第1个参数是映像文档下载到的内存地址。
第2个参数是要下载执行的映像文档。

=> help run
run var [...]
- run the commands in the environment variable(s) 'var'

run命令能够执行环境变量中的命令,后面参数能够跟几个环境变量名。

=> help setenv
setenv name value ...
- set environment variable 'name' to 'value ...'
setenv name
- delete environment variable 'name'

setenv命令能够配置环境变量。
第1个参数是环境变量的名称。
第2个参数是要配置的值,假如没有第2个参数,表示删除这个环境变量。


=> help sleep
sleep N
- delay execution for N seconds (N is _decimal_ !!!)

sleep命令能够延迟N秒钟执行,N为十进制数。

=> help tftpboot
tftpboot [loadAddress] [bootfilename]

tftpboot命令能够使用TFTP协议通过网络下载文档。按照二进制文档格式下载。另外使用这个命令,必须配置好相关的环境变量。例如serverip和ipaddr。
第1个参数loadAddress是下载到的内存地址。
第2个参数是要下载的文档名称,必须放在TFTP服务器相应的目录下。
这些U-Boot命令为嵌入式系统提供了丰富的研发和调试功能。在Linux内核启动和调试过程中,都能够用到U-Boot的命令。但是一般情况下,无需使用全部命令。比如已支持以太网接口,能够通过tftpboot命令来下载文档,那么更有必要使用串口下载的loadb吗?反过来,假如研发板需要特别的调试功能,也能够添加新的命令。
在建立交叉研发环境和调试Linux内核等章节时,在ARM平台上移植了U-Boot,并且提供了具体U-Boot的操作步骤。"

2009年5月5日星期二

U-BOOT(bootloader)程序的特点功能

U-BOOT(bootloader)程序的特点功能: "1 U-BOOT简介
  U-BOOT是由德国的工程师Wolfgang Denk从8XXROM代码发展而来的,它支持很多处理器,比如PowerPC、ARM、MIPS和x86。目前,U-BOOT源代码在 sourceforge网站的社区服务器中,Internet上有一群自由开发人员对其进行维护和开发,它的项目主页是http: //sourceforge.net/projects/U-BOOT。U-BOOT的最新版本源代码可以在Sourceforge的CVS服务器中匿名获得。
#cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/U-BOOT login
#cvs -z6 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/U-BOOT \ co -P modulename

1.1 U-BOOT源代码目录结构

◆ board:和一些已有开发板有关的文件,比如Makefile和u-boot.lds等都和具体开发板的硬件和地址分配有关。
◆ common:与体系结构无关的文件,实现各种命令的C文件。
◆ cpu:CPU相关文件,其中的子目录都是以U-BOOT所支持的CPU为名,比如有子目录arm926ejs、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c,start.S。其中cpu.c初始化CPU、设置指令Cache和数据Cache等; interrupt.c设置系统的各种中断和异常,比如快速中断、开关中断、时钟中断、软件中断、预取中止和未定义指令等;start.S是U-BOOT 启动时执行的第一个文件,它主要是设置系统堆栈和工作方式,为进入C程序奠定基础。
◆ disk:disk驱动的分区处理代码。
◆ doc:文档。
◆ drivers:通用设备驱动程序,比如各种网卡、支持CFI的Flash、串口和USB总线等。
◆ fs:支持文件系统的文件,U-BOOT现在支持cramfs、fat、fdos、jffs2和registerfs。
◆ include:头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。
◆ net:与网络有关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。
◆ lib_arm:与ARM体系结构相关的代码。
◆ tools:创建S-Record格式文件 和U-BOOT images的工具。

1.2 U-BOOT的特点

  U-BOOT支持SCC/FEC以太网、OOTP/TFTP引导、IP和MAC的预置功能,这一点和其它BootLoader(如BLOB和RedBoot等)类似。但U-BOOT还具有一些特有的功能。

◆ 在线读写Flash、DOC、IDE、IIC、EEROM、RTC,其它的BootLoader根本不支持IDE和DOC的在线读写。
◆ 支持串行口kermit和S-record下载代码,U-BOOT本身的工具可以把ELF32格式的可执行文件转换成为 S-record格式,直接从串口下载并执行。
◆ 识别二进制、ELF32、uImage格式的Image,对Linux引导有特别的支持。U-BOOT对Linux 内核进一步封装为uImage。封装如下:
#{CROSS_COMPILE}-objcopy -O binary -R.note -R.comment -S vmlinux \ linux.bin
#gzip -9 linux.bin
#tools/mkimage -A arm -O linux -T kernel -C gzip -a 0xc0008000 -e\
0xc0008000 -n “Linux-2.4.20” -d linux.bin.gz /tftpboot/uImage
即在Linux内核镜像vmLinux前添加了一个特殊的头,这个头在include/image.h中定义,包括目标操作系统的种类(比如Linux, VxWorks等)、目标CPU的体系机构(比如ARM、PowerPC等)、映像文件压缩类型(比如gzip、bzip2等)、加载地址、入口地址、映像名称和映像的生成时间。当系统引导时,U-BOOT会对这个文件头进行CRC校验,如果正确,才会跳到内核执行。如下所示:
WT-ARM9# bootm 0xc1000000
## Checking Image at 0xc100000 ...
Image Name: Linux-2.4.20
Created: 2004-07-02 22:10:11 UTC
Image Type: ARM Linux Kernel Image (gzip compressed)
Data Size: 550196 Bytes = 537 kB = 0 MB
Load Address: 0xc0008000
Entry Point: 0xc0008000
Verifying Checksum ... OK
Uncompressing Kernel Image ……… OK
◆ 单任务软件运行环境。U-BOOT可以动态加载和运行独立的应用程序,这些独立的应用程序可以利用U-BOOT控制台的I/O函数、内存申请和中断服务等。这些应用程序还可以在没有操作系统的情况下运行,是测试硬件系统很好的工具。
◆ 监控(minitor)命令集:读写I/O,内存,寄存器、内存、外设测试功能等
◆ 脚本语言支持(类似BASH脚本)。利用U-BOOT中的autoscr命令,可以在U-BOOT中运行“脚本”。首先在文本文件中输入需要执行的命令,然后用tools/mkimage封装,然后下载到开发板上,用autoscr执行就可以了。
① 编辑如下的脚本example.script。
echo
echo Network Configuration:
echo ----------------------
echo Target:
printenv ipaddr hostname
echo
echo Server:
printenv serverip rootpath
echo
② 用tools/mkimage对脚本进行封装。
# mkimage -A ARM -O linux -T script -C none -a 0 -e 0 -n 'autoscr example script' -d example.script /tftpboot/example.img
Image Name: autoscr example script
Created: Wes Sep 8 01:15:02 2004
Image Type: ARM Linux Script (uncompressed)
Data Size: 157 Bytes = 0.15 kB = 0.00 MB
Load Address: 0x00000000
Entry Point: 0x00000000
Contents:
Image 0: 149 Bytes = 0 kB = 0 MB
③ 在U-BOOT中加载并执行这个脚本。
WT-ARM9# tftp 100000 /tftpboot/example.img
ARP broadcast 1
TFTP from server 10.0.0.2; our IP address is 10.0.0.99
Filename '/tftpboot/TQM860L/example.img'.
Load address: 0x100000
Loading: #
done
Bytes transferred = 221 (dd hex)
WT-ARM9# autoscr 100000
## Executing script at 00100000
Network Configuration:
----------------------
Target:
ipaddr=10.0.0.99
hostname=arm
Server:
serverip=10.0.0.2
rootpath=/nfsroot
WT-ARM9#
◆ 支持WatchDog、LCD logo和状态指示功能等。如果系统支持splash screen,U-BOOT启动时,会把这个图像显示到LCD上,给用户更友好的感觉。
◆ 支持MTD和文件系统。U-BOOT作为一种强大的BootLoader,它不仅支持MTD,而且可以在MTD基础上实现多种文件系统,比如cramfs、fat和jffs2等。
◆ 支持中断。由于传统的BootLoader都分为stage1和stage2,所以在stage2中添加中断处理服务十分困难,比如BLOB;而U-BOOT是把两个部分放到了一起,所以添加中断服务程序就很方便。
◆ 详细的开发文档。由于大多数BootLoader都是开源项目,所以文档都不是很充分。U-BOOT的维护人员意识到了这个问题,充分记录了开发文档,所以它的移植要比BLOB等缺少文档的BootLoader方便。"

2009年5月4日星期一

郭光景: arm-linux内核编译错误集

郭光景:arm-linux内核编译错误集: "arm-linux内核编译错误集

1,编译linux-2.6.22内核时出现如下错误:

arm-linux-ld:arch/arm/kernel/vmlinux.lds:541: parse error
make: *** [.tmp_vmlinux1] 错误 1
根据提示,找到编译内核文件夹下的arch/arm/kernel/vmlinux.lds文件中第541行,看到

/*
* These must never be empty
* If you have to comment these two assert statements out, your
* binutils is too old (for other reasons as well)
*/
ASSERT((__proc_info_end - __proc_info_begin), “missing CPU support”)
ASSERT((__arch_info_end - __arch_info_begin), “no machine record defined”)

没错,就是这里显示出错了,注解上写着if you have to comment these two assert statements out, your binutils is too old (for other reasons as well),我用arm-linux交叉编译工具的3.4.3版本,看来已经很旧了。

只要把这两句comment out就可以了,注意要使用/**/这种注释。"

郭光景:在linux下使用gtkterm

郭光景:在linux下使用gtkterm: "linux下有个工具,叫gtkterm。是管理串口的,比minicom还好配置和使用,个人觉得。

在ubuntu里,用HL-340 USB转SERIAL线的时候,一时忘记设备名是什么(是ttyUSB0),那里会直接显示,而用MINICOM就麻烦咯。如果不知道还真的有点难搞。我还被人误导是USBtty0呢 !

不过,gtkterm找不到选项保存自己的配置。"

mincom 的使用

前几日一直在折腾utu2440-S-V4.1

在minicom下总是显示乱码,各种波特率都用了,还是不行
不知道是不是Uboot版本的问题
今天又翻了些资料,回去后测试一下

Minicom的使用
1.minicom的执行用指令'rpm -qa | grep minicom'来确认是否安装了minicom,回车后会显示minicom 的版本信息.第一次 启动时:即输入 minicom提示 错误。则 需: minicom -s启动出现配置菜单:选serial port setup进入串口配置输入A配置串口驱动为/dev/ttyS0输入E配置速率为115200 8N1输入F将 Hardware Flow Control 设 为 NO回车 退出
由于我们使用minicom作为超级终端控制路由器等设备, 而不是控制modem, 所以需要修改Modem and
dialing, 将Init string, Reset string, Hang-up string设置为空. 设置完成后选择Save setup as
dfl将当前设置保存为默认设置.在配置菜单 选Save setup as df1保存(一定要记得这一步)选Exit退出
下次在输入minicon 即可直接进入。命令minicom是进入串口超级终端画面,而minicom -s为配置minicom。说明/dev/ttyS0 对应为串口0 为你连接开发板的端口。注意:非正常关闭minicom,会在/var/lock下创建几个文件LCK*,这几个文件阻止了minicom的运行,将
它们删除后即可恢复使用"

2009年5月1日星期五

上拉电阻下拉电阻的总结[综合电子]_老古开发网文章

上拉电阻下拉电阻的总结[综合电子]_老古开发网文章: "上拉电阻:
1、当TTL电路驱动COMS电路时,如果TTL电路输出的高电平低于COMS电路的最低高电平(一般为3.5V),这时就需要在TTL的输出端接上拉电阻,以提高输出高电平的值。
2、OC门电路必须加上拉电阻,才能使用。
3、为加大输出引脚的驱动能力,有的单片机管脚上也常使用上拉电阻。
4、在COMS芯片上,为了防止静电造成损坏,不用的管脚不能悬空,一般接上拉电阻产生降低输入阻抗,提供泄荷通路。
5、芯片的管脚加上拉电阻来提高输出电平,从而提高芯片输入信号的噪声容限增强抗干扰能力。
6、提高总线的抗电磁干扰能力。管脚悬空就比较容易接受外界的电磁干扰。
7、长线传输中电阻不匹配容易引起反射波干扰,加上下拉电阻是电阻匹配,有效的抑制反射波干扰。
上拉电阻阻值的选择原则包括:
1、从节约功耗及芯片的灌电流能力考虑应当足够大;电阻大,电流小。
2、从确保足够的驱动电流考虑应当足够小;电阻小,电流大。
3、对于高速电路,过大的上拉电阻可能边沿变平缓。综合考虑
以上三点,通常在1k到10k之间选取。对下拉电阻也有类似道理
对上拉电阻和下拉电阻的选择应结合开关管特性和下级电路的输入特性进行设定,主要需要考虑以下几个因素:
1. 驱动能力与功耗的平衡。以上拉电阻为例,一般地说,上拉电阻越小,驱动能力越强,但功耗越大,设计是应注意两者之间的均衡。
2. 下级电路的驱动需求。同样以上拉电阻为例,当输出高电平时,开关管断开,上拉电阻应适当选择以能够向下级电路提供足够的电流。
3. 高低电平的设定。不同电路的高低电平的门槛电平会有不同,电阻应适当设定以确保能输出正确的电平。以上拉电阻为例,当输出低电平时,开关管导通,上拉电阻和开关管导通电阻分压值应确保在零电平门槛之下。
4. 频率特性。以上拉电阻为例,上拉电阻和开关管漏源级之间的电容和下级电路之间的输入电容会形成RC延迟,电阻越大,延迟越大。上拉电阻的设定应考虑电路在这方面的需求。
下拉电阻的设定的原则和上拉电阻是一样的。
OC门输出高电平时是一个高阻态,其上拉电流要由上拉电阻来提供,设输入端每端口不大于100uA,设输出口驱动电流约500uA,标准工作电压是5V,输入口的高低电平门限为0.8V(低于此值为低电平);2V(高电平门限值)。
选上拉电阻时:
500uA x 8.4K= 4.2即选大于8.4K时输出端能下拉至0.8V以下,此为最小阻值,再小就拉不下来了。如果输出口驱动电流较大,则阻值可减小,保证下拉时能低于0.8V即可。
当输出高电平时,忽略管子的漏电流,两输入口需200uA
200uA x15K=3V即上拉电阻压降为3V,输出口可达到2V,此阻值为最大阻值,再大就拉不到2V了。选10K可用。COMS门的可参考74HC系列
设计时管子的漏电流不可忽略,IO口实际电流在不同电平下也是不同的,上述仅仅是原理,一句话概括为:输出高电平时要喂饱后面的输入口,输出低电平不要把输出口喂撑了(否则多余的电流喂给了级联的输入口,高于低电平门限值就不可靠了)

在数字电路中不用的输入脚都要接固定电平,通过1k电阻接高电平或接地。
1. 电阻作用:
l 接电组就是为了防止输入端悬空
l 减弱外部电流对芯片产生的干扰
l 保护cmos内的保护二极管,一般电流不大于10mA
l 上拉和下拉、限流
l 1. 改变电平的电位,常用在TTL-CMOS匹配
2. 在引脚悬空时有确定的状态
3.增加高电平输出时的驱动能力。
4、为OC门提供电流
l 那要看输出口驱动的是什么器件,如果该器件需要高电压的话,而输出口的输出电压又不够,就需要加上拉电阻。
l 如果有上拉电阻那它的端口在默认值为高电平你要控制它必须用低电平才能控制如三态门电路三极管的集电极,或二极管正极去控制把上拉电阻的电流拉下来成为低电平。反之,
l 尤其用在接口电路中,为了得到确定的电平,一般采用这种方法,以保证正确的电路状态,以免发生意外,比如,在电机控制中,逆变桥上下桥臂不能直通,如果它们都用同一个单片机来驱动,必须设置初始状态.防止直通!

2、定义:
l 上拉就是将不确定的信号通过一个电阻嵌位在高电平!电阻同时起限流作用!下拉同理!
l 上拉是对器件注入电流,下拉是输出电流
l 弱强只是上拉电阻的阻值不同,没有什么严格区分
l 对于非集电极(或漏极)开路输出型电路(如普通门电路)提升电流和电压的能力是有限的,上拉电阻的功能主要是为集电极开路输出型电路输出电流通道。

3、为什么要使用拉电阻:
l 一般作单键触发使用时,如果IC本身没有内接电阻,为了使单键维持在不被触发的状态或是触发后回到原状态,必须在IC外部另接一电阻。
l 数字电路有三种状态:高电平、低电平、和高阻状态,有些应用场合不希望出现高阻状态,可以通过上拉电阻或下拉电阻的方式使处于稳定状态,具体视设计要求而定!
l 一般说的是I/O端口,有的可以设置,有的不可以设置,有的是内置,有的是需要外接,I/O端口的输出类似与一个三极管的C,当C接通过一个电阻和电源连接在一起的时候,该电阻成为上C拉电阻,也就是说,如果该端口正常时为高电平,C通过一个电阻和地连接在一起的时候,该电阻称为下拉电阻,使该端口平时为低电平,作用吗:
比如:当一个接有上拉电阻的端口设为输如状态时,他的常态就为高电平,用于检测低电平的输入。
l 上拉电阻是用来解决总线驱动能力不足时提供电流的。一般说法是拉电流,下拉电阻是用来吸收电流"

寄存器

寄存器定义

  寄存器是中央处理器内的组成部份。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器(PC)。在中央处理器的算术及逻辑部件中,包含的寄存器有累加器(ACC)。
  寄存器是内存阶层中的最顶端,也是系统获得操作资料的最快速途径。寄存器通常都是以他们可以保 存的位元数量来估量,举例来说,一个 "8 位元寄存器"或 "32 位元寄存器"。寄存器现在都以寄存器档案的方式来实作,但是他们也可能使用单独的正反器、高速的核心内存、薄膜内存以及在数种机器上的其他方式来实作出 来。
  寄存器通常都用来意指由一个指令之输出或输入可以直接索引到的暂存器群组。更适当的是称他们为 "架构寄存器"。
  例如,x86 指令及定义八个 32 位元寄存器的集合,但一个实作 x86 指令集的 CPU 可以包含比八个更多的寄存器。
  寄存器是CPU内部的元件,寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快。

寄存器用途

  1.可将寄存器内的数据执行算术及逻辑运算;
  2.存于寄存器内的地址可用来指向内存的某个位置,即寻址;
  3.可以用来读写数据到电脑的周边设备。

数据寄存器

  8086 有14个16位寄存器,这14个寄存器按其用途可分为(1)通用寄存器、(2)指令指针、(3)标志寄存器和(4)段寄存器等4类。
  (1)通用寄存器有8个, 又可以分成2组,一组是数据寄存器(4个),另一组是指针寄存器及变址寄存器(4个).
  数据寄存器分为:
  AH&AL=AX(accumulator):累加寄存器,常用于运算;在乘除等指令中指定用来存放操作数,另外,所有的I/O指令都使用这一寄存器与外界设备传送数据.
  BH&BL=BX(base):基址寄存器,常用于地址索引;
  CH&CL=CX(count):计数寄存器,常用于计数;常用于保存计算值,如在移位指令,循环(loop)和串处理指令中用作隐含的计数器.
  DH&DL=DX(data):数据寄存器,常用于数据传递。
  他们的特点是,这4个16位的寄存器可以分为高8位: AH, BH, CH, DH.以及低八位:AL,BL,CL,DL。这2组8位寄存器可以分别寻址,并单独使用。
  另一组是指针寄存器和变址寄存器,包括:
  SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置;
  BP(Base Pointer):基址指针寄存器,可用作SS的一个相对基址位置;
  SI(Source Index):源变址寄存器可用来存放相对于DS段之源变址指针;
  DI(Destination Index):目的变址寄存器,可用来存放相对于 ES 段之目的变址指针。
  这4个16位寄存器只能按16位进行存取操作,主要用来形成操作数的地址,用于堆栈操作和变址运算中计算操作数的有效地址。
  (2) 指令指针IP(Instruction Pointer)
  指令指针IP是一个16位专用寄存器,它指向当前需要取出的指令字节,当BIU从内存中取出一 个指令字节后,IP就自动加1,指向下一个指令字节。注意,IP指向的是指令地址的段内地址偏移量,又称偏移地址(Offset Address)或有效地址(EA,Effective Address)。
  (3)标志寄存器FR(Flag Register)
  
8086有一个18位的标志寄存器FR,在FR中有意义的有9位,其中6位是状态位,3位是控制位。
  OF: 溢出标志位OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。
  DF:方向标志DF位用来决定在串操作指令执行时有关指针寄存器发生调整的方向。
  IF:中断允许标志IF位用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志为何值,CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。具体规定如下:
  (1)、当IF=1时,CPU可以响应CPU外部的可屏蔽中断发出的中断请求;
  (2)、当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求。
  TF:跟踪标志TF。该标志可用于程序调试。TF标志没有专门的指令来设置或清楚。
  (1)如果TF=1,则CPU处于单步执行指令的工作方式,此时每执行完一条指令,就显示CPU内各个寄存器的当前值及CPU将要执行的下一条指令。
  (2)如果TF=0,则处于连续工作模式。
  SF:符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。
  ZF: 零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。
  AF:下列情况下,辅助进位标志AF的值被置为1,否则其值为0:
  (1)、在字操作时,发生低字节向高字节进位或借位时;
  (2)、在字节操作时,发生低4位向高4位进位或借位时。
  PF:奇偶标志PF用于反映运算结果中"1"的个数的奇偶性。如果"1"的个数为偶数,则PF的值为1,否则其值为0。
  CF:进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。)
  4)段寄存器(Segment Register)
  为了运用所有的内存空间,8086设定了四个段寄存器,专门用来保存段地址:
  CS(Code Segment):代码段寄存器;
  DS(Data Segment):数据段寄存器;
  SS(Stack Segment):堆栈段寄存器;
  ES(Extra Segment):附加段寄存器。
  当一个程序要执行时,就要决定程序代码、数据和堆栈各要用到内存的哪些位置,通过设定段寄存器 CS,DS,SS 来指向这些起始位置。通常是将DS固定,而根据需要修改CS。所以,程序可以在可寻址空间小于64K的情况下被写成任意大小。 所以,程序和其数据组合起来的大小,限制在DS 所指的64K内,这就是COM文件不得大于64K的原因。8086以内存做为战场,用寄存器做为军事基地,以加速工作。
  以上是8086寄存器的整体概况, 自80386开始,PC进入32bit时代,其寻址方式,寄存器大小,功能等都发生了变化。
  =============================以下是80386的寄存器的一些资料======================================
  寄存器都是32-bits宽。
  A、通用寄存器
  下面介绍通用寄存器及其习惯用法。顾名思义,通用寄存器是那些你可以根据自己的意愿使用的寄存器,修改他们的值通常不会对计算机的运行造成很大的影响。通用寄存器最多的用途是计算。
  EAX:通用寄存器。相对其他寄存器,在进行运算方面比较常用。在保护模式中,也可以作为内存偏移指针(此时,DS作为段 寄存器或选择器)
  EBX:通用寄存器。通常作为内存偏移指针使用(相对于EAX、ECX、EDX),DS是默认的段寄存器或选择器。在保护模式中,同样可以起这个作用。
  ECX:通用寄存器。通常用于特定指令的计数。在保护模式中,也可以作为内存偏移指针(此时,DS作为 寄存器或段选择器)。
  EDX:通用寄存器。在某些运算中作为EAX的溢出寄存器(例如乘、除)。在保护模式中,也可以作为内存偏移指针(此时,DS作为段 寄存器或选择器)。
  同AX分为AH&AL一样,上述寄存器包括对应的16-bit分组和8-bit分组。
  B、用作内存指针的特殊寄存器
  ESI:通常在内存操作指令中作为"源地址指针"使用。当然,ESI可以被装入任意的数值,但通常没有人把它当作通用寄存器来用。DS是默认段寄存器或选择器。
  EDI:通常在内存操作指令中作为"目的地址指针"使用。当然,EDI也可以被装入任意的数值,但通常没有人把它当作通用寄存器来用。DS是默认段寄存器或选择器。
  EBP:这也是一个作为指针的寄存器。通常,它被高级语言编译器用以建造'堆栈帧'来保存函数或过程的局部变量,不过,还是那句话,你可以在其中保存你希望的任何数据。SS是它的默认段寄存器或选择器。
  注意,这三个寄存器没有对应的8-bit分组。换言之,你可以通过SI、DI、BP作为别名访问他们的低16位,却没有办法直接访问他们的低8位。
  C、段选择器:
  实模式下的段寄存器到保护模式下摇身一变就成了选择器。不同的是,实模式下的"段寄存器"是16-bit的,而保护模式下的选择器是32-bit的。
  CS 代码段,或代码选择器。同IP寄存器(稍后介绍)一同指向当前正在执行的那个地址。处理器执行时从这个寄存器指向的段(实模式)或内存(保护模式)中获取指令。除了跳转或其他分支指令之外,你无法修改这个寄存器的内容。
  DS 数据段,或数据选择器。这个寄存器的低16 bit连同ESI一同指向的指令将要处理的内存。同时,所有的内存操作指令 默认情况下都用它指定操作段(实模式)或内存(作为选择器,在保护模式。这个寄存器可以被装入任意数值,然而在这么做的时候需要小心一些。方法是,首先把 数据送给AX,然后再把它从AX传送给DS(当然,也可以通过堆栈来做).
  ES 附加段,或附加选择器。这个寄存器的低16 bit连同EDI一同指向的指令将要处理的内存。同样的,这个寄存器可以被装入任意数值,方法和DS类似。
  FS F段或F选择器(推测F可能是Free?)。可以用这个寄存器作为默认段寄存器或选择器的一个替代品。它可以被装入任何数值,方法和DS类似。
  GS G段或G选择器(G的意义和F一样,没有在Intel的文档中解释)。它和FS几乎完全一样。
  SS 堆栈段或堆栈选择器。这个寄存器的低16 bit连同ESP一同指向下一次堆栈操作(push和pop)所要使用的堆栈地址。这个寄存器也可以被装入任意数值,你可以通过入栈和出栈操作来给他赋 值,不过由于堆栈对于很多操作有很重要的意义,因此,不正确的修改有可能造成对堆栈的破坏。
  * 注意 一定不要在初学汇编的阶段把这些寄存器弄混。他们非常重要,而一旦你掌握了他们,你就可以对他们做任意的操作了。段寄存器,或选择器,在没有指定的情况下都是使用默认的那个。这句话在现在看来可能有点稀里糊涂,不过你很快就会在后面知道如何去做。
  指令指针寄存器:
  EIP 这个寄存器非常的重要。这是一个32位宽的寄存器 ,同CS一同指向即将执行的那条指令的地址。不能够直接修改这个寄存器的值,修改它的唯一方法是跳转或分支指令。(CS是默认的段或选择器)
  上面是最基本的寄存器。下面是一些其他的寄存器,你甚至可能没有听说过它们。(都是32位宽):
  CR0, CR2, CR3(控制寄存器)。举一个例子,CR0的作用是切换实模式和保护模式。
  还有其他一些寄存器,D0, D1, D2, D3, D6和D7(调试寄存器)。他们可以作为调试器的硬件支持来设置条件断点。
  TR3, TR4, TR5, TR6 和 TR? 寄存器(测试寄存器)用于某些条件测试。

---------------------------------------------------------------------------------------------

储单元就被CPU"选中",那么CPU就可以把这个存储单元所存的数据通过另一组线路(数据总线)取出,或向这个存储单元存入新的数据。  不同的CPU 所具有的地址线数量是不一样的,像8086/88只有20根地址线,所能给出的地址范围是0-220-1(1048575),所以8086/88只能配备 1MB存储器。而286有24根地址线,当然可配备224个字节的存储器。386/486有32根地址线,所以最多可配备4GB存储器。
  前面所说的存储器都是直接和CPU相联接的,这些存储器和CPU往往安装在同一块电路板上,因此通常把这类存储器称为"内存储器"(内存)。在机器中还有另一类存储器-"外存储器",这类存储器一般指得是软盘、硬盘、磁带和光盘等容量较大的存储设备。
  外存储器和内存相联接而不和CPU直接联接,即CPU无法直接将外存中的数据取到自己内部进行处理,而只能先通过另一部分控制电路将外存中的数据取到内存中,再进行进一步的处理。处理后的数据也是先放在内存中,再传至外存。
  正是由于这个原因,外存的容量并不受CPU地址线数量的限制。其容量可从几百KB直至几个GB不等。而且外存往往是机械--电子结合的设备,其数据存取速度远低于内存。

1.6 寄存器

  寄存器又分为内部寄存器与外部寄存器,所谓内部寄存器,其实也是一些小的存储单元,也能存储数据。但同存储器相比,寄存器又有自己独有的特点:
  ① 寄存器位于CPU内部,数量很少,仅十四个;
  ② 寄存器所能存储的数据不一定是8bit,有一些寄存器可以存储16bit数据,对于386/486处理器中的一些寄存器则能存储32bit数据;
  ③ 每个内部寄存器都有一个名字,而没有类似存储器的地址编号。
  寄存器的功能十分重要,CPU对存储器中的数据进行处理时,往往先把数据取到内部寄存器中,而后再作处理。关于各个寄存器的具体问题后面会深入讨论。
  外部寄存器是计算机中其它一些部件上用于暂存数据的寄存器,它与CPU之间通过"端口"交换数据,所以外部寄存器具有寄存器和内存储器双重特点。有些时候我们常把外部寄存器就称为"端口",这种说法不太严格,但经常这样说。
   外部寄存器虽然也用于存放数据,但是它保存的数据具有特殊的用途。某些寄存器中各个位的0、1状态反映了外部设备的工作状态或方式;还有一些寄存器中的 各个位可对外部设备进行控制;也有一些端口作为CPU同外部设备交换数据的通路。所以说,端口是CPU和外设间的联系桥梁。
  CPU对端口的访问也是依据端口的"编号"(地址),这一点又和访问存储器一样。不过考虑到机器所联接的外设数量并不多,所以在设计机器的时候仅安排了1024个端口地址,端口地址范围为0--3FFH。图1-5反映了CPU、内存、端口和外设间的联系关系。

-------------------------------------------------------------------------------

寄存器(register,台湾译作暂存器),是中央处理器内的其中组成部份。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器(PC)。在中央处理器的算术及逻辑部件中,包含的寄存器有累加器(ACC)。

在计算机架构里,处理器中的寄存器是少量且速度快的计算机存储器,借由提供快速共同地访问数值来加速计算机程序的运行——典型地说就是在已知时间点所作的之计算中间的数值。

寄存器是存储器层次结构 中的最顶端,也是系统操作数据的最快速途径。寄存器通常都是以他们可以保存的位数量来估量,举例来说,一个8位寄存器或 32位寄存器。寄存器现在都以寄存器文件的方式来实现,但是他们也可能使用单独的正反器、高速的内核存储器、薄膜存储器以及在数种机器上的其他方式来实现出来。

这个名词通常都用来意指由一个指令之输出或输入可以直接索引到的寄存器组群。更适当的是称他们为 "架构寄存器"。例如,x86 指令及定义八个 32 位寄存器的集合,但一个实现x86指令集的CPU可以包含比八个更多的寄存器。

共有以下几类的寄存器: