Ⅰ uboot 放在哪里
uboot是放在nand中的第一个分区。
选择nand启动后,首先进入uboot。
nor里面很多厂商已经固化引导程序在里面,并且已经写保护,不能更改,可以通过nor启动来烧写uboot到nand中,然后选择nand启动。
nand启动后,进入uboot,setenv设置环境变量后,要执行saveenv,保存环境变量,然后通过printenv查看当前环境变量。
另外,nor里面的bootloader不一定就是uboot,比如说友善2440的就是supervivi。
Ⅱ uboot移植过程中的运行地址和装载地址的区别
哈哈 ,你是只要简单的使用uboot还是真正要去修改源码移植?不管怎样,我建议你先搞懂uboot的工作流程,就是它的启动流程,如果引导内核的。。。如果只是简单的使用uboot,可以去网上移植好的uboot,然后用jflash arm 烧到你的nandflash或者norflash。如果要移植,建议去买本书或者看看,看的话韦东山的嵌入式,他对整个uboot的工作流程分析得还是比较不错的,当然那只是帮助你理解uboot而已,真正想搞懂还是得靠你去看它的代码,我个人是觉得不会太难吧。。。。加油!
Ⅲ 如何从uboot读取mac,然户传递到内核中
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函数。
Ⅳ uboot是什么,在linux中干嘛用的
u-boot是一种普遍用于嵌入式系统中的Bootloader,Bootloader是在操作系统运行之前执行的一小段程序,通过它,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的软硬件环境,为最终调用操作系统内核做好准备。Boot Loader的主要运行任务就是将内核映象从硬盘上读到RAM中,然后跳转到内核的入口点去运行,即开始启动操作系统。系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的Boot Loader程序。
Ⅳ 如何设置u-boot变量ip地址
setenv ipaddr 192.168.1.111
这样就可以了。然后在使用网络相关的时候,会自动获取这个ip并使用的。
如果用tftp 还需设置
setenv serverip 192.168.1.123
需要重启还有效,则
saveenv
Ⅵ uboot运行的时候操作的是虚拟地址还是物理地址
uboot运行的时候操作的是虚拟地址还是物理地址
C源程序的结构特点
1.一个C语言源程序可以由一个或多个源文件组成。
2.每个源文件可由一个或多个函数组成。
3.一个源程序不论由多少个文件组成,都有一个且只能有一个main函数,即主函数。
4.源程序中可以有预处理命令(include 命令仅为其中的一种),预处理命令通常应放在源文件或源程序的最前面。
5.每一个说明,每一个语句都必须以分号结尾。但预处理命令,函数头和花括号“}”之后不能加分号。
6.标识符,关键字之间必须至少加一个空格以示间隔。若已有明显的间隔符,也可不再加空格来间隔。
Ⅶ linux uboot 怎样读gpio
在u-boot中操作某个寄存器:
[cpp] view plain
print?
reg = readl(IOMUXC_BASE_ADDR + IOMUXC_REG_GPR1);
reg &= ~IOMUXC_REG_GPR1_ACTCS0_MASK;
writel(reg, IOMUXC_BASE_ADDR + IOMUXC_REG_GPR1);
其中IOMUXC_BASE_ADDR是物理地址,跟踪代码发现writel操作如下:
#define writel(v,a) __arch_putl(v,a)
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
所以在uboot里面配置寄存相当于是给物理地址直接赋值,volatile的意思是提醒编译器需要存储或读取这个变量的时候,都会直接从变量地址中读取数据
而在内核中,上面的写法是无法运行的,会提示虚拟地址错误。在内核中通常是通过虚拟地址来给物理地址赋值,所以需要将物理地址转换成虚拟地址
[cpp] view plain
print?
reg = __raw_readl(ioremap(IOMUXC_BASE_ADDR + IOMUXC_REG_GPR1,4));
reg &= ~IOMUXC_REG_GPR1_ACTCS0_MASK;
reg &= ~IOMUXC_REG_GPR1_ADDRS0_MASK;
reg |= ((CS0_NORFLASH_SIZE | IOMUXC_REG_GPR1_ACTCS0));
__raw_writel(reg, ioremap(IOMUXC_BASE_ADDR + IOMUXC_REG_GPR1,4));
这里的ioremap是将物理地址IOMUXC_BASE_ADDR转换得到对应的虚拟地址,4表示4个字节,即32位的地址。
u-boot下读写gpio:
与读写寄存器类似,u-boot下读写GPIO口是直接给GPIO赋值:
Ⅷ uboot是什么
U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目。U-Boot的作用是系统引导。U-Boot从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是根据相应的Linux内核源程序进行简化而形成的,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。
拓展资料:
选择U-Boot的理由:
① 开放源码;
② 支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS, android;
③ 支持多个处理器系列,如PowerPC、ARM、x86、MIPS;
④ 较高的可靠性和稳定性;
⑤ 高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等;
⑥ 丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等;
⑦ 较为丰富的开发调试文档与强大的网络技术支持。
Ⅸ uboot下mac地址怎么修改
3.jpg 编程器备份原始固件,刷小米mini的不死breed,然后进入breed刷回原厂编程器固件,最后进入breed改mac
Ⅹ 如何在uboot中添加ping命令
首先icmp和arp是没有关系的!icmp承载于网络层他的协议号好像是1,其中有8种类型比如host不可达、超时等这是用来测试网络连通性的一种控制信息协议。ARP是以太网技术中最重要的一种协议地址解析协议,它承载于osi第二层类型号好像是806,因为以太网是多路访问的一种,所以为了解析其以太网物理MAC地址必须要用ARP协议,这种协议发送的request包中目标MAC地址为全1广播地址,reply包以自己的mac和IP地址为源,目标地址以目标主机MAC和IP地址为目标封装成帧后发送出去!虽然说它是链路层协议,但是他有网络层的概念IP地址,我抓包看到过ARP协议中有协议类型800这是IP协议的类型,因为他要用IP地址来解析MAC地址,所以每个网络层以上的设备都会有基于ARP的缓存,路由交换设备中的命令是showarp!windows中的命令是arp-a,有了这种缓存大大提高了互联网访问速度!好了说了这么多可能楼主认为我说的是废话!那么我就开始所问所答了!第一,ping命令是ICMP的一种形式,它属于ICMP,当然tracert也属于ICMP!ICMP与ARP没有任何关系,一个是网络层协议,一个是数据链路层协议!在功能方面上也没有什么交集的地方,唯一共同点就是都涉及IP地址。第二,我不会写什么UBOOT代码,但是既然承载在internet上那么他就应该遵循网络体系结构为了让网络统一化,IEEE和国际标准化组织iso统一定义了接入层及上层协议标准!当你ping时会发送ARP帧是因为你在以太网的环境中,为什么会发送ARP是因为在计算机刚刚启动的时候是没有对方主机的通信地址的!ping是为了测试与对方主机的连通性,所以需要知道对方主机的地址虽然你知道了目的的IP地址,但还需要其MAC地址,所以在ping之前就会发送ARP帧,主机中ARP默认缓存老化时间应该是10分钟。也就是说,自ARP解析10分钟后ARP缓存条目会自动清除。第三,arp帧发送和恢复确实不一样!一个用广播一个是单播好了!不管我写的是不是废话!辛辛苦苦写了这些不容易啊!接下来就看LZ你的了!^_^!