重读 《节妇吟》
节妇吟
【唐】张籍
君知妾有夫,赠妾双明珠;
感君缠绵意,系在红罗襦。
妾家高楼连苑起,良人执戟明光里。
知君用心如日月,事夫誓拟同生死。
还君明珠双泪垂,恨不相逢未嫁时!
今天重读这首诗,心里又有别样的感觉,最近发生了很多事,自己也需要静下来
淡泊以明志,宁静而致远。
路漫漫其修远兮,吾将上下而求索。
节妇吟
【唐】张籍
君知妾有夫,赠妾双明珠;
感君缠绵意,系在红罗襦。
妾家高楼连苑起,良人执戟明光里。
知君用心如日月,事夫誓拟同生死。
还君明珠双泪垂,恨不相逢未嫁时!
今天重读这首诗,心里又有别样的感觉,最近发生了很多事,自己也需要静下来
淡泊以明志,宁静而致远。
摘 要:U-BOOT是一种开放源码的、用于多种嵌入式微处理器的引导加载程序,目前U-BOOT仅支持10M/100M网络功能。本文介绍了一种让U- BOOT支持千兆网络功能的方法及所需的硬件平台结构,重点介绍了此千兆网络驱动程序的结构及设计方法,并给出了驱动程序在U-BOOT中的移植过程。该 设计可以使U-BOOT功能更加强大,使用更加方便,同时也能使嵌入式系统网络接口设计更加灵活。
关键词: U-BOOT;千兆网;AX88180;驱动
引言
U-BOOT是德国DENX小组开发的用于多种嵌入式微处理器的引导加载程序,它是系统上电后运行的第一段程序代码,用于初始化目标板 硬件,为嵌入式操作系统提供目标板硬件配置信息,并装载、引导和运行嵌入式操作系统等。U-BOOT支持网络功能,在下载操作系统内核和大的文件系统时, 比其它不支持网络的引导加载程序速度更快、更方便。目前U-BOOT仅支持10M/100M的网络功能,随着科学技术发展,千兆网络功能必将大量应用在嵌 入式系统中。本文介绍了一种让U-BOOT支持千兆网络功能的方法,可以使U-BOOT功能更加强大,使用更加方便。
U-BOOT简介
U-Boot的全称是Universal Boot Loader,它遵循GPL条款的开放源码项目,支持多种处理器,如ARM、PowerPC、MIPS等,也支持Linux、VxWorks、QNX、RTEMS、ARTOS、LynxOS等嵌入式操作系统。
U- BOOT包含两种不同的工作模式:启动加载模式和下载模式。启动加载模式也称为自主模式,即U-BOOT从目标机上的某个固态存储设备上将操作系统加载到 RAM 中运行,这种模式是U-BOOT的正常工作模式。下载模式就是在开发或生产过程中,U-BOOT通过网络连接等通信手段从主机下载操作系统内核和文件系统 等到目标机的 RAM 中,然后再写到目标机上的FLASH 类固态存储设备中。U-BOOT允许用户在这两种工作模式间进行切换,系统启动时会延时等待一段时间,如果这时用户没有按键,U-Boot就默认进入启动 加载模式。
U-BOOT代码采用一种高度模块化的编程方式,可以很方便地在不同的硬件平台上进行移植。U-BOOT下包含多个目录,如图1所示。 其中BOARD目录下存放了所有其支持的目标板子目录,比如BOARD/SMDK2440/就是本文将要用到的目标板;COMMON目录是与体系结构无关 的文件,实现各种命令的C文件;CPU目录存放了其支持的CPU类型, 比如arm920t、mips、mpc8260和nios等,每个特定的子目录中都包括cpu.c和interrupt.c、start.S; DRIVERS目录存放了各种外设接口的驱动程序,其中就包含本文用到的千兆网络的驱动程序;FS目录存放了一些文件系统,U-BOOT现在支持 cramfs、fat、fdos、jffs2和registerfs;net目录存放的是与网络有关的代码,BOOTP协议、TFTP协议、RARP协议 和NFS文件系统的实现;INCLUDE目录存放了一些相关头文件,还有对各种硬件平台支持的汇编文件、系统的配置文件和对文件系统支持的文件。
图1? U-BOOT目录
硬件平台
本文使用的硬件平台是基于S3C2440A的开发板和基于非PCI千兆以太网控制芯片AX88180的嵌入式网卡,如图2所示。 S3C2440A是ARM920T 核的16/32 位RISC嵌入式微处理器,运行频率高达500MHz,开发板上有64M NAND闪存、64M SDRAM;网卡由MAC芯片AX88180、PHY芯片88E1111、RJ45等电路组成;S3C2440A目标板与网卡之间采用目标板32位扩展总 线相连接,在产品设计时也可以将这两部分设计在同一块板上。
驱动程序
在U-BOOT中嵌入千兆网络功能需要设计千兆网卡驱动程序,并在U-BOOT中进行移植,在相应的硬件平台上实现通过千兆网口下 载等功能。网卡驱动程序主要由初始化程序eth_init(bd_t*bd)、关闭网络设备程序eth_halt(void)、发送数据包程序 eth_send(volatilevoid* packet,intlength)、接收数据包程序inteth_rx(void)等组成。初始化程序的工作主要是配置和初始化硬件,在初始化程序里可 以完成对网络控制芯片AX88180和PHY芯片的配置,比如将接口设置为1000Mbps、全双工模式等。数据发送就是将上层协议打包好的数据放在发送 数据缓冲区,然后由网卡发送到网络上;数据接收就是在网卡接收到网络传来的数据包产生中断后,从缓冲区将数据取出交给上层协议程序进行解包处理。中断服务 程序处理网卡发送数据包后、接收到数据包后产生的中断以及PHY产生的中断等。
图2 硬件平台结构框图
网卡初始化程序如下:
int eth_init (bd_t * bd)
{
...
memset (&axlocal, 0, sizeof(AX88180_PRIVATE));
RESET_MAC;
DISABLE_INTERRUPT;
WRITE_MACREG(CMD, WAKEMOD);
tmp16 = bd->bi_enetaddr[1];
macid0_val = (tmp16 << 8) | bd->bi_enetaddr[0];
tmp16 = bd->bi_enetaddr[3];
macid1_val = (tmp16 << 8) | bd->bi_enetaddr[2];
tmp16 = bd->bi_enetaddr[5];
macid2_val = (tmp16 << 8) | bd->bi_enetaddr[4];
WRITE_MACREG(MACID0, macid0_val);
WRITE_MACREG(MACID1, macid1_val);
WRITE_MACREG(MACID2, macid2_val);
ax88180_PHY_initial();
ax88180_meida_config();
WRITE_MACREG(RXFILTER, DEFAULT_RXFILTER);
INIT_TXRX_VARIABLES;
READ_MACREG(ISR, tmp_regval);
PRINTK(INIT_MSG, "ax88180: The interrupt status = 0x%08lx\n", tmp_regval);
if (tmp_regval)?WRITE_MACREG(ISR, tmp_regval);
WRITE_MACREG(CMD, RXEN | TXEN | WAKEMOD);
return 0;}
驱动移植
驱动移植是在基于S3C2440A硬件平台的U-BOOT中添加驱动程序代码和相关配置,具体如下:
1. 在drivers/目录中添加网口设备驱动程序ax88180.c和ax88180.h。
2. 在lib_arm/board.c中相应位置(参考CS8900)添加如下代码:
#ifdef CONFIG_DRIVER_AX88180
extern void ax88180_get_ enetaddr (uchar * addr);
#endif
#ifdef CONFIG_DRIVER_AX88180
ax88180_get_enetaddr (gd->bd->bi_enetaddr);
#endif
3. 在include/configs/smdk2440.h中相应位置(参考CS8900)添加如下代码:
#define CONFIG_DRIVER_AX88180?1
#define AX88180_BASE???0x08000000
4. 最后在drivers/Makefile中加入ax88180.o,重新编译生成U-BOOT即可。
结语
U-BOOT广泛应用在嵌入式系统中,本文阐述的方法可以使U-BOOT功能更强大、使用更方便,文中介绍的硬件平台给嵌入式系统千兆 网络功能的设计提供了一定的指导。本设计虽然基于S3C2440A平台,对其它类似的系统也有很好的借鉴作用,本文介绍的方法已经在产品中得到应用,效果 良好。 ■
参考文献
1. 钱峰. U-Boot在S3C44B0上的移植[J].微计算机信息.2006年第9-2期:P119-121
2. 聂强,孙贺. linux_mig_ release.pdf. http://www.hhcn.com/chinese/files
3. Allan Chou. ax88180.c.ASIX Electronics Corporation.2006
RAM Configuration:
Bank #0: 30000000 64 MB
Flash: 1 MB
*** Warning - bad CRC, using default environment
Out: serial
Err: serial
RAM Configuration:
Bank #0: 30000000 64 MB
Flash: 1 MB
NAND: 64 MB
*** Warning - bad CRC, using default environment
Out: serial
Err: serial
* Command definition
***********************************************************/
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_NAND | \
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I2C |*/ \
/*CFG_CMD_USB |*/ \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_ELF)
NAND_WAIT_READY(nand); /* do the worst case 25us wait */
else
udelay(10);
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
* NAND flash basic functions
* Added by Lu Xianzi 2006.5.27
* Copied from board/mpl/vcma9/vcma9.h & vcma9.c
*/
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
{
NF_Cmd(cmd);
udelay(1);
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
case NFCE_LOW:
nand->NFCONF &= ~(1<<11);
break;
nand->NFCONF |= (1<<11);
break;
}
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
}
{
int i;
NF_Cmd(0xFF); /* reset command */
for(i = 0; i < 10; i++); /* tWB = 100ns. */
NF_WaitRB(); /* wait 200~500us; */
NF_SetCE(NFCE_HIGH);
}
{
#if 0 /* a little bit too optimistic */
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif
/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
}
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
#ifdef DEBUG
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
* NAND flash settings
* Added by Lu Xianzi 2006.5.27
* Copied from include/conifgs/vcma9.h
*/
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#define SECTORSIZE 512
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW)
#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)
#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)
#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)
#define WRITE_NAND(d, adr) NF_Write(d)
#define READ_NAND(adr) NF_Read()
/* the following functions are NOP's because S3C24X0 handles this in hardware */
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
Because there's no definition of a macro called __mem_pci,
there will be a link error.
*/
#define CONFIG_MTD_NAND_ECC_JFFS2 1
RAM Configuration:
Bank #0: 30000000 64 MB
Flash: 1 MB
*** Warning - bad CRC, using default environment
Out: serial
Err: serial
## Start Addr = 0x33000000
## Starting application at 0x33000000 ...
U-Boot 1.1.2 (May 28 2006 - 08:36:42)
RAM Configuration:
Bank #0: 30000000 64 MB
Flash: 1 MB
NAND: 64 MB
*** Warning - bad CRC, using default environment
Out: serial
Err: serial
LXZROB #
nand info - show available NAND devices
nand device [dev] - show or set current device
nand read[.jffs2[s]] addr off size
nand write[.jffs2] addr off size - read/write `size' bytes starting
at offset `off' to/from memory address `addr'
nand erase [clean] [off size] - erase `size' bytes from
offset `off' (entire device if not specified)
nand bad - show bad blocks
nand read.oob addr off size - read out-of-band data
nand write.oob addr off size - read out-of-band data
Size: 1 MB in 19 Sectors
Sector Start Addresses:
00000000 (RO) 00004000 (RO) 00006000 (RO) 00008000 (RO) 00010000 (RO)
00020000 00030000 00040000 00050000 00060000
00070000 00080000 00090000 000A0000 000B0000
000C0000 000D0000 000E0000 000F0000 (RO)
Un-Protected 5 sectors
LXZROB # flinfo
Size: 1 MB in 19 Sectors
Sector Start Addresses:
00000000 00004000 00006000 00008000 00010000
00020000 00030000 00040000 00050000 00060000
00070000 00080000 00090000 000A0000 000B0000
000C0000 000D0000 000E0000 000F0000 (RO)
Erasing sector 0 ... ok.
Erasing sector 1 ... ok.
Erasing sector 2 ... ok.
Erasing sector 3 ... ok.
Erasing sector 4 ... ok.
Erased 5 sectors
Copy to Flash... done