1、基于jz2440的uboot分析一、一般步骤:1、拷贝u-boot源文件至目标目录,解压,得到源代码树2、配置u-boot,执行命令 make 100ask24x0_config3、执行make 生成可执行的二进制文件 u-boot.bin4、Tftp 0x30000000 u-boot.bin或者NFS模式5、Go 0x30000000,或者烧写到nandflash中2、配置过程:make 100ask24x0_config查找顶层Makefile 的 100ask24x0_config目标:100ask24x0_config : unconfig $(MKCONFIG) $(:_confi
2、g=) arm arm920t 100ask24x0 NULL s3c24x0MKCONFIG:MKCONFIG := $(SRCTREE)/mkconfig$(:_config=) 将目标字符串的_config替代为空格,即 $(:_config=) 为 100ask24x0则上面的一句话变成:$(:_config=) 100ask24x0_config : unconfig mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0查找源根目录下的文件 mkconfig,执行完上述命令后得到:A、BOARD_NAME = 100ask24
3、x0 打印这句话 “Configuring for 100ask24x0 board.”B、.创建三个链接:cd ./includeln -s asm-$2 asm,即 ln -s asm-arm asm,在include目录下创建一个链接asm-arm指向asmln -s $LNPREFIXarch-$6 asm-$2/arch ,即ln -s arch-s3c24x0 asm-arm/archln -s $LNPREFIXproc-armv asm-$2/proc 即ln -s proc-armv asm-arm/procC、配置config.mk# Create include file
4、 for Make#echo ARCH = $2 config.mkecho CPU = $3 config.mkecho BOARD = $4 config.mk即在config.mk文件中:ARCH = arm CPU = arm920t BOARD = 100ask24x0 SOC = s3c24x0D、创建相关的头文件# Create board specific header file#创建相关的头文件#创建config.h头文件echo /* Automatically generated - do not edit */ config.hecho #include config.
5、h即在头文件 config.h中输入;/* Automatically generated - do not edit */#include ” 表示新建一个文件三、分析make过程1、首先指定一些常数,如版本等等,使用前面的配置文件mkconfig,得到一些参数如CPU,arch等。include $(OBJTREE)/include/config.mkexport ARCH CPU BOARD VENDOR SOC2、指定交叉编译器 export CROSS_COMPILE3、接着就是一系列需要编译的文件和库文件OBJS = cpu/$(CPU)/start.oOBJS := $(addp
6、refix $(obj),$(OBJS)LIBS = lib_generic/libgeneric.aLIBS += .LIBS := $(addprefix $(obj),$(LIBS) /给$(LIBS)加前缀 $(obj),即$(LIBS) = $(obj)$(LIBS),$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT) UNDEF_SYM=$(OBJDUMP) -x $(LIBS) |sed -n -e s/.*(_u_boot_cmd_.*)/-u1/p|sort|uniq; cd $(LNDIR)
7、 & $(LD) $(LDFLAGS) $UNDEF_SYM $(_OBJS) -start-group $(_LIBS) -end-group $(PLATFORM_LIBS) -Map u-boot.map -o u-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 -Ttext 0x33F80000 $UNDEF_SYM cpu/arm920t/start.o -start-group lib_
8、generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libd
9、tt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/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 -Map u-boot.map -o u-boot从中可以看出链接文件为 u-boot.ldsSECT
10、IONS . = 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
11、_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段#define Struct_Section _attribute_ (unused,section (.u_boot_cmd)#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) cmd_tbl_t _u_boot_cmd_#na
12、me Struct_Section = #name, maxargs, rep, cmd, usage, helpU_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按照给定参数初始化struct cmd_tbl_s char *name; /* Command Name */ int maxargs
13、; /* maximum number of arguments */ int repeatable; /* autorepeat allowed? */ /* Implementation function */ int (*cmd)(struct cmd_tbl_s *, int, int, char *); char *usage; /* Usage message (short) */#ifdef CFG_LONGHELP char *help; /* Help message (long) */#endif#ifdef CONFIG_AUTO_COMPLETE /* do auto
14、completion on the arguments */ int (*complete)(int argc, char *argv, char last_char, int maxv, char *cmdv);#endif;Run_command()将所有命令放在 u-boot.cmd段中,(以结构体形式存在),run_command()运行时,根据传进来的参数,find_command()函数来查找命令,之后进行一系列的处理后运行一些可执行的程序。自己写u_boot命令:在comcom目录下仿照其他文件的编写,在修改该目录下的Makefile,增加该文件环境参数的设置(以此结构体存放):
15、typedef struct environment_s unsigned long crc; /* CRC32 over data bytes */ #ifdef CFG_REDUNDAND_ENVIRONMENT unsigned char flags; /* active/obsolete flags */ #endif unsigned char dataENV_SIZE; /* Environment data */ env_t; /*最开始,调用env_init函数对环境变量进行初始化, 这里暂时不考虑ENV_IS_EMBEDDED的情况,所以,初始化 工作就是设置env_addr
16、地址,并设置env_valid为有限 */ int env_init(void)初始化环境变量地址为default值之后,调用下面env_relocate函数具体分配内存空间,将环境变量从flash中读到内存中来,完成初始化过程.前面介绍了环境变量初始化的过程,在完成了初始化之后。U-boot其它部分的代码在要调用环境变的时候可以调用相应的接口读取。这个接口就是getenvGetenv函数就是在gd-env_addr这个buffer中不断的寻找name相对应的字符串,找到这个字符串”name=xxxxxx”之后将第一个x的地址返回。本文还需要分析一下的就是对环境参数的保存,如果通过u-boot
17、命令setenv修改了环境参数,我们必须还要通过saveenv将修改的参数保存在能在下次启动是继续使用设置的参数这个函数比较简单,首先就是擦除相应部分的flash,然后将环境变量结构体写到对应的flash部分,我分析的mini2440中环境变量的偏移地址是256K,总共大小为64K.向linux内核传递参数:./common/cmd_bootm.c 文件调用 ./uboot/arch/arm/lib/bootm.c 文件中的 do_nand_boot 函数来启动 Linux kernel。 在do_nand_boot 函数中:int do_nand_boot (cmd_tbl_t *cmdtp
18、, int flag, int argc, char *argv) DECLARE_GLOBAL_DATA_PTR; int ret; bd_t *bd = gd-bd; ulong addr, data, len, initrd_start, initrd_end; void (*theKernel)(int zero, int arch, uint params);int strlen;char *commandline = getenv (bootargs); setup_start_tag (bd); / 初始化第一个kernel tag结构体 setup_serial_tag (&p
19、arams); setup_revision_tag (¶ms); setup_memory_tags (bd);theKernel (0,machid,bd-bi_boot_params / 传给 Kernel 的参数 (struct tag *) 型的 bd-bi_boot_params);setup_start_tag 和 setup_memory_tags 函数说明函数 setup_start_tag 也在此文件中定义,如下:static void setup_start_tag (bd_t *bd) params = (struct tag *) bd-bi_boot_par
20、ams;/* 初始化 (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 (
21、params);RAM 相关参数在函数 setup_memory_tags 中初始化:static void setup_memory_tags (bd_t *bd) int i; for (i = 0; i hdr.tag = ATAG_MEM; params-hdr.size = tag_size (tag_mem32); params-u.mem.start = bd-bi_drami.start; params-u.mem.size = bd-bi_drami.size; params = tag_next (params); / 初始化内存相关 tag Kernel 读取U-boot
22、 传递的ATAG参数 ,Head.s中最终调用start_kernelinit/main.c 中的 start_kernel 函数中会调用 setup_arch 函数来处理各种平台相关的动作,包括了 u-boot 传递过来参数的分析和保存其中, 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 = defa
23、ult_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_poin
24、ter); 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
25、_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(AT
26、AG_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_lineCOMMAND_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
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1