基于jz2440的uboot分析.docx
- 文档编号:4542615
- 上传时间:2022-12-06
- 格式:DOCX
- 页数:10
- 大小:194.36KB
基于jz2440的uboot分析.docx
《基于jz2440的uboot分析.docx》由会员分享,可在线阅读,更多相关《基于jz2440的uboot分析.docx(10页珍藏版)》请在冰豆网上搜索。
基于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中输入;
/*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 …… }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 jz2440 uboot 分析