基于jz2440的uboot分析.docx

上传人:b****6 文档编号:4542615 上传时间:2022-12-06 格式:DOCX 页数:10 大小:194.36KB
下载 相关 举报
基于jz2440的uboot分析.docx_第1页
第1页 / 共10页
基于jz2440的uboot分析.docx_第2页
第2页 / 共10页
基于jz2440的uboot分析.docx_第3页
第3页 / 共10页
基于jz2440的uboot分析.docx_第4页
第4页 / 共10页
基于jz2440的uboot分析.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

基于jz2440的uboot分析.docx

《基于jz2440的uboot分析.docx》由会员分享,可在线阅读,更多相关《基于jz2440的uboot分析.docx(10页珍藏版)》请在冰豆网上搜索。

基于jz2440的uboot分析.docx

基于jz2440的uboot分析

一、一般步骤:

1、拷贝u-boot源文件至目标目录,解压,得到源代码树

2、配置u-boot,执行命令make100ask24x0_config

3、执行make生成可执行的二进制文件u-boot.bin

4、Tftp0x30000000u-boot.bin或者NFS模式

5、Go0x30000000,或者烧写到nandflash中

2、配置过程:

make100ask24x0_config

查找顶层Makefile的100ask24x0_config目标:

100ask24x0_config:

unconfig

@$(MKCONFIG)$(@:

_config=)armarm920t100ask24x0NULLs3c24x0

MKCONFIG:

MKCONFIG:

=$(SRCTREE)/mkconfig

$(@:

_config=)

将目标字符串的_config替代为空格,即$(@:

_config=)为100ask24x0

则上面的一句话变成:

$(@:

_config=)

100ask24x0_config:

unconfig

mkconfig100ask24x0armarm920t100ask24x0NULLs3c24x0

查找源根目录下的文件mkconfig,执行完上述命令后得到:

A、BOARD_NAME=100ask24x0

打印这句话“Configuringfor100ask24x0board..”

B、.创建三个链接:

cd./include

ln-sasm-$2asm,即ln-sasm-armasm,在include目录下创建一个链接asm-arm指向asm

ln-s${LNPREFIX}arch-$6asm-$2/arch,即ln-sarch-s3c24x0asm-arm/arch

ln-s${LNPREFIX}proc-armvasm-$2/proc即ln-sproc-armvasm-arm/proc

C、配置config.mk

#

#CreateincludefileforMake

#

echo"ARCH=$2">config.mk

echo"CPU=$3">>config.mk

echo"BOARD=$4">>config.mk

即在config.mk文件中:

ARCH=arm

CPU=arm920t

BOARD=100ask24x0

SOC=s3c24x0

D、创建相关的头文件

#

#Createboardspecificheaderfile

#创建相关的头文件

#

创建config.h头文件

echo"/*Automaticallygenerated-donotedit*/">>config.h

echo"#include">>config.h

即在头文件config.h中输入;

/*Automaticallygenerated-donotedit*/

#include

”>”表示新建一个文件

三、分析make过程

1、首先指定一些常数,如版本等等,使用前面的配置文件mkconfig,得到一些参数如CPU,arch等。

include$(OBJTREE)/include/config.mk

exportARCHCPUBOARDVENDORSOC

2、指定交叉编译器exportCROSS_COMPILE

3、接着就是一系列需要编译的文件和库文件

OBJS=cpu/$(CPU)/start.o

OBJS:

=$(addprefix$(obj),$(OBJS))

LIBS=lib_generic/libgeneric.a

LIBS+=....

LIBS:

=$(addprefix$(obj),$(LIBS))//给$(LIBS)加前缀$(obj),即$(LIBS)=$(obj)$(LIBS),

 

$(obj)u-boot:

dependversion$(SUBDIRS)$(OBJS)$(LIBS)$(LDSCRIPT)

UNDEF_SYM=`$(OBJDUMP)-x$(LIBS)|sed-n-e's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\

cd$(LNDIR)&&$(LD)$(LDFLAGS)$$UNDEF_SYM$(__OBJS)\

--start-group$(__LIBS)--end-group$(PLATFORM_LIBS)\

-Mapu-boot.map-ou-boot

cd/home/linux/soft/u-boot-1.1.6&&arm-linux-ld-Bstatic-T/home/linux/soft/u-boot-1.1.6/board/100ask24x0/u-boot.lds-Ttext0x33F80000$UNDEF_SYMcpu/arm920t/start.o\

--start-grouplib_generic/libgeneric.aboard/100ask24x0/lib100ask24x0.acpu/arm920t/libarm920t.acpu/arm920t/s3c24x0/libs3c24x0.alib_arm/libarm.afs/cramfs/libcramfs.afs/fat/libfat.afs/fdos/libfdos.afs/jffs2/libjffs2.afs/reiserfs/libreiserfs.afs/ext2/libext2fs.anet/libnet.adisk/libdisk.artc/librtc.adtt/libdtt.adrivers/libdrivers.adrivers/nand/libnand.adrivers/nand_legacy/libnand_legacy.adrivers/usb/libusb.adrivers/sk98lin/libsk98lin.acommon/libcommon.a--end-group-L/home/linux/toolchain/gcc-3.4.5-glibc-2.3.6/bin/../lib/gcc/arm-linux/3.4.5-lgcc\

-Mapu-boot.map-ou-boot

从中可以看出链接文件为u-boot.lds

SECTIONS

{

.=0x00000000;//u-boot.bin文件的安放的起始位置

.=ALIGN(4);

.text:

{

cpu/arm920t/start.o(.text)

board/100ask24x0/boot_init.o(.text)

*(.text)

}

.=ALIGN(4);

.rodata:

{*(.rodata)}

.=ALIGN(4);

.data:

{*(.data)}

.=ALIGN(4);

.got:

{*(.got)}

.=.;

__u_boot_cmd_start=.;

.u_boot_cmd:

{*(.u_boot_cmd)}

__u_boot_cmd_end=.;

.=ALIGN(4);

__bss_start=.;

.bss:

{*(.bss)}

_end=.;

}

其中:

__u_boot_cmd_start=.;

.u_boot_cmd:

{*(.u_boot_cmd)}

__u_boot_cmd_end=.;

自定义的u_boot_cmd段

#defineStruct_Section__attribute__((unused,section(".u_boot_cmd")))

#defineU_BOOT_CMD(name,maxargs,rep,cmd,usage,help)\

cmd_tbl_t__u_boot_cmd_##nameStruct_Section={#name,maxargs,rep,cmd,usage,help}

 

U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)

展开即是:

cmd_tbl_t__u_boot_cmd_name

__attribute__((unused,section(".u_boot_cmd")))={name,maxargs,rep,cmd,usage,help}

即将结构体__u_boot_cmd_name按照给定参数初始化

structcmd_tbl_s{

char*name;/*CommandName*/

intmaxargs;/*maximumnumberofarguments*/

intrepeatable;/*autorepeatallowed?

*/

/*Implementationfunction*/

int(*cmd)(structcmd_tbl_s*,int,int,char*[]);

char*usage;/*Usagemessage(short)*/

#ifdefCFG_LONGHELP

char*help;/*Helpmessage(long)*/

#endif

#ifdefCONFIG_AUTO_COMPLETE

/*doautocompletiononthearguments*/

int(*complete)(intargc,char*argv[],charlast_char,intmaxv,char*cmdv[]);

#endif

};

Run_command()

将所有命令放在u-boot.cmd段中,(以结构体形式存在),run_command()运行时,根据传进来的参数,find_command()函数来查找命令,之后进行一系列的处理后运行一些可执行的程序。

 

自己写u_boot命令:

在comcom目录下仿照其他文件的编写,在修改该目录下的Makefile,增加该文件

环境参数的设置(以此结构体存放):

typedefstructenvironment_s

{

unsignedlongcrc;/*CRC32overdatabytes*/

#ifdefCFG_REDUNDAND_ENVIRONMENT

unsignedcharflags;/*active/obsoleteflags*/

#endif

unsignedchardata[ENV_SIZE];/*Environmentdata*/

}env_t;

 

/*最开始,调用env_init函数对环境变量进行初始化,

这里暂时不考虑ENV_IS_EMBEDDED的情况,所以,初始化

工作就是设置env_addr地址,并设置env_valid为有限

*/

intenv_init(void)

初始化环境变量地址为default值之后,调用下面env_relocate函数具体分配内存空间,将环境变量从flash中读到内存中来,完成初始化过程.

前面介绍了环境变量初始化的过程,在完成了初始化之后。

U-boot其它部分的代码在要调用环境变的时候可以调用相应的接口读取。

这个接口就是getenv

Getenv函数就是在gd->env_addr这个buffer中不断的寻找name相对应的字符串,找到这个字符串”name=xxxxxx”之后将第一个x的地址返回。

本文还需要分析一下的就是对环境参数的保存,如果通过u-boot命令setenv修改了环境参数,我们必须还要通过saveenv将修改的参数保存在能在下次启动是继续使用设置的参数

这个函数比较简单,首先就是擦除相应部分的flash,然后将环境变量结构体写到对应的flash部分,我分析的mini2440中环境变量的偏移地址是256K,总共大小为64K.

 

向linux内核传递参数:

./common/cmd_bootm.c文件调用./uboot/arch/arm/lib/bootm.c文件中的do_nand_boot函数来启动Linuxkernel。

在do_nand_boot函数中:

intdo_nand_boot(cmd_tbl_t*cmdtp,intflag,intargc,char*argv[])

{

DECLARE_GLOBAL_DATA_PTR;

intret;

bd_t*bd=gd->bd;

ulongaddr,data,len,initrd_start,initrd_end;

void(*theKernel)(intzero,intarch,uintparams);

intstrlen;

char*commandline=getenv("bootargs");

setup_start_tag(bd);//初始化第一个kerneltag结构体

setup_serial_tag(¶ms);

setup_revision_tag(¶ms);

setup_memory_tags(bd);

theKernel(0,

machid,

bd->bi_boot_params//传给Kernel的参数=(structtag*)型的bd->bi_boot_params

);

}

setup_start_tag和setup_memory_tags函数说明

函数setup_start_tag也在此文件中定义,如下:

staticvoidsetup_start_tag(bd_t*bd)

{

params=(structtag*)bd->bi_boot_params;

/*初始化(structtag*)型的全局变量params为bd->bi_boot_params的地址,

*之后的setuptags相关函数如下面的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相关参数在函数setup_memory_tags中初始化:

staticvoidsetup_memory_tags(bd_t*bd)

{

inti;

for(i=0;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

}

Kernel读取U-boot传递的ATAG参数,

Head.s中最终调用start_kernel

init/main.c中的start_kernel函数中会调用setup_arch函数来处理各种平台相关的动作,包括了u-boot传递过来参数的分析和保存

其中,setup_arch函数在arch/arm/kernel/setup.c文件中实现,如下:

void__initsetup_arch(char**cmdline_p)

{

structtag*tags=(structtag*)&init_tags;

structmachine_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起始位置的指针,定义如下:

//unsignedint__atags_pointer__initdata;

//此指针指向__initdata段,各种tag的信息保存在这个段中。

tags=phys_to_virt(__atags_pointer);

elseif(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=(structtag*)&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=(unsignedlong)&_text;

init_mm.end_code=(unsignedlong)&_etext;

init_mm.end_data=(unsignedlong)&_edata;

init_mm.brk=(unsignedlong)&_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);

#ifdefCONFIG_SMP

smp_init_cpus();

#endif

……

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1