简介:
实验目的
实验环境
实验步骤inline void wait_idle(void) {
int i;
while(!(NFSTAT & BUSY))
for(i=0; i<10; i++);
}
* low level nand read function *
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
Create PDF files without this message by purchasing novaPDF printer (http:www.novapdf.com) if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
return -1; * invalid alignment *
}
* chip Enable *
NFCONF &= ~0x800;
for(i=0; i<10; i++);
for(i=start_addr; i < (start_addr + size);) {
* READ0 *
NFCMD = 0;
* Write Address *
NFADDR = i & 0xff;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = (NFDATA & 0xff);
buf++;
}
}
* chip Disable *
NFCONF |= 0x800; * chip disable *
return 0;
}
# endif
四.同时修改 boardfs2410Makefile文件,增加 nand_read文件
COBJS := fs2410.o nand_read.o flash.o
五、修改 boardfs2410fs2410.c 文件,加入 NAND Flash 操作
(1)加入Nand Flash的初始化函数
在文件的最后加入Nand Flash的初始化函数,该函数在后面Nand Flash的操作都要用到。
u-boot运行到第2阶段会进入start_armboot()函数。其中nand_init()函数是对nand flash的最
初初始化函数。nand_init()函数在两个文件中实现。其调用与 CFG_NAND_LEGACY 宏有
关,如果没有定义这个宏,系统调用 driversnandnand.c 中的 nand_init();否则调用自己在
本文件中的 nand_init()函数,本例使用后者。fs2410.c代码如下:
#if defined(CONFIG_CMD_NAND)
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;
static inline void NF_Conf(u16 conf)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF = conf;
}
Create PDF files without this message by purchasing novaPDF printer (http:www.novapdf.com)static inline void NF_Cmd(u8 cmd)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCMD = cmd;
}
static inline void NF_CmdW(u8 cmd)
{
NF_Cmd(cmd);
udelay(1);
}
static inline void NF_Addr(u8 addr)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFADDR = addr;
}
static inline void NF_WaitRB(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
while (!(nand->NFSTAT & (1<<0)));
}
static inline void NF_Write(u8 data)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFDATA = data;
}
static inline u8 NF_Read(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFDATA);
}
static inline u32 NF_Read_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFECC);
}
static inline void NF_SetCE(NFCE_STATE s)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
switch (s) {
case NFCE_LOW:
nand->NFCONF &= ~(1<<11);
break;
case NFCE_HIGH:
nand->NFCONF |= (1<<11);
Create PDF files without this message by purchasing novaPDF printer (http:www.novapdf.com) break;
}
}
static inline void NF_Init_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF |= (1<<12);
}
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
int i;
NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); * reset command *
for(i = 0; i < 10; i++); * tWB = 100ns. *
NF_WaitRB(); * wait 200~500us; *
NF_SetCE(NFCE_HIGH);
}
static inline void NF_Init(void)
{
#if 0
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif
当配置参数CONFIG_S3C2440被定义为真时,
执行以下操作:NF_Conf((TACLS左移12位)|(TWRPH0左移8位)|(TWRPH1左移4位)); NF_Cont((1<<6)|(1<<4)|(1<<1)|(1<<0));
否则,
执行以下操作:NF_Conf((1<<15)|(!TWRPH0的低14位值)|(!TWRPH0的低7位值)|(TACLS左移8位)...);
其中,nand->NFCONF等于(1<<15)|(1<<14)|(1<<13)|(1<<12)|...;
注释:
- 该操作表示为:[数值序列]、[参数描述]、[返回结果];
具体说明如下:
En 512B的四步ECRC校验nFCE=H,其中tACLS、tWRPH0和tWRPH1分别对应相应的参数值;
执行完成后,
调用NF_Reset();
6
void nand_init(void) { /* 创建PDF文件需购买 novaPDF 打印机 (http:www.novapdf.com) */}
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
NF_Init();
#ifdef DEBUG
printf(NAND flash probing at 0x%.8lXn, (ulong)nand);
#endif
printf (%4lu MBn, nand_probe((ulong)nand) >> 20);
}
【6
该模块涉及的底层接口函数包括Nand Flash命令层的相关操作。其中包含多个宏定义用于实现不同功能:
#define addressWriteNand(d, adr) {rNFADDR = d;}
#define writeNand(d, adr) {rNFDATA = d;}
#define readNand(adr) (rNFDATA)
#define waitReady(nand) {while(!(rNFSTAT&(1<<0)));}
#define commandWriteNand(d, adr) {rNFCMD = d;}
#define commandWriteNandWithWord(d, adr) {NF_CmdW(d)}
此外,这些函数属于NOP类型,因为S3C24X0处理器在硬件层面进行了相关处理。这些函数用于支持NAND闪存的写入校验功能。
(6)加入Nand Flash启动支持(在文件结尾处)
* Nandflash Boot*
#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x8000
* NAND Flash Controller *
#define NAND_CTL_BASE 0x4E000000
#define bINT_CTL(Nb) __REG(INT_CTL_BASE + (Nb))
* Offset *
#define oNFCONF 0x00
#define CONFIG_S3C2410_NAND_BOOT 1
* Offset *
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x0c
#define oNFSTAT 0x10
#define oNFECC 0x14
#define rNFCONF (*(volatile unsigned int *)0x4e000000)
#define rNFCMD (*(volatile unsigned char *)0x4e000004)
Create PDF files without this message by purchasing novaPDF printer (http:www.novapdf.com)#define rNFADDR (*(volatile unsigned char *)0x4e000008)
#define rNFDATA (*(volatile unsigned char *)0x4e00000c)
#define rNFSTAT (*(volatile unsigned int *)0x4e000010)
#define rNFECC (*(volatile unsigned int *)0x4e000014)
#define rNFECC0 (*(volatile unsigned char *)0x4e000014)
#define rNFECC1 (*(volatile unsigned char *)0x4e000015)
#define rNFECC2 (*(volatile unsigned char *)0x4e000016)
#endif
(7)加入 jffs2的支持
*JFFS2 Support *
#undef CONFIG_JFFS2_CMDLINE
#define CONFIG_JFFS2_NAND 1
#define CONFIG_JFFS2_DEV nand0
#define CONFIG_JFFS2_PART_SIZE 0x4c0000
#define CONFIG_JFFS2_PART_OFFSET 0x40000
*JFFS2 Support *
(8)加入 usb的支持
* USB Support*
#define CONFIG_USB_OHCI
#define CONFIG_USB_STORAGE
#define CONFIG_USB_KEYBOARD
#define CONFIG_DOS_PARTITION
#define CFG_DEVICE_DEREGISTER
#define CONFIG_SUPPORT_VFAT
#define LITTLEENDIAN
* USB Support*
七、修改 includelinuxmtdnand.h头文件
屏蔽如下定义:
#if 0
* Select the chip by setting nCE to low *
#define NAND_CTL_SETNCE 1
* Deselect the chip by setting nCE to high *
#define NAND_CTL_CLRNCE 2
* Select the command latch by setting CLE to high *
#define NAND_CTL_SETCLE 3
* Deselect the command latch by setting CLE to low *
#define NAND_CTL_CLRCLE 4
* Select the address latch by setting ALE to high *
#define NAND_CTL_SETALE 5
* Deselect the address latch by setting ALE to low *
#define NAND_CTL_CLRALE 6
* Set write protection by setting WP to high. Not used! *
#define NAND_CTL_SETWP 7
* Clear write protection by setting WP to low. Not used! *
Create PDF files without this message by purchasing novaPDF printer (http:www.novapdf.com)#define NAND_CTL_CLRWP 8
#endif
八、修改 includelinuxmtdnand_ids.h 头文件
在该文件中加入开发板的 NAND Flash型号
{Samsung K9F1208U0B, NAND_MFR_SAMSUNG, 0x76, 26, 0, 4, 0x4000, 0},
九、修改 commonenv_nand.c文件
我们使用了早期的Nand读写方式,因此做出下列移植:
(1) 加入函数原型定义
extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, size_t len, int clean);
* info for NAND chips, defined in driversnandnand.c *
extern nand_info_t nand_info[CFG_MAX_NAND_DEVICE];
(2) 修改saveenv函数
注释if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))
加入:if (nand_legacy_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0))
注释ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
加入:ret = nand_legacy_rw(nand_dev_desc + 0,0x00 | 0x02,
CFG_ENV_OFFSET,
CFG_ENV_SIZE,
&total, (u_char*)env_ptr);
(3) 修改env_relocate_spec函数
注释ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);
加入:ret = nand_legacy_rw(nand_dev_desc + 0,
0x01 | 0x02,
CFG_ENV_OFFSET,
CFG_ENV_SIZE,
&total, (u_char*)env_ptr);
十、修改 commoncmd_boot.c 文件,添加内核启动参数设置
(1) 首先添加头文件#include
(2) 修改do_go函数。具体修改为:
int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
#if defined(CONFIG_I386)
DECLARE_GLOBAL_DATA_PTR;
#endif
ulong addr, rc;
int rcode = 0;
char *commandline = getenv(bootargs);
指针变量my_params初始化为特定内存地址。
函数将指定结构体的每个字节置零。
my_params->u1.s.page_size属性设置为4096字节。
my_params->u1.s.nr_pages属性通过位运算计算得到具体值。
memcpy函数将源字符复制到目标区域,增加末尾一个字节以确保完整传输。
无需此提示信息的PDF文件可通过购买novapdf打印机创建(http://www.novapdf.com)。
若参数数量少于2个,则输出错误使用信息并返回退出码1。
地址变量addr由argv[1]转换为无符号长整数得到。
程序启动时会输出相关信息,其中* argv[0]指定命令名称及后续所有参数。
针对x86架构的特殊处理方式:将全局数据指针gd赋值给argv[0]位置。
对于非Nios内核的操作系统,该功能需通过其他方法实现。
该函数初始化了多个寄存器和缓存机制。首先,将r1寄存器初始化为0x77FFn以实现硬件启动所需的初始状态。随后,设置ip指针指向内存的第0个字节位置并将其标记为n无效位,确保后续操作的安全性。通过执行mcr指令序列分别对p15控制域进行配置:首先设置零PID字段,接着清除I/D缓存以防止原有数据干扰;之后启动写缓冲区排空功能,并清除非必要项中的I/D TLB条目。随后,获取控制寄存器的值并决定MMU是否需要禁用。最后,通过 Series 指令完成整个初始化流程。rc = ((uint64_t*(int,char*)[])(addr))((--argc),&argv[1]);
#ifndef __NIO__*/
*
*Nios functions addresses undergo right shift by one bit to accommodate function pointers.*/
rc = ((uint64_t*(int,char*)[]) (addr>>1)) ((--argc), &argv[1]);
#endif /*__NIO__*/ if (rc != 0) rcode = 1;
生成无此提示信息的PDF文件并安装并配置novaPDF打印机(http:www.novapdf.com)。编译以下代码:
#include
int main() {
printf(## Application terminated, rc = 0x%lXn, rc);
return (rc);
}
其中用括号标记的代码是需要添加进去的。
如果不将这些参数正确传递给Linux内核进行启动,则会遇到无法正常初始化的错误。其根本原因在于平台号或启动参数设置不正确。请确保所有必要的内核启动参数已正确传入并配置。
在交叉编译U-BOOT阶段,首先执行以下命令:
$ make distclean
$ make fs2410_config
然后在终端中输入以下环境变量设置:
export PATH=$PATH:homelinuxcrosstoolgcc-3.4.5-glibc-2.3.6arm-softfloat-linux-gnubin:
接着运行编译命令:
$ arm-linux-gnueabuild -O0 -mthumb /
最后执行验证步骤:
$ ./finalized_image
#make CROSS_COMPILE= arm-softfloat-linux-gnu 并生成我们的移植版本 u-boot.bin。将此文件下载至开发板并执行。生成PDF文件而不包含此消息的方式是通过购买novaPDF打印机(http:www.novapdf.com)进行的。U-Boot介绍U-Boot是一款基于GPL条款的开放源代码项目,源自于FADSROM、8xxROM和PPCBOOT等项目的演进与扩展。其中,许多U-Boot源代码实际上是相应Linux内核源代码的简化版本,并特别针对嵌入式设备中的设备驱动进行了优化处理。然而,在功能上,U-Boot不仅限于支持嵌入式Linux系统的引导程序,如今它已扩展至包括NetBSD、VxWorks等多款嵌入式操作系统的支持。目前其主要支持的目标系统包括OpenBSD、NetBSD、FreeBSD等。另一层意义在于它能够兼容多种不同的嵌入式处理器类型,并提供相应的操作系统支持。其主要开发目标就是为嵌入式设备提供一个通用且灵活的解决方案,以确保在各种复杂环境下都能稳定运行。特别是在PowerPC处理器领域,U-Boot的表现尤为突出,在这方面目前没有任何其他开源项目能与之竞争。此外,U-Boot还特别注重对不同处理器系列的支持,包括ARM、MIPS、x86等主流类型,并且能够轻松应对这些设备的移植工作。尤其是在PowerPC处理器领域,U-Boot的表现尤为突出。当前项目维护由德国DENX公司的软件工程师Wolfgang Denk博士担任,他凭借其专业技术和持着不懈的努力,推动了这一项目的顺利发展。作为一款功能强大且高度灵活的开源BOOT Loader,U-Boot现已成为许多嵌入式开发人员的重要选择工具。基于此特性,我们有理由相信,在未来的发展中它将为更多的嵌入式操作系统的实现提供有力支持。
U-Boot的核心内容是其体系结构。
该资源包包含多个关键文件夹及其实现内容,具体如下:
1. 目标板相关文件:主要包含用于存储动态随机存取存储器(SDRAM)和闪存驱动的文件;
2. 独立于处理器体系结构的通用代码:如内存大小探测与故障检测功能相关的代码;
3. 处理器相关文件:包括与处理器架构相关的目录,例如mpc8xx子目录下包含串口、网口、LCD驱动程序以及中断初始化等文件内容;
4. 通用设备驱动程序:涵盖多种类型的应用程序,目前对INTEL闪存支持较好,如CFI FLASH驱动程序;
5. PDF创建工具:用于生成U-Boot说明文档的软件包链接(可通过购买novaPDF打印机获取);
6. 可运行示例程序:包含在U-Boot环境中可直接运行的程序文件夹,例如hello_world.c、timer.c等;
7. 头文件接口:提供核心功能接口定义的头文件集合,其中 configs子目录下的与目标板相关的配置头文件是移植过程中需要重点修改的部分;
8. 处理器体系结构相关文件:如lib_ppc和lib_arm目录下分别包含PowerPC和ARM架构体系结构相关的文件内容;
9. 网络功能实现文件:包括bootp、nfs、tftp等目录下的网络功能相关文件;
10. 上电自检配置文件:位于post子目录中,目前仍需进一步完善;
11. RTC驱动程序:用于实时时钟控制的软件包内容;
12. U-Boot镜像创建工具:提供用于生成U-Boot S-RECORD和BIN格式镜像文件的工具包集合。U-Boot则主要支撑其在核心作用上的发挥。U-Boot系统可支持的主要功能列表如下:
1. 系统引导:
- 支持通过NFS协议进行文件系统挂载,可采用压缩或非压缩的FRAMING形式实现根文件系统的建立;
- 可从存储设备如FRAMING进行启动,支持压缩和非压缩版本的系统内核初始化;
2. 基本辅助功能:
- 提供强大的操作系统接口功能,允许用户灵活设置并传递关键参数以满足不同开发阶段的调试需求;
- 适用于Linux等操作系统的强大兼容性设计,特别强调对Linux环境的支持能力最强;
3. 目标板环境支持:
- 支持多种存储方式配置目标板环境,包括FRAMING、NVRAM、EEPROM等多种存储介质;
- 提供CRC32校验功能,用于验证FRAMING中内核镜像文件的完整性保证数据传输的安全性;
4. 设备驱动支持:
- 支持串口、SDRAM、FLASH、以太网、LCD等设备的硬件驱动配置;
- 同时也支持NVRAM、EEPROM、键盘、USB、PCMCIA、PCI等多种接口类型的硬件配置;
- 包括RTC(时间码)相关的驱动支持;
5. 上电自检功能:
- 实现对FRAMING容量的自动计算和初始化功能,同时提供SDRAM故障检测能力;
- 可依据CPU型号参数进行相应的设置以优化系统性能;
6. 特殊功能:
- 支持XIP内核引导方式,通过启动向量进行配置的内核引导方式支持多种版本选择;移植前的准备
(1)建议先阅读uboot自带的readme文档以获得基本了解。
(2)在common.h文件中可以看到一些基础内容,并包含了一些必要的头文件。同时,在flash.h中定义了一个名为flash_info_t的结构体,该结构体内嵌入了闪存的一些属性定义。此外,这个文件还详细说明了所有Flash属性的相关信息。其中,AMD设备特有的属性包括:AMD_ID_LV320B,其值为“#define AMD_ID_LV320B 0x22F922F9”。
(3)关于.boradat91rm9200dkflash.c的修改工作主要包括以下几个方面:
a. 在函数定义OrgDef的基础上增加了当前闪存相关的内容。
b. 修改了全局变量Flash_BANK_SIZE的值,将其设定为自定义容量。
c. 对于函数 flash_identification(flash_info_t* info)的作用进行了重新表述:该函数的主要任务是在uboot启动时输出相关信息。
d. 在函数 flash_init(void)中对一系列变量赋值的方式发生了改变。
e. 最后一项修改内容是关于函数 flash_print_info(flash_info_t *info),其功能是实际打印闪存信息。
f. 还需调整另一个函数flash_erase的功能逻辑,使其在特定条件下进行操作。具体来说,在检测到已知Flash类型与当前设备不匹配的情况下,对该函数进行了注释处理。
接下来观察SDRAM修改方案,并对其修改方案进行研究
在该资源中,关于‘SIZE’的具体说明是按照字节进行计算的。为了实现这一目标,只需要修改文件中的具体数值即可。特别指出的是,在此定义中,‘SIZE’一词是按照字节进行计算的。(8):还有一个需要特别注意的地方。在当前设置下,一级 boot 运行了 u_boot 到 SDRAM 的空间中,具体位置如下:21F00000 -> 21F16B10。正好对应了 SDRAM 的高端区域。另外,对应的 BSS 区域为 21F1AE34。
a. 对u-boot.bin进行gzip压缩。$ gzip –c u-boot.bin > u-boot.gz $
b. 接着将boot.bin以及已经压缩好的u-boot.gz写入Flash存储器中。其中,boot.bin大约为11kBytes,具体存储位置在Flash的0x1000 0000 ~ 0x1000 3fff区域。
U-Boot的迁移流程
获得官方发布的最新版U-Boot源码,其格式与Linux内核源码具有相似性,并采用bzip2压缩方式存储。通过访问U-Boot的官方网站http://sourceforge.net/projects/U-Boot可以获取该版本代码包。
② 参考相关文档,尤其是 U-Boot 源码根目录下的 README 文档和 U-Boot 官方网站发布的 DULG 手册(The DENX U-Boot and Linux Guide)http://www.denx.detwikibinviewDULGManual。该手册详细介绍了如何建立交叉开发环境以及解决了移植过程中常见的问题。
③ 访问 U-Boot 用户邮件列表 http://lists.sourceforge.net/lists/listinfou-boot-users。在移植过程中遇到问题后,首先查阅相关文档,并访问 U-Boot 用户邮件档案库 http://sourceforge.net/mailarchive/forum.php?forum_id=12898 进行进一步搜索仍无法解决的情况下,立即提交所遇到的问题。众多热心的 U-Boot 开发人员会及时协助排查问题,并且很有可能,W.D 将会直接参与指导。
基于构建的开发环境中完成移植操作。大多数开发环境采用交叉编译模式,在此领域内,DENX和MontaVista都配备了全面的开发工具包。
在目标板与开发主机之间安装硬件调试器。该设备作为关键的调试验试工具使用,在U-Boot移植工作中尤其重要且不可或缺。特别是在整个移植过程的初期阶段,唯有通过硬件调试器才能准确了解目标板的真实运行状态。鉴于此,W.D本人以及众多嵌入式开发专家更倾向于采用BDI2000这一调试设备。一方面,与其相比ICE调试器成本更低;另一方面,其具有极强的成本效益优势,在可靠性、功能性等方面表现卓越,完全可以胜任U-Boot的移植与调试验证工作。此外,网络上也有关于BDI2000调试的参考资料。在移植U-Boot的过程中可能会遇到目标板上已有的BOOT LOADER的移除问题。根据说明书,在移除现有BOOT LOADER的前提下,可以先着手解决恢复的方法。从而可以在未来需要的时候方便地恢复原先的BOOT LOADER。目前针对U-Boots的移植方案主要可分为两类。第一类是基于BDI2000设备构建目标板启动基础环境,该过程包括获取U-Boots镜像文件u-boot.bin并将其存储在目标板内存的特定区域。随后利用BDI2000设备执行程序调试过程。这种方法的优势在于无需将U-Boot 镜像文件写入FRAM存储器中,从而降低了对开发人员专业技能的要求。然而其配置文件设置相对复杂,调试工作需要较高的专业知识和经验。
第二种方案则采用BDI2000设备将U-Boots镜像文件复制至系统存储器,并通过集成GDB工具与BDI2000设备实现程序调试过程。这种方法的显著优点在于简化了BDM配置流程,且整个调试流程与实际运行过程高度契合:即首先由FRAM存储器加载U-Boot操作系统内核,随后完成数据段复制至内存区域并切换至该内存空间进行正常运行操作。需要注意的是,在这种方案下需要频繁执行烧录操作以确保FRAM存储器的稳定性。
鉴于FRAM存储器的常规擦写次数通常在10万次左右,对于U-Boot移植工作而言,上述操作不会对FRAM设备造成显著影响。因此可以认为该方法具有较高的可行性。综合考虑各种因素后,W.D个人更倾向于采用第二种方案,并建议普通移植人员除非具备较高的专业素养或得到技术支持的情况下,尽量选择此方案作为首选策略。在进行U-Boot移植时,需对以下文件进行重点调整:①目标板的.h头文件配置文件,如includeconfigsRPXlite.h等。这些文件负责设置寄存器参数;②. c配置文件(如boardRPXliteRPXlite.c),该文件主要负责SDRAM控制器的UPM表设置及上电初始化操作;③Flash存储控制器(如boardRPXliteflash.c或commoncfi_flash.c),需根据目标板的FLASH数据手册进行适当修改以满足移植需求;④串口通信接口的配置文件(如cpumpc8xxserial.c),需对其中的串口收发器芯片使能部分进行调整。U-Boot移植的关键点包括系统初始化、文件加载和硬件配置等,需要特别注意裸机态启动的兼容性与稳定性保障措施。注
注
注
在开展U-Boot移植工作时需要特别关注几个关键点。首先,根据目标板的硬件配置(包括CPU、FLASH和SDRAM)选择合适的移植参考板至关重要。建议优先选用与目标板处理器型号一致或同系列的U-Boot支持板作为移植参考,例如RPXlite系列中的某款型号即可满足需求。对于新手操作者,按照循序渐进的学习曲线逐步掌握技术要领,在熟悉移植流程后才可考虑对目标板进行命名优化。在实际操作过程中,可以通过grep命令定位关键代码片段(如grep –r RPXlite .),并据此对移植参考板的代码进行相应的屏蔽或修改工作。此外,建议不要局限于现有参考板中的代码库,应充分借鉴U-Boot已有的优秀实现案例,以期更好地完成特定功能模块的开发任务。U-Boot烧录地址的配置因目标主板而异。各款目标主板对U-Boot存储位置的要求各异,这种差异主要由处理器的中断复位向量所决定,并受主板硬件配置的影响。具体而言,在MPC8xx系列主板上,这一参数是由HRCW(硬件配置字)进行设置的。因此,U-Boot的烧录起始地址是由硬件参数所指定的,而不是通过程序设计来任意选择的。在实际操作中,必须确保程序中的U-Boot起始地址与处理器中断复位向量设置保持完全一致;例如,在RPXlite DW主板上,中断复位向量被设置为0x00000100。因此,U-Boot的BIN镜像数据必须精确烧录到FLASH存储器的起始位置。需要指出的是,大多数PPC系列处理器的中断复位向量设定通常包括两个值:0x0000010O和$FFFOOOO O(或类似的高位启动和低位启动模式)。通过修改目标主板的U-Boot源代码<目标板>.h中的CFG_MONITOR_BASE参数,以及在board<目标板>对应的config.mk文件中调整TEXT_BASE设置,可以实现对硬件配置的有效匹配。CPU寄存器的参数设置因各处理器系列及类型而异,需要依据目标芯片的具体情况,进行科学合理的参数设置。一种切实可行且操作简便的方式是取其移植经验作为基础,并结合目标芯片的实际需求,进行优化调整。这一过程既耗时又费力,对技术功底要求较高。MPC8xx处理器较为关键的寄存器设置包括SIUMCR、PLPRCR、SCCR、BRx和ORx等。串口调试。通过串口输出信息,即使出现乱码现象,也表明U-Boot移植已实现了实质性的突破。依据笔者的调试经验,在串口是否有有效输出这一问题上,不仅受串口驱动芯片性能的影响,还与相关存储设备中的FLASH寄存器设置密切相关。由于U-Boot系统是从FLASH存储空间被引导启动的程序,因此如果 FLASH 设备配置不当,就可能导致U-Boot代码读取和执行过程中出现异常现象。为此,在进行 U-Boot 系统调试时,需要特别关注并调整相关存储设备中的寄存器设置参数。同时,还需对串口收发芯片的工作波形特性进行详细分析。根据笔者的调试经历,如果串口无法输出数据或出现乱码情况,则可能的原因包括:硬件损坏、工作状态异常等。因此,在实际操作中,应逐一排查可能导致问题的因素,并采取相应的调整措施以确保系统的正常运行。与启动FLASH相关的寄存器BR0、OR0的参数设置需注意其相关位含义。在配置BR0和OR0时,需要参考目标板FLASH的数据手册,结合这些寄存器对应的相关位的定义来完成参数设置。这不仅关系到FFF能否顺利启动的同时,这一过程还与其后续的串口调试操作有着密切的关系。关于CPLD电路。即使目标板上有CPLD电路,也不会对U-Boot移植及嵌入式操作系统正常运行造成任何影响。实际上,CPLD电路是一种可能的实现手段。它主要用于生成所需的脉冲信号并配置部分电路逻辑,其功能完全可以由一些逻辑电路和CPU总线来实现。
SDRAM的主控芯片存储器控制器部分驱动与调试工作同样关键。串口外设正常发送信号后,U-Boot移植能否顺利进行主要取决于其主控芯片存储器控制器部分的驱动是否正确实现。这一阶段的工作内容较为复杂,涉及多个方面:首先需要完成相关寄存器的配置;其次要确保UPM表的完整性;最后还需完成对SDRAM上电初始化过程的支持工作等。其中任何一个环节出现问题都会导致U-Boot、嵌入式操作系统以及后续应用程序运行出现不稳定现象。因此可以说,SDRAM驱动部分不仅关系到U-Boot是否能够正常运行,而且是整个系统架构中非常重要的基础模块。
在获得一个能工作的 U-Boot 后,就可以根据目标板及其实际开发需求增添额外功能的支持。这些功能包括网络通信(Ethernet)、 Liquid Crystal Display (LCD) 和 NVRAM 存储器等。相较于串口接口及SDRAM存储器的调试工作而言,在现有基础上增添其他功能相对更为简便。通常只需基于现有开源代码库进行一定程度上的调整与配置即可。
如果将U-Boot成功移植至自研主板,则需要从软硬件兼容性出发进行初步筛选与评估。例如,需关注其电路原理设计是否匹配、PCB布局是否合理以及所选元器件的性能状态等。准确识别故障源点(硬件或软件)往往成为移植成功与否的关键因素之一。以下以将u-boot移植至44B0开发板的过程为例,在移植过程中,主要涉及硬件部分的修改。具体操作如下:
1. 在board目录中新建ev44b0ii目录,并在里面创建ev44b0ii.c、flash.c、memsetup.S和u-boot.lds等文件。
2. 在cpu目录中新建arm7tdmi子目录,在其中主要包含start.S、interrupts.c以及cpu.c和serial.c等多个文件。这些内容无需从头开始复制,可以直接从arm720t开发板的相应位置进行复制,并对具体内容进行修改。
3. 在includeconfigs目录下添加ev44b0ii.h文件,这个步骤需要在其中放置全局的宏定义等信息。
4. 找到位于u-boot根目录下的Makefile文件,并对其进行修改,添加如下内容:
```
ev44b0ii_config : unconfig
@.mkconfig $(@:_config=) arm arm7tdmi ev44b0ii
```
5. 最后执行make ev44b0ii_config命令。如果操作过程中未出现错误提示,就可以开始进行硬件相关的代码移植工作。u-boot的体系结构如下:
1)总体结构:
u-boot采用层次化设计,从上图可以看出,在移植工作中需要为UART、Ether网、Flash以及USB接口提供相应的驱动。
目前,针对USB接口的驱动尚未必要,因此暂未开发相关驱动程序。在驱动层之上,u-boot承担着通过串口与人机交互的功能。常用命令如md可实现基本操作。
Kermit工具则用于通过串口使用超级终端下载应用程序;TFTP则提供网络下载功能。
2)内存分布:
在flash rom中,内存分布图ev44b0ii的闪存大小为2M(8bits),现将地址范围0-40000(共256k)指定为u-boot的存储空间。由于u-boot包含一些环境变量如IP地址、引导文件名等,在命令行中可通过setenv进行配置,并将这些信息保存在40000-50000区间的内存段内。
如果已存在预设的环境变量,u-boot引导可以直接使用这些设置。从代码分析可见,我们将在DRAM中运行flash引导代码,并将其加载至地址范围为0x0C700 16中的位置(如图所示)。特别注意的是,在ev44b0ii uclinux中断向量程序的地址位于0x0c0 8 256,因此不能将程序下载至此处。通常情况下,我们会将其下载到较远的位置,例如0x0c08 16。每个Image必须只有一个入口,在Rom(flash)内存空间的基址位置通常被设置为全局入口点。其中在start.S文件中定义了.globl _start,并将其作为入口点存放。需要注意的是,必须向编译器告知该入口地址,而这一工作的核心内容则是修改相关联的符号数据文件(Link Data Set),也就是通常所说的lds文件。
配置异常处理向量表,也可称为中断向量表,在uclinux系统中必须以0地址起始并连续存储所有指令项。该表需与uclinux的vector_base参数相匹配,例如当vector_base定义为0x0c00 0000时,HandleUndef应设置在相应的内存位置上。
具体配置步骤如下:
将目标地址设置为HandleUndef处:
ldr pc,=HandleUndef
同理,其他处理指令的设置方式类似:
- SWI: ldr pc,=HandleSWI
- Pabort: ldr pc,=HandlePabort
- Dabort: ldr pc,=HandleDabort
- Reserved: ldr pc,=HandleReserved
(注: reserved 通常用于标记未定义的处理)
继续配置:
ldr pc,=Handle IRQ
ldr pc,=Handle FIQ
其他高级中断向量项的设置方式:
ldr pc,=HandleEINT0
ldr pc,=HandleEINT1
...依此类推
对照各标记值,确保所有异常向量正确无误地分配到对应的内存位置上。例如:
.equ HandleReset 0xc000000
.equ HandleUndef 0xc000004
.equ HandleSWI 0xc00008
对照完毕后,可进一步验证各异常处理指令的配置是否正确。
初始化与CPU相关的pll、clock、中断控制寄存器(其中包括watchdog timer和interruption mask)以及锁时钟参数。这些值包括locktime、pllcon和其他时钟设置。操作步骤如下:
1. 初始化并关闭watch dog timer:通过执行ldr r0,WTCON followed by ldr r1,=0x0,将wtcon置零以关闭watch dog timer。
2. 关闭所有中断:使用str r1,[r0]指令来设置intmsk寄存器为零,从而关闭所有中断。
3. 设置锁时钟参数(locktime):通过ldr r0,LOCKTIME followed by ldr r1,=800,将locktime的计数值计算为t_lock乘以fin值。其中,默认情况下t_lock设为200us,fin设为4mhz。
4. 配置PLL控制寄存器:设置pllcon寄存器中的初始值为800,并将其与锁时钟参数绑定。
5. 设置主时钟:将clkcon寄存器的值设置为0x7ff8以启用所有单元块的主时钟。
接下来,继续执行其他配置步骤:
- 配置pllcon_dat寄存器以支持更高的频率设置(例如10mhz输入和40mhz或60mhz输出)。
- 设置锁时钟参数:通过ldr r0,PLLCON followed by ldr r1,PLLCON_DAT来动态调整locktime的计数值。
这些步骤确保了系统的稳定性和正确配置。初始化内存控制器。该系统通过配置13个寄存器来实现内存管理功能,包括总线宽度、8个内存bank大小、单个bank的大小参数、总线clock频率控制和两种不同的bank模式设置。* 配置内存控制寄存器 *加载初始配置:memsetup:adr r0,SMRDATAldmia r0,{r1-r13}ldr r0,...BWSCON Addressstmia r0,{r1-r13}
首先,通过pc设备获取bootlegator在flash存储器起始地址的信息。然后,利用标号之间的差异计算出该程序代码的具体规模。这些标号将在编译过程中被正确分配以确保准确无误地反映程序特征。获得所需数据后,使用寄存器r3至r10作为临时存储介质,将代码复制到ram中。
移动armboot内容到RAM内存中。
创建无此提示信息的PDF文件,请购买novaPDF打印机(http:www.novapdf.com)。
源地址设置在r0寄存器。
目标地址存储于r1寄存器。
源区结束地址保存在r2中。
循环开始:copy_loop指令执行时,ldmia r0!, {r3-r10};然后stmia r1!, {r3-r10}。接着进行比较操作cmp r0, r2,并判断条件后调用copy_loop指令。
初始化堆栈的操作按照以下步骤进行:在各个运行状态中设置相应模式的堆栈结构。初始化顺序遵循如下原则:首先设置服务中断堆栈,在此之前依次执行以下操作以配置各种模式。具体步骤包括设置标志寄存器(cpsr)和通用目的寄存器(r0),然后执行位运算指令如bic r0,r0,#0X1F,接着完成其他初始化任务如设置未定义状态(UndefMODE|NOINT)、中断处理相关堆栈管理等。各模式的具体操作步骤如下: IRQMode的配置涉及多个机器指令的操作序列,确保堆栈结构正确无误。Without any unnecessary messages, you can create PDF files using the novaPDF printer (http://www.novapdf.com). By utilizing the address of the C function within RAM, you can seamlessly transfer files to this memory location without any issues.该软件系统启动前的准备步骤包括系统的初始化部分进行相应的参数配置。串口部分主要涉及初始化串口环节的同时,需要特别关注串口的Baudrate设置与其时钟MCLK之间的关系。计算公式为:rUBRDIV0 = ((int)(MCLK16.(gd → baudrate) + 0.5) - 1),这在相关手册中可查得详细解释。此外,数据发送与数据接收操作也是串口功能的重要组成部分。当中断未发生时,通常会通过循环等待的方式判断操作是否完成。例如,在实现接收函数时,可以使用以下代码:while(!((rUTRSTAT0 & 0x1) )) { Receive data read } return RdURXH0();
2. 时钟部分
完成了延时函数uDelay的功能模块实现。
这里的get_timer是通过全局变量进行累加计算的。
Flash存储器作为系统内存的一部分具有良好的可访问性。然而,其写入操作需要满足特定的条件和流程。
在进行写入操作之前必须进行擦除操作以确保数据的安全性和完整性。核心功能包括:初始化、擦除和写入等步骤,其中初始化阶段的主要目的是确认Flash存储器的类型是否正确。
int flash_init (void) {
// 初始化Flash存储器
}
int flash_erase (flash_info_t *info, int s_first, int s_last) {
// 进行数据擦除操作,并确保擦除过程的安全性
}
static int write_word(flash_info_t *info, ulong dest,ulong data) {
// 实现16位数据的写入功能,分两步完成以减少对系统资源的占用
}
*/ Write a word to Flash returns: */
* 0 - OK
* 1 - write timeout
* 2 - Flash not erased
注:由于考虑了兼容性问题,在实现过程中采用高低分离的方式进行数据处理。
U-Boot源码分析——启动第一阶段
建议在分析代码时,首先查看上电启动后的第一条执行指令。那么第一条指令的位置在哪里?以实例说明,我们来看它的链接脚本:文件 boardsmsk2410u-boot.lds:ENTRY(_start)指定程序入口地址(见汇编指令)。SECTIONS块中的入口段设置如下:.text:代码段。cpuarm920tstart.o (.text)确定启动后首先运行的第一个文件由.cuarm920tstart.o指定。/rodata:.rodata:静态数据段通过分析该文件可以看出运行的第一步任务很可能位于程序启动时最先执行的指令位置。具体而言,该文件中包含了一系列控制流程的关键代码块,这些代码在系统启动时会被优先处理以确保系统的正常运转。让我们深入观察一下这个程序的运行流程:首先查看主程序入口点所在的位置,然后确定各个子程序之间的调用关系图谱。
.text section:
.global globalsection
.R32 R32 register
.DFP.0 Dfp.zero float reg
.DFP.1 Dfp.one float reg
.R56 R56 register
.FP0 fp.reg[0] float reg
.FP1 fp.reg[1] float reg
.globl _start其中包含8条关于中断向量的规则,这些信息可在ARM相关书籍中找到以确定该段代码的具体编写方式。
该伪指令标识为.word,并用于实现变量替换。undefined_instruction: 该伪指令定义为.undefined_instruction,并表示未定义的指令。software_interrupt: 软件中断由.word标识器实现。
通过购买novaPDF打印机(www.novapdf.com)无需此提示创建PDF文件。prefetch_abort: 预取终止:.word prefetch_abort.
data_abort: 数据终止:.word data.abort.
not_used: 未使用的变量:.word not_used.
irq: 中断类型:.word irq.
fiq: 系统中断 flag:.word fiq.
S3C2410的CPU设置了开机后PC寄存器的起始地址为0,这意味着在开机时程序将从该地址开始执行指令。因此,在系统正常启动之前,必须将复位代码放置在相应的初始位置以确保正常开机。ARM架构规定,在启动地址所在区域的前32个字节应存储中断和异常处理所需的跳转信息;这些数据区包含了各种类型的处理函数及其相关的信息,在发生中断事件时,系统会按照预定义的流程在这里进行处理。据u-boot.lds显示,当系统启动时,程序从该起始地址设在_start位置开始依次执行指令。因此第一条指令应为:b reset 会引导至 reset 处进行重置操作。CPU接通电源时转移至本处后切换至SVC32模式以实现专权操作通过参考相关文档 *实际重置代码* 进行配置具体步骤如下首先执行移位和掩码指令对r0进行按位与运算随后或运算处理#0xd3字段最后完成状态寄存器的重置
Deactivate the watchdog在CPU上进行与watchdog相关寄存器的操作,具体信息可在CPU的数据手册中找到,其中使用的地址均为实际地址。由于尚未完成MMU等部件的初始化任务,并且目前未切换操作模式。
#if defined(CONFIG_S3C2400)
# define PWTCON的值为十六进制数0x15300000
并定义INTMSK寄存器的初始值为十六进制数0x14400008,此值标识中断控制器的基础地址
同时定义CLKDIVN寄存器的值为十六进制数0x14800014,该寄存器用于存储时钟除法比率为2:1的配置信息
#elif defined(CONFIG_S3C2410)
# define PWTCON的值为十六进制数0x53000000
并定义INTMSK寄存器的初始值为十六进制数0x4A000008,此值标识中断控制器的基础地址
同时定义INTSUBMSK寄存器的值为十六进制数0x4A00001C,并定义CLKDIVN寄存器的值为十六进制数0x4C000014,该寄存器用于存储时钟除法比率为2:1的配置信息
#endif
# if (CONFIG_S3C2400 || CONFIG_S3C2410)
首先加载pWTCON寄存器的内容到通用目的寄存器R0中
然后将R1初始化为零字节
创建PDF文件并移除此提示消息,可通过购买novapdf打印机(http:www.novapdf.com)来实现
关闭watchdog功能,并参考CPU手册以获取详细的信息
通过设置INTMSK寄存器的所有位为0值,可屏蔽所有中断控制器的中断请求
将R1初始化为十六进制数0xFFFFFFFF
随后加载INTMSK寄存器的内容到通用目的寄存器R0中
最后写入关闭所有中断状态的指令
# if defined(CONFIG_S3C2410)
Load register r1 with the value 0x3ff and store it into memory address specified by register r0 to disable all interrupts.
# endif
The ratio of F_CLK, H_CLK, P_CLK is set as 1 : 2 : 4 respectively. *
By default, the system operates at a base clock frequency of 120 MHz.
将 HCLK 设置为 FCLK2,并将 PCLK 设定为 FCLK4;同时,FCLK 由 CPU 产生 clock,而 AHB 总线上的设备会产生相应的 clock;同样地,APB 总线上的设备也会输出 clock。具体细节请参考 $s3c2410$ 数据手册中的详细信息。
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif * CONFIG_S3C2400 || CONFIG_S3C2410 *
*
* 我们仅在重启时执行sys-critical初始化,不从RAM加载!
*
注释
注释
注释
重定位程序代码至内存空间进行执行,具体步骤如下:
1. 通过读取指令起始位置指令获取存储区段起始地址。操作如下:ldr r2, _armboot_start(其中r2的值等于存储区段的起始地址,并可通过查看u-boot.lds文件获得该信息)。
2. 同样地,通过读取基准块开始位置指令获取基本输入/output数据段起始地址。具体操作为:ldr r3, _bss_start(其中r3的值等于基本输入/output数据段的起始地址,并可在u-boot.lds文件中找到该信息)。
3. 通过减法运算获得存储区段和基本输入/output数据段之间的距离,即sub r2, r3, r2。这样,r2变量就表示了需要重定位的字节数量。
4. 最后,将存储区段的起始位置累加其自身大小,以获取存储区段的结束位置:add r2, r0, r2(其中r2等于存储区段的结束地址)。
将代码从 flash中复制到ram
copy_loop:
ldmia r0!, {r3-r10} *加载并获取从 r0开始的代码段,存储于寄存器r3—r10*
stmia r1!, {#r3#-#r10#} *将 r3—r10 的内容复制到ram地址*r1!,即完成数据转移*
cmp r0, r2 *开始循环复制所有代码段*
ble copy_loop
#endif *若当前配置无需进行 relocation操作则跳过此块*
设置栈的起始地址:
stack_setup:
ldr r0, _TEXT_BASE *将upper 128 KiB区域的数据重定位到uboot程序空间中*
sub r0, r0, #CFG_MALLOC_LEN *其中malloc分配内存的区域大小由板子配置参数决定,具体设置可参考smdk2410在includeconfigssmdk2410.h中的定义*
sub r0, r0, #CFG_GBL_DATA_SIZE * 存放 bdinfo的区域,定义同上*
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
保留中断所需的区域
#endif
sub sp, r0, #12 * 保留 12 字节给 abort-stack, 并设好堆栈*
bss段内容清 0
clear_bss:
ldr r0, _bss_start * find start of bss segment *
ldr r1, _bss_end * stop here *
mov r2, #0x00000000 * clear *
clbss_l:str r2, [r0] * clear loop... *
add r0, r0, #4
cmp r0, r1
ble clbss_l
#if 0
* try doing this stuff after the relocation *
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
* mask all IRQs by setting all bits in the INTMR - default*
mov r1, #0xffffffff
ldr r0, =INTMR
str r1, [r0]
* FCLK:HCLK:PCLK = 1:2:4 *
* default FCLK is 120 MHz ! *
ldr r0, =CLKDIVN
mov r1, #3
Create PDF files without this message by purchasing novaPDF printer (http:www.novapdf.com) str r1, [r0]
* END stuff after relocation *
#endif
ldr pc, _start_armboot 跳转到_start_armboot处执行。
_start_armboot: .word start_armboot 综上所述,这段代码的作用域主要负责实现了以下几个方面:
1. 实施初始配置步骤时,请注意以下几点:
- 并禁止单点中断;
- 配置watchdog关机;
- 初始化内存控制器单元;
2. 将启动加载器重新安置至ram空间中。
3. 正确配置堆栈结构,确保数据完整性。
4. 切换至第二部分的处理逻辑。
完成这些后,此时内存的分布情况如下:此图展示了u-boot自身在内存中的状态。与上文所示不同的是,在这一区域中,(Text_BASE)对应的位置位于地址空间的偏移量处(即0x33F8’ 0000)。接下来将详细说明CPU初始化关键操作的具体步骤。
其中,CPU_init_critical指令负责以下几项设置:首先配置缓存、TLB和MMU等寄存器;其次确定内存操作的时间序列;最后通过相关注释(如可参考数据手册)完成上述功能。
在执行这些初始化操作之前,请确保以下步骤已正确配置:1. 启用低层初始化程序lowlevel_init.S;2. 设置CPU的时序参数,具体实现方式需根据板子特性进行调整。请特别注意以下几点:a) 在移动IP和LR前,需要首先调用lowlevel_init程序;b) 完成配置后应执行类似以下操作以模拟函数返回流程:
* 置r0寄存器为零值;
* 设置低层初始化入口地址到IP寄存器,并将LR设置为此入口地址的下一个字节位置;
* 将程序计数器PC设置为当前机器码起始地址。
这个流程类似于函数返回机制,确保整个初始化过程有序进行。
CPU初始化指令主要用于启用指令缓存,并关闭MMU及其相关组件。然而,在u-boot阶段之后的代码中并未发现此类操作。数据缓存通常在board初始化阶段进行配置。其中以smdk2410位为例,boardsmdk2410lowlevel_init.S_TEXT_BASE: .word TEXT_BASE .globl lowlevel_init lowlevel_init:内存控制器配置部分已经成功修改
生成无此提示信息的PDF文件需要购买 novaPDF 打印机(http:www.novapdf.com)
U-BOOT源码分析及移植
本文主要从以下几方面进行u-Booth的概述与移植工作:
1、其整体架构设计特点
2、其运行流程、核心数据类型及其内存占用情况。
3、对其关键功能模块进行解析与实现路径探讨。
4、将其移植至FS2410开发板,实现在其上配置Nor型闪存、Nand型闪存以及相关的网络功能。
这些认识源自作者在进行U-BOOT移植项目的过程中所查阅的相关文档与对开源代码的初步调研。
对于ARM平台而言,u-boot工程的核心目录结构如下:
1. 源代码组织
- 核心目录下分为硬件描述语言(HDL)文件以及与不同板子相关联的电路设计信息。
- 具体实现中通常会根据不同的硬件需求动态调整配置参数。
CPU 平台依赖 存储与 CPU 相关的目录文件,每个特定型号的 CPU 配备一个目录结构,例如 arm920t、xscale 和 i386 等目录。
lib_arm 平台依赖 存储与 ARM 体系结构通用的文件,主要用于实现 ARM 平台通用功能,如软件浮点运算。
该资源提供一组通用功能函数实现工具包,涵盖环境管理、命令执行和控制台交互等功能。
该资源包含一系列头文件和开发板配置文件,所有开发板相关的配置信息均存储于configs目录下。
该库包含了通用的公共基础模块,为项目提供了基本的数据处理能力。
该资源集成了网络协议存储功能,其中net目录中存放了完整的网络协议栈代码。
本系统提供了一组统一的设备驱动接口集合,主要包含以太网适配器和NAND存储芯片的专用驱动程序设计。这些驱动程序实现了对不同硬件组件的统一控制与管理。
2.makefile 简要分析
该资源采用顶层makefile进行配置,所有目录的编译链接操作均由该文件统一管理。
在项目执行流程中,首先需要完成makefile相关设置,
随后按照指定顺序依次构建各个核心模块。