U-Boot 除了 Bootloader 的系统引导功能,它还有用户命令接口,具备多种引导内核启动的方式。常用的 go 和 bootm 命令可以直接引导 Linux 内核映像启动。
U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是根据相应的Linux内核源程序进行简化而形成的,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
⑵ 怎样弄uboot编译交叉编译工具,我的xp和ubuntu间有个共享文件夹,我把交叉工具放在那里,怎样把它安装
1:先把交叉编译环境包放到你的共享目录,(我这里的版本是:arm-linux-gcc-4.4.3.tar.gz)
2:进行解压 tar zxvf arm-linux-gcc-4.4.3.tar.gz -C (要解压的路径)
比如:tar zxvf arm-linux-gcc-4.4.3.tar.gz -C ~/ (root 用户的工作目录)
3:然后设置环境变量:export PATH=$PATH:~/opt/FriendlyARM/toolschain/4.4.3/bin
4:要想系统启动自动加载环境变量:
1:普通用户:vim .profile 在最后添加你的环境变量:export PATH=$PATH:~/opt/FriendlyARM/toolschain/4.4.3/bin
2:root用户:vim .bashrc 在最后添加你的环境变量:export PATH=$PATH:~/opt/FriendlyARM/toolschain/4.4.3/bin
自此,交叉环境彻底搭建完毕。
注意:我的交叉编译包,解压出来的路径就是:opt/FriendlyARM/toolschain/4.4.3/bin
你的版本,可能有些不同
⑶ linux编译u-boot时显示[arch/arm/dts/zynq-zc702.dtb]错误
在编译uboot的时候,会出现出错,因此我们要首先做 make disclean. 将原来的一些中间文件清理干净。
因此在编译Uboot依次执行 1.make disclean
2.make smdk2440_config
3. make
就可以编译通过了
⑷ 如何在自己的uboot中实现命令
你这个问题专业性太强了,还好你遇到了我,我11年的时候参加过一个嵌入式的培训,当初我们是做一个数码相框的项目,就是要把已经编写好的程序移植到ARM2440板上面运行。整个过程非常的繁琐复杂,我真的无法口述清楚。你想把linux中的命令移植到uboot代码中,应该也是想在你的ARM上面编译你的程序然后运行,你可以进我的CSDN的博客,博客地址:http://blog.csdn.net/coolboyli520,然后打开那个《Linux移植课实验指导书》,这里有详细的记录,如果对你有帮助,还望采纳!
⑸ 从庖丁解牛说uboot如何编译
其实,这个世界上的万事万物,都有一个“纹理”。我读中学的时候劈柴,如果顺着木头的纹理劈下去很轻易的就劈开了,但如果反其道而行之不但劈不开而且斧头还会弹回来伤人!呵呵,城里出生的孩子是没这个体会,即使现在农村的孩子因为家里都烧液化气也没有这个机会体验了。 庖丁解牛之所以游刃有余,是因为他掌握了牛的纹理,顺着这些纹理就应该很容易。 那么我们的uboot的纹理在哪里呢? 很多初学者,拿到这种代码从来没有去看过它的readme或者document!这两个文本文件是非常重要的东西,可惜呀!很多人不去看readme而去请教别人,google,,跑图书馆。其实,有些东西当你问到别人的时候,聪明的人也是去看readme然后给你解答的。 下面我们就去找uboot的纹理! 本文u-boot版本U-Boot 1.1.4 我们按正常人的思维(智商90)来分析。 首先,是要编译,那么编译就要执行命令make,而make实际上就是执行makefile文件。第一次make肯定是不能成功的。听从观音菩萨的教诲“从哪里来就到哪里去”!make 出问题,我们就去makefile里找原因。Makefile里有这样一段话: TOPDIR := $(shell if [“$$PWD” != “”]; then echo $$PWD; else pwd; fi) export TOPDIR ifeq (include/config.mk,$(wildcard include/config.mk)) # load ARCH, BOARD, and CPU configuration include include/config.mk export ARCH CPU BOARD VENDOR SOC # load other configuration include $(TOPDIR)/config.mk ifndef CROSS_COMPILE ifeq ($(HOSTARCH),ppc) CROSS_COMPILE = else ifeq ($(ARCH),ppc) CROSS_COMPILE = powerpc-linux- endif ifeq ($(ARCH),arm) CROSS_COMPILE = /usr/local/arm/2.95.3/bin/arm-linux- endif ifeq ($(ARCH),i386) ifeq ($(HOSTARCH),i386) CROSS_COMPILE = else CROSS_COMPILE = i386-linux- endif endif ifeq ($(ARCH),mips) CROSS_COMPILE = mips_4KC- endif ifeq ($(ARCH),nios) CROSS_COMPILE = nios-elf- endif ifeq ($(ARCH),nios2) CROSS_COMPILE = nios2-elf- endif ifeq ($(ARCH),m68k) CROSS_COMPILE = m68k-elf- endif ifeq ($(ARCH),microblaze) CROSS_COMPILE = mb- endif endif endif export CROSS_COMPILE 这段脚本就是设置交叉编译路径CROSS_COMPILE,在设置这个路径前要判断我们所用的平台是什么,即ARCH是什么。我们这里以ARM为例。1 2
⑹ 如何实现uboot和linux之间的参数传递
U-boot会给Linux Kernel传递很多参数,如:串口,RAM,videofb等。而Linux kernel也会读取和处理这些参数。两者之间通过struct tag来传递参数。U-boot把要传递给kernel的东西保存在struct tag数据结构中,启动kernel时,把这个结构体的物理地址传给kernel;Linux kernel通过这个地址,用parse_tags分析出传递过来的参数。
本文主要以U-boot传递RAM和Linux kernel读取RAM参数为例进行说明。
1、u-boot给kernel传RAM参数
./common/cmd_bootm.c文件中(指Uboot的根目录),bootm命令对应的do_bootm函数,当分析uImage中信息发现OS是Linux时,调用./lib_arm/bootm.c文件中的do_bootm_linux函数来启动Linux kernel。
在do_bootm_linux函数中:
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],\
ulong addr, ulong *len_ptr, int verify)
{
......
#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
defined (CONFIG_CMDLINE_TAG) || \
defined (CONFIG_INITRD_TAG) || \
defined (CONFIG_SERIAL_TAG) || \
defined (CONFIG_REVISION_TAG) || \
defined (CONFIG_LCD) || \
defined (CONFIG_VFD)
setup_start_tag (bd); //初始化tag结构体开始
#ifdef CONFIG_SERIAL_TAG
setup_serial_tag (¶ms);
#endif
#ifdef CONFIG_REVISION_TAG
setup_revision_tag (¶ms);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
setup_memory_tags (bd); //设置RAM参数
#endif
#ifdef CONFIG_CMDLINE_TAG
setup_commandline_tag (bd, commandline);
#endif
#ifdef CONFIG_INITRD_TAG
if (initrd_start && initrd_end)
setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
setup_videolfb_tag ((gd_t *) gd);
#endif
setup_end_tag (bd); //初始化tag结构体结束
#endif
......
......
theKernel (0, machid, bd->bi_boot_params);
//传给Kernel的参数= (struct tag *)型的bd->bi_boot_params
//bd->bi_boot_params在board_init 函数中初始化,如对于at91rm9200,初始化在at91rm9200dk.c的board_init中进 行:bd->bi_boot_params=PHYS_SDRAM + 0x100;
//这个地址也是所有taglist的首地址,见下面的setup_start_tag函数
}
对于setup_start_tag和setup_memory_tags函数说明如下。
函数setup_start_tag也在此文件中定义,如下:
static void setup_start_tag (bd_t *bd)
{
params = (struct tag *) bd->bi_boot_params;
//初始化(struct tag *)型的全局变量params为bd->bi_boot_params的地址,之后的setup tags相关函数如下面的setup_memory_tags就把其它tag的数据放在此地址的偏移地址上。
params->hdr.tag = ATAG_CORE;
params->hdr.size = tag_size (tag_core);
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = tag_next (params);
}
RAM相关参数在bootm.c中的函数setup_memory_tags中初始化:
static void setup_memory_tags (bd_t *bd)
{
int i;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
params->hdr.tag = ATAG_MEM;
params->hdr.size = tag_size (tag_mem32);
params->u.mem.start = bd->bi_dram[i].start;
params->u.mem.size = bd->bi_dram[i].size;
params = tag_next (params);
} //初始化内存相关tag
}
2、Kernel读取U-boot传递的相关参数
对于Linux Kernel,ARM平台启动时,先执行arch/arm/kernel/head.S,此文件会调用arch/arm/kernel/head- common.S和arch/arm/mm/proc-arm920.S中的函数,并最后调用start_kernel:
......
b start_kernel
......
init/main.c中的start_kernel函数中会调用setup_arch函数来处理各种平台相关的动作,包括了u-boot传递过来参数的分析和保存:
start_kernel()
{
......
setup_arch(&command_line);
......
}
其中,setup_arch函数在arch/arm/kernel/setup.c文件中实现,如下:
void __init setup_arch(char **cmdline_p)
{
struct tag *tags = (struct tag *)&init_tags;
struct machine_desc *mdesc;
char *from = default_command_line;
setup_processor();
mdesc = setup_machine(machine_arch_type);
machine_name = mdesc->name;
if (mdesc->soft_reboot)
reboot_setup("s");
if (__atags_pointer)
//指向各种tag起始位置的指针,定义如下:
//unsigned int __atags_pointer __initdata;
//此指针指向__initdata段,各种tag的信息保存在这个段中。
tags = phys_to_virt(__atags_pointer);
else if (mdesc->boot_params)
tags = phys_to_virt(mdesc->boot_params);
if (tags->hdr.tag != ATAG_CORE)
convert_to_tag_list(tags);
if (tags->hdr.tag != ATAG_CORE)
tags = (struct tag *)&init_tags;
if (mdesc->fixup)
mdesc->fixup(mdesc, tags, &from, &meminfo);
if (tags->hdr.tag == ATAG_CORE) {
if (meminfo.nr_banks != 0)
squash_mem_tags(tags);
save_atags(tags);
parse_tags(tags);
//处理各种tags,其中包括了RAM参数的处理。
//这个函数处理如下tags:
__tagtable(ATAG_MEM, parse_tag_mem32);
__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
__tagtable(ATAG_SERIAL, parse_tag_serialnr);
__tagtable(ATAG_REVISION, parse_tag_revision);
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
}
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(cmdline_p, from); //处理编译内核时指定的cmdline或u-boot传递的cmdline
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_SMP
smp_init_cpus();
#endif
cpu_init();
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &mmy_con;
#endif
#endif
early_trap_init();
}
对于处理RAM的tag,调用了parse_tag_mem32函数:
static int __init parse_tag_mem32(const struct tag *tag)
{
......
arm_add_memory(tag->u.mem.start, tag->u.mem.size);
......
}
__tagtable(ATAG_MEM, parse_tag_mem32);
上述的arm_add_memory函数定义如下:
static void __init arm_add_memory(unsigned long start, unsigned long size)
{
struct membank *bank;
size -= start & ~PAGE_MASK;
bank = &meminfo.bank[meminfo.nr_banks++];
bank->start = PAGE_ALIGN(start);
bank->size = size & PAGE_MASK;
bank->node = PHYS_TO_NID(start);
}
如上可见,parse_tag_mem32函数调用arm_add_memory函数把RAM的start和size等参数保存到了meminfo结构的meminfo结构体中。最后,在setup_arch中执行下面语句:
paging_init(&meminfo, mdesc);
对没有MMU的平台上调用arch/arm/mm/nommu.c中的paging_init,否则调用arch/arm/mm/mmu.c中的paging_init函数。这里暂不分析mmu.c中的paging_init函数。
3、关于U-boot中的bd和gd
U-boot中有一个用来保存很多有用信息的全局结构体 --gd_t(global data缩写),其中包括了bd变量,可以说gd_t结构体包括了u-boot中所有重要全局变量。最后传递给内核的参数,都是从gd和bd中来的,如上 述的setup_memory_tags函数的作用就是用bd中的值来初始化RAM相应的tag。
对于ARM平台这个结构体的定义大致如下:
include/asm-arm/global_data.h
typedef struct global_data {
bd_t *bd;
unsigned long flags;
unsigned long baudrate;
unsigned long have_console; /* serial_init() was called */
unsigned long reloc_off; /* Relocation Offset */
unsigned long env_addr; /* Address of Environment struct */
unsigned long env_valid; /* Checksum of Environment valid? */
unsigned long fb_base; /* base address of frame buffer */
void **jt; /* jump table */
} gd_t;
在U-boot中使用gd结构之前要用先用宏DECLARE_GLOBAL_DATA_PTR来声明。这个宏的定义如下:
include/asm-arm/global_data.h
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
从这个宏的定义可以看出,gd是一个保存在ARM的r8寄存器中的gd_t结构体的指针。
说明:本文的版本为U-boot-1.3.4、Linux-2.6.28,平台是ARM。
⑺ Linux 3.10.17下的单独编译u-boot的配置命令是什么
如果你是要编译u-boot,uImage和文件系统的话建议你使用yocto命令来编译。如果是仅仅编译u-boot或者uImage的话,你可以使用命令单独编译,编译的话和以前release的BSP中文档中的方法是一样的。
⑻ 如何编译u-boot-xlnx-xilinx-v2017.1.tar
$(EBI_UBOOT_DIR)是你uboot解压后的目录
$(EBI_IMAGE_DIR)是你编译后放置u-boot.elf的目录
⑼ linux下jlink烧写uboot求助
Jlink for Linux之烧写
为什么会这样做,是因为我每次编译好u-boot后都要到Windows下进行烧写,用的是j-flash(j-link家庭一款软件)。我不知道它是出现的很晚还是怎么回事,看很多人还在用“j-link command工具”,这个东西我没有用过,不过看博客讲述的烧写过程极其复杂。j-flash三下五除2就搞定了。到目前应该不会去认识它了。就好比高中时没有电脑的时候Windows Vista很火,但是到大学能用上电脑的时候又都是Win7了。
在Jlink for Linux之烧写要做的话就按照这篇文章《J-LINK烧写NOR FLASH NAND FLASH》来做,在没有J-flash之前,这个应该算是很牛的了,但是在j-flash出来之后才接触j-link的对上边那篇文章就显得很无力了。
不过话说过来,为什么直接用Win7的人去了解Windows Vista呢?有一定的原因的。我是想在Linux也能烧u-boot.bin。但是下载的j-link工具中没有j-flash那种工具。只有命令行的(这也说明linux应用老滞后win)。然后我就碰到了《J-LINK烧写NOR FLASH NAND FLASH》,先是觉得神奇,又觉得好笑,最好又觉得神奇了。关于在linux的用jlink来烧写到nor flash就不深入研究了,这里我在寻找Linux gdb调试u-boot的路上的一个意外收获!目前的jlink for Linux版本的GDB提供的还是比较全的。
⑽ 如何在linux下用openjtag 烧写uboot到MINI6410上(arm板子已是板砖,所以不用说uboot烧写uboot的方法)
首先要有 CPU 和 内存的初始化代码。
可以从Uboot中提取出来,编译成bin下载到内存运行,也可以通过OpenJtag的脚本操作CPU 寄存器完成初始化。
内存初始化完成后,直接用OpenJtag将完整的Uboot下载到连接时指定的地址运行即可。
Uboot可以运行了,后面的就不成问题了。
另外用SD卡,也能很方便的解决问题。