AR71XX_UBOOT编译入门_第1页
AR71XX_UBOOT编译入门_第2页
AR71XX_UBOOT编译入门_第3页
AR71XX_UBOOT编译入门_第4页
AR71XX_UBOOT编译入门_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2. 解压代码 这个就随便了,一般解压在主目录。 将下载的 mr3420_3220v1.tar.gz 移动到主目录。 注意:这里压缩包扩展名有误,实际上是 bzip2 压缩的。 打开终端,此时终端应该默认在主目录下,若不在主目录下,就运行 cd 命令进入主目录。 运行命令 tar -jxvf mr3420_3220v1.tar.gz 以解压代码。tar_jxvf_mr3420_3220v1.png (31.25 KB, 下载次数: 0) 3. 编译代码 运行命令 cd mr3420_3220v1/build 进入代码编译目录。 运行命令 make BOARD_TYPE=ap99 fs_prep

2、 以创建编译过程所需的目录。 运行命令 make BOARD_TYPE=ap99 uboot 以开始编译 U-Boot。 4. 刷机测试 如果没有意外,那么编译结束后的输出应该是这样的: 生成的 u-boot.bin 位于 mr3420_3220v1/images/ap99/ 目录下。 此文件未被填充到 128K,需要手动填充。 填充后的文件就可以进行刷机测试了。 此文件是未压缩版,因此本身体积很大。此代码也不能生成压缩版的 U-Boot。 5. 说明 操作说明请参阅代码根目录下的 readme.txt。入门级的操作就这么简单。进阶级: 进阶级依然使用 TL-MR3420 v1 的代码。 进阶

3、级将分离 U-Boot 代码及现成的工具链,搭建基本的交叉编译环境。 1. 分离 U-Boot 代码 U-Boot 代码位于 mr3420_3220v1/ap99/boot/u-boot 。 将整个 u-boot 目录复制到一个地方,如用户主目录。 此 u-boot 目录里的代码就是全部所需的代码了。之后的所有操作都在这里面完成。2. 复制工具链 此工具链即为编译器,但是是针对 mips 架构的交叉编译器。 工具链位于 mr3420_3220v1/build/gcc-3.4.4-2.16.1/build_mips。 将整个 build_mips 复制到一个地方,如主目录。 3. 搭建编译环境

4、现在,mr3420_3220v1 目录已经没有用,可以删掉,因为所有需要的文件都已复制出来了。 设置环境变量以让 Shell 能够访问到工具链。运行命令 export PATH=$PATH:/build_mips/bin 即可。 此设置只在当前的 Shell 里有效。关于如何设置永久的环境变量,请自行百度。 4. 清理代码 此操作用于清理上次编译产生的临时文件及配置文件,为下次配置及编译做准备。 进入 u-boot 目录:运行命令 cd /u-boot 。 运行命令 make distclean 以执行完全清理。 5. 编译代码 这里是一个完整的编译步骤。 a. 指定开发板类型 此操作表示我们

5、要编译哪个开发板。AR7241 的开发板(这里其实叫参考板,reference board)名称为 ap99,因此运行 make ap99_config 以进行配置。 所有的开发板定义都写在 Makefile 里。其中以 *_config: 开头的行,* 就是开发板名称。 AR 及 QCA 系列的参考板名称会在最后列出。 有些开发板还有额外的参数可以定义,这里暂不讲解。b. 编译 运行命令 make CROSS_COMPILE=mips-linux- 进行编译。 CROSS_COMPILE=mips-linux- 指定了交叉编译器的文件名前缀为 mips-linux-。例如,要使用工具链中的

6、gcc 程序,那么就运行 mips-linux-gcc。这个可以看一下 build_mips/bin 目录下的文件名。 由于之前运行了 export PATH=$PATH:/build_mips/bin 命令,所以 Shell 能够直接找到相关程序的位置。否则,CROSS_COMPILE= 需要指定为 /build_mips/bin/mips-linux-。 c. 测试 编译成功后,u-boot 目录下会生成 u-boot.bin,这就是未填充到 128K 的文件。 6. 常用编译命令。 make *_config 配置生成为指定的开发板(* 为开发板名称)。 make CROSS_COMPI

7、LE=* 编译代码,并指定交叉编译器文件名前缀为 *。 make clean 清理上次编译生成的临时文件。此命令不会删除开发板配置,下次编译可以直接运行 make 命令。 make distclean 清理编译生成的临时文件及开发板配置。运行此命令后,需要再次指定开发板后才能进行编译。其它说明: 这里使用的 MR3420 v1 代码不能生成压缩代码。其他的,如 AR9331 AR934x 等代码需要在编译时加入 COMPRESSED_UBOOT=1 来进行编译,如 make CROSS_COMPILE=mips-linux- COMPRESSED_UBOOT=1 。 编译 AR934x QCA

8、95xx 的代码需要指定使用的以太网交换机 PHY 类型,即在编译时加入 ETH_CONFIG=_s27 或 ETH_CONFIG=_s17 。其中 _s27 为内置百兆 PHY,_s17 为外部千兆 PHY。 具体路由型号的 GPL 代码里都有说明文件,可以根据说明文件来进行编译,并了解参考板名称。常见参考板名称: AR7240 - ap91 AR7241 - ap99 AR9331 - ap121 AR9341 - ap123 AR9342 - mi124 AR9344 - db12x QCA953x - ap143 QCA9558 - ap135 其它的请在 及 上进行查找。:UBoot

9、 启动过程及简单代码分析这里以 AR7241 的 U-Boot 为例MIPS 架构简介MIPS 地址空间:这里说的是地址空间,不是内存空间。内存只是映射在一部分地址空间上而已。内存分为4段 (Kuseg、Kseg0、Kseg1、Kseg2),其中 Kseg0 (0x80000000 0x9fffffff) 为缓存段,直接映射在物理地址段上。Kseg1 (0xa0000000 0xbfffffff) 为非缓存段,直接映射在物理地址段上。Kuseg 和 Kseg2 需要经过地址转换才能访问。在 CPU 复位时,缓存未被初始化,只有 Kseg1 能够被直接访问。AR71XX 物理段:内存、Flash

10、、IO寄存器等都被映射在物理段上范围为 00x1fffffff,访问时需要通过宏 KSEG0ADDR(_addr) 来通过 Kseg0 访问或 KSEG1ADDR(_addr) 来通过 Kseg1 访问。物理地址一般不能直接访问,都需要通过 Kseg0 或 Kseg1 来访问。主要的映射范围:DDR:00x0fffffff (这一段直接映射物理内存,一般通过带缓存的 Kseg0 来访问,以便加快速度)I/O空间:0x10000000 0x1dffffff (这一段直接控制硬件,必须通过 Kseg1 来访问)SPI Flash 空间:0x1f000000 0x1fffffff (这一段映射闪存的

11、前 16MB 数据)AR71XX 启动过程CPU 上电时,物理段中,SPI Flash 的前4MB 被循环映射在 0x1f000000 上,因此会被重复 4 次。执行地址为 KSEG1ADDR(0x1fc00000),即 0xbfc00000。*注意:U-Boot 在编译时,实际设置的基址,即启动地址为 KSEG0ADDR(0x1f000000),即 0x9f000000。下面会讲到为什么要这么设置。U-Boot 中的起始代码在 cpu/mips/start.S 中:_start:#ifndef COMPRESSED_UBOOTRVECENT(reset,0) /* U-boot entry

12、point */RVECENT(reset,1) /* software reboot */RVECENT(romReserved,2)-省略-RVECENT(romReserved,125)RVECENT(romReserved,126)RVECENT(romReserved,127)/* We hope there are no more reserved vectors!* 128 * 8 = 1024 = 0x400* so this is address R_VEC+0x400 = 0xbfc00400*/复制代码以上代码设置异常向量,不需要理解第一句 RVECENT(reset,0

13、) 为一个跳转,直接转到下面的代码进行运行.align 4reset:/* set GPIO_OE- added by lsz to fix the LED issue 09.03.25 */li a1, AR7100_GPIO_OElw v1, 0(a1)li v0, 0x3fdffor v1, v1, v0sw v1, 0(a1)lw v0, 0(a1)lw v0, 0(a1)-省略-/* CONFIG0 register */li t0, CONF_CM_UNCACHEDmtc0 t0, CP0_CONFIG复制代码以上代码前半部分通过设置 GPIO 来点亮路由的 LED。后半部分设置

14、CPU 相关参数,不需要理解以上代码没有包含使用相对地址的指令,也就是说,无论这段代码在 CPU 地址空间的何种位置,都能够正常执行因此虽然 CPU 的执行地址为 0xbfc00000,以上代码依然能执行/* Initialize GOT pointer.*/bal 1fnop.word _GLOBAL_OFFSET_TABLE_1:move gp, ralw t1, 0(ra)move gp, t1复制代码以上代码加载了用于 U-Boot 重定位的 GOT 指针,它是 U-Boot 在内存中进行自身移动的关键la t9, lowlevel_initjalr t9nop复制代码以上代码进行 C

15、PU 频率设置,超频就是在这里实现的la t0, rel_startj t0noprel_start:复制代码以上代码很关键,它实现了 U-Boot 的执行地址的转移假设当前 CPU 的执行地址在 0xbfc00000 + x那么执行此段代码后,CPU 执行地址将跳转到 0x9f000000 + x 处进行执行前面提到了 CPU 在复位时,物理段 0x1f000000 处循环映射 4 次 Flash 的前 4MB,而 U-Boot 大小只有100KB多,因此 0x1f000000 跟 0x1fc00000 处的数据是一样的,这就实现了运行地址的转移。至于为什么不跳转到 0xbf000000 +

16、 x 处运行,是因为 AR71XX CPU 在复位时,缓存可用,因此通过 Kseg0 段执行,可以加快速度。/* REMAP_DISABLE */li a0, AR7100_SPI_CLOCKli t0, 0x43sw t0, 0(a0)复制代码以上代码的作用是禁用物理段 0x1f000000 的 4MB Flash 数据循环映射,以便让 0x1f000000 能够映射 16MB 的 Flash 数据/* Initialize caches.*/* 初始化缓存 */la t9, simple_mips_cache_resetjalr t9nop/* . and enable them.*/*

17、启用缓存 */li t0, CONF_CM_CACHABLE_NONCOHERENTmtc0 t0, CP0_CONFIG-省略-#if defined(CONFIG_AR7100) | defined(CONFIG_AR7240)/* 将缓存锁定在 Kseg0 低端处 */la t9, mips_cache_lock_24kjalr t9nop#endif#endif /* #ifndef COMPRESSED_UBOOT */* 将栈指针指向缓存 */li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSETla sp, 0(t0)/* 进入 C 环境 */la

18、t9, board_init_fj t9nop复制代码这段代码的作用是初始化缓存,并将缓存锁定在 Kseg0 上,用作临时的栈空间此时内存并未初始化, Kseg0 对应的 0x80000000 0x8fffffff 还不能被访问,因此需要用缓存代替。然后跳转到 board_init_f 进行执行下面开始在 C 环境中运行文件:lib_mips/board.cvoid board_init_f(ulong bootflag)gd_t gd_data, *id;bd_t *bd;init_fnc_t *init_fnc_ptr;ulong addr, addr_sp, len = (ulong)&

19、uboot_end - CFG_MONITOR_BASE;ulong *s;#ifdef COMPRESSED_UBOOTchar board_string50;#endif#ifdef CONFIG_PURPLEvoid copy_code (ulong);#endif/* Pointer is writable since we allocated a register for it.*/gd = &gd_data;/* compiler optimization barrier needed for GCC = 3.4 */_asm_ _volatile_(: : :memory);me

20、mset (void *)gd, 0, sizeof (gd_t);/* 依次运行初始化函数 */for (init_fnc_ptr = init_sequence; *init_fnc_ptr; +init_fnc_ptr) if (*init_fnc_ptr)() != 0) hang ();#ifdef COMPRESSED_UBOOTcheckboard(board_string);printf(%snn,board_string);gd-ram_size = bootflag;puts (DRAM:);print_size (gd-ram_size, n);#endif/* Now

21、that we have DRAM mapped and working, we can* relocate the code and continue running from DRAM.*/addr = CFG_SDRAM_BASE + gd-ram_size;/* We can reserve some RAM on top here.*/* round down to next 4 kB limit.*/addr &= (4096 - 1);debug (Top of RAM usable for U-Boot at: %08lxn, addr);-省略-/* Save local v

22、ariables to board info struct*/* 记录内存基址及大小、串口波特率 */bd-bi_memstart = CFG_SDRAM_BASE; /* start ofDRAM memory */bd-bi_memsize = gd-ram_size; /* sizeofDRAM memory in bytes */bd-bi_baudrate = gd-baudrate; /* Console Baudrate */memcpy (id, (void *)gd, sizeof (gd_t);/* On the purple board we copy the code

23、in a special way* in order to solve flash problems*/#ifdef CONFIG_PURPLEcopy_code(addr);#endif/* 执行代码转移 */relocate_code (addr_sp, id, addr);/* NOTREACHED - relocate_code() does not return */复制代码board_init_f 的作用为进行内存、时钟、串口等设备的初始化,并为 U-Boot 的运行划分内存。初始化函数位于 board_init_f 函数上方init_fnc_t *init_sequence =

24、#ifndef COMPRESSED_UBOOTtimer_init, /* 初始化时钟 */#endifenv_init, /* initialize environment */ /* 初始化环境变量 */#ifdef CONFIG_INCA_IPincaip_set_cpuclk, /* set cpu clock according to environment variable */#endifinit_baudrate, /* initialze baudrate settings */#ifndef COMPRESSED_UBOOTserial_init, /* serial c

25、ommunications setup */ /* 初始化串口,这样 TTL 才有输出 */#endifconsole_init_f, /* 初始化控制台环境 */display_banner, /* say that we are here */ /* 显示 U-Boot 1.1.4 . */#ifndef COMPRESSED_UBOOTcheckboard, /* 显示 AP99 (ar7241 - Virian) U-boot */init_func_ram, /* 初始化内存 */#endifNULL,;复制代码以上为初始化函数列表,依次运行在初始化完成后,board_init_f

26、调用 relocate_code 将 U-Boot 代码从 Flash 中复制到内存中,再从内存中执行回到 cpu/mips/start.S.globl relocate_code.ent relocate_coderelocate_code:move sp, a0 /* Set new stack pointer */li t0, CFG_MONITOR_BASEla t3, in_ramlw t2, -12(t3) /* t2 - uboot_end_data */move t1, a2/* Fix GOT pointer:* New GOT-PTR = (old GOT-PTR - CF

27、G_MONITOR_BASE) + Destination Address*/* 根据传递的参数计算移动距离 */move t6, gpsub gp, CFG_MONITOR_BASEadd gp, a2 /* gp now adjusted */sub t6, gp, t6 /* t6 - relocation offset */* t0 = source address* t1 = target address* t2 = source end address*/* 复制代码到内存 */1:lw t3, 0(t0)sw t3, 0(t1)addu t0, 4ble t0, t2, 1bad

28、du t1, 4 /* delay slot */* If caches were enabled, we would have to flush them here.*/* Jump to where weve relocated ourselves.*/* 跳转到移动后的代码继续执行 */addi t0, a2, in_ram - _startj t0nop.word uboot_end_data.word uboot_end.word num_got_entriesin_ram:/* 此时已经在内存中了 */* Now we want to update GOT.*/lw t3, -4(

29、t0) /* t3 - num_got_entries */addi t4, gp, 8 /* Skipping first two entries. */li t2, 2/* GOT 表重定位 */1:lw t1, 0(t4)beqz t1, 2fadd t1, t6sw t1, 0(t4)2:addi t2, 1blt t2, t3, 1baddi t4, 4 /* delay slot */* Clear BSS.*/lw t1, -12(t0) /* t1 - uboot_end_data */lw t2, -8(t0) /* t2 flags |= GD_FLG_RELOC; /*

30、tell others: relocation done */debug (Now running in RAM - U-Boot at: %08lxn, dest_addr);gd-reloc_off = dest_addr - CFG_MONITOR_BASE;/* 记录 U-Boot 重定位时移动的偏移量 */monitor_flash_len = (ulong)&uboot_end_data - dest_addr;/* We have to relocate the command table manually*/* U-Boot 命令表,重定位所有字符串地址和函数地址 */for

31、(cmdtp = &_u_boot_cmd_start; cmdtp !=&_u_boot_cmd_end; cmdtp+) ulong addr;addr = (ulong) (cmdtp-cmd) + gd-reloc_off;#if 0printf (Command %s: 0x%08lx = 0x%08lxn,cmdtp-name, (ulong) (cmdtp-cmd), addr);#endifcmdtp-cmd =(int (*)(struct cmd_tbl_s *, int, int, char *)addr;addr = (ulong)(cmdtp-name) + gd-r

32、eloc_off;cmdtp-name = (char *)addr;if (cmdtp-usage) addr = (ulong)(cmdtp-usage) + gd-reloc_off;cmdtp-usage = (char *)addr;#ifdef CFG_LONGHELPif (cmdtp-help) addr = (ulong)(cmdtp-help) + gd-reloc_off;cmdtp-help = (char *)addr;#endif/* there are some other pointer constants we must deal with */#ifndef

33、 CFG_ENV_IS_NOWHEREenv_name_spec += gd-reloc_off;#endif/* 熄灭路由的 LED */* turn off switch LED added by tiger 20091225 */ar7240_gpio_sw_led();-省略-/* configure available FLASH banks */* 初始化 Flash,显示 Flash:XXXX (X MB) */size = flash_init();display_flash_config (size);bd = gd-bd;bd-bi_flashstart = CFG_FLA

34、SH_BASE;bd-bi_flashsize = size;#if CFG_MONITOR_BASE = CFG_FLASH_BASEbd-bi_flashoffset = monitor_flash_len; /* reserved area for U-Boot */#elsebd-bi_flashoffset = 0;#endif/* initialize malloc() area */* 初始化内存管理器,以便能够使用 malloc 等函数 */mem_malloc_init();malloc_bin_reloc();/* relocate environment function

35、 pointers etc. */* 重定位环境变量相关函数和数据 */env_relocate();/* board MAC address */s = getenv (ethaddr);for (i = 0; i bi_enetaddri = s ? simple_strtoul (s, &e, 16) : 0;if (s)s = (*e) ? e + 1 : e;/* IP Address */bd-bi_ip_addr = getenv_IPaddr(ipaddr);#if defined(CONFIG_PCI)/* Do pci configuration*/* PCI 设备初始化

36、*/pci_init();#endif/* leave this here (after malloc(), environment and PCI are working) */* Initialize devices */devices_init ();jumptable_init ();/* Initialize the console (after the relocation and devices init) */console_init_r ();/* * * * * * * * * * * * * * * * * * * * * */* Initialize from envi

37、ronment */if (s = getenv (loadaddr) != NULL) load_addr = simple_strtoul (s, NULL, 16);#if (CONFIG_COMMANDS & CFG_CMD_NET)if (s = getenv (bootfile) != NULL) copy_filename (BootFile, s, sizeof (BootFile);#endif /* CFG_CMD_NET */#if defined(CONFIG_MISC_INIT_R)/* miscellaneous platform dependent initial

38、isations */misc_init_r ();#endif#if (CONFIG_COMMANDS & CFG_CMD_NET)/* 初始化网络 */#if defined(CONFIG_NET_MULTI)puts (Net: );#endifeth_initialize(gd-bd);#endif/* main_loop() can return to retry autoboot, if so just run it again. */* 进入命令主循环,永不返回 */for (;) main_loop ();/* NOTREACHED - no way out of comman

39、d loop except booting */复制代码到此为止 U-Boot 就开始正常运行了在处理交互命令前,U-Boot 会检查有没有启动命令文件:common/main.cvoid main_loop (void)-省略-#if defined(CONFIG_BOOTDELAY) & (CONFIG_BOOTDELAY = 0)char *s;int bootdelay;#endif-省略-#if defined(CONFIG_BOOTDELAY) & (CONFIG_BOOTDELAY = 0)/* 获取启动延时 */s = getenv (bootdelay);bootdelay

40、= s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;/ debug (# main_loop entered: bootdelay=%dnn, bootdelay);# ifdef CONFIG_BOOT_RETRY_TIMEinit_cmd_timeout ();# endif /* CONFIG_BOOT_RETRY_TIME */-省略-/* 获取启动命令 */s = getenv (bootcmd);if (!s) /* 如果没有启动命令,就设置默认的命令 */#ifdef CONFIG_ROOTFS_FLASH/* XXX

41、 if rootfs is in flash, expect uImage to be in flash */#ifdef CONFIG_AR7100/* 这里设置的即为 AR71XX 的默认固件启动命令 */setenv (bootcmd, bootm 0xbf200000);#elsesetenv (bootcmd, bootm 0xbf450000);#endif /* CONFIG_AR7100 */#elsesetenv (bootcmd, tftpboot 0x8022c090 uImage; bootm 0x8022c090);#endif/* 重新获取启动命令 */s = ge

42、tenv (bootcmd);/ debug (# main_loop: bootcmd=%sn, s ? s : );if (bootdelay = 0 & s & !abortboot (bootdelay) # ifdef CONFIG_AUTOBOOT_KEYEDint prev = disable_ctrlc(1); /* disable Control C checking */# endif # ifndef CFG_HUSH_PARSER/* 执行启动命令 */run_command (s, 0);# elseparse_string_outer(s, FLAG_PARSE_S

43、EMICOLON |FLAG_EXIT_FROM_LOOP);# endif# ifdef CONFIG_AUTOBOOT_KEYEDdisable_ctrlc(prev); /* restore Control C checking */# endif-省略-#endif /* CONFIG_BOOTDELAY */#ifdef CONFIG_AMIGAONEG3SEextern void video_banner(void);video_banner();#endif/* 启动命令执行完毕,则开始处理交互命令 */* Main Loop for Monitor Command Processing*/#ifdef CFG_HUSH_PARSERparse_file_outer();/* This point is never reached */for (;);#el

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论