300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > uboot加载linux内核加载那些内容 几个地址参数及uboot加载启动内核过程的理解

uboot加载linux内核加载那些内容 几个地址参数及uboot加载启动内核过程的理解

时间:2019-03-17 02:06:37

相关推荐

uboot加载linux内核加载那些内容 几个地址参数及uboot加载启动内核过程的理解

关于uBoot和Linux内核中几个地址参数及uboot加载启动内核过程的理解

uboot一般使用mkimage工具先制作一个启动映象文件来引导识别内核的,uboot源代码的tools/目录下有mkimage工具,这个工具可以用来制作不压缩或者压缩的多种可启动映象文件。mkimage在制作映象文件的时候,是在原来的可执行映象文件的前面加上一个0x40字节的头,记录参数所指定的信息,这样uboot才能识别这个映象是针对哪个CPU体系结构的,哪个OS的,哪种类型,加载内存中的哪个位置, 入口点在内存的那个位置以及映象名是什么

vim arch/arm/Makefile

31 # defines filename extension depending memory management type.

32 ifeq ($(CONFIG_MMU),)

33 MMUEXT := -nommu

34 endif

121 #Default value

122 head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task .o

123 textofs-y := 0x00008000

124 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000

125 # We don't want the htc bootloader to corrupt kernel during resume

126 textofs-$(CONFIG_PM_H1940) := 0x00108000

127 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memo ry

128 ifeq ($(CONFIG_ARCH_SA1100),y)

129 textofs-$(CONFIG_SA1111) := 0x00208000

130 endif

222 # The byte offset of the kernel image in RAM from the start of RAM.

223 TEXT_OFFSET := $(textofs-y)

241 export TEXT_OFFSET GZFLAGS MMUEXT

./scripts/mkuboot.sh

#!/bin/bash

#

# Build U-Boot image when `mkimage' tool is available.

#

MKIMAGE=$(type -path "${CROSS_COMPILE}mkimage")

if [ -z "${MKIMAGE}" ]; then

MKIMAGE=$(type -path mkimage)

if [ -z "${MKIMAGE}" ]; then

# Doesn't exist

echo '"mkimage" command not found - U-Boot images will not be built' >&2

exit 1;

fi

fi

# Call "mkimage" to create U-Boot image

${MKIMAGE} "$@"

./arch/arm/mach-s3c2410/Makefile.boot

1 ifeq ($(CONFIG_PM_H1940),y)

2 zreladdr-y := 0x30108000

3 params_phys-y := 0x30100100

4 else

5 zreladdr-y := 0x30008000

6 params_phys-y := 0x30000100

7 endif

vim arch/arm/boot/Makefile

14 MKIMAGE := $(srctree)/scripts/mkuboot.sh

16 ifneq ($(MACHINE),)

17 include $(srctree)/$(MACHINE)/Makefile.boot //即arch/arm/mach-s3c2410/Makefile.boot

18 endif

20 # Note: the following conditions must always be true:

21 # ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)

22 # PARAMS_PHYS must be within 4MB of ZRELADDR

23 # INITRD_PHYS must be in RAM

24 ZRELADDR := $(zreladdr-y) //内核加载地址ZRELADDR

25 PARAMS_PHYS := $(params_phys-y)

26 INITRD_PHYS := $(initrd_phys-y)

27

28 export ZRELADDR INITRD_PHYS PARAMS_PHYS

29

30 targets := Image zImage xipImage bootpImage uImage

62 quiet_cmd_uimage = UIMAGE $@

63 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \

64 -C none -a $(LOADADDR) -e $(STARTADDR) \

65 -n 'Linux-$(KERNELRELEASE)' -d $< $@

66

67 ifeq ($(CONFIG_ZBOOT_ROM),y)

68 $(obj)/uImage: LOADADDR=$(CONFIG_ZBOOT_ROM_TEXT)

69 else

70 $(obj)/uImage: LOADADDR=$(ZRELADDR)

71 endif

72

73 $(obj)/uImage: STARTADDR=$(LOADADDR)

cmd_uimage展开相当于:

mkimage -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -n 'Linux-3.0" -d zImage uImage

-A:CPU类型

-O:操作系统

-T:用于指定image类型,比如Kernel

-C:采用的压缩方式

-a:内核加载地址

-e:内核入口地址

-d 无头信息的image文件名

Boot options --->

[ ] Flattened Device Tree support

(0x0) Compressed ROM boot loader base address

(0x0) Compressed ROM boot loader BSS address

430:CONFIG_ZBOOT_ROM_TEXT=0x0

431:CONFIG_ZBOOT_ROM_BSS=0x0

arch/arm/boot/compressed/Makefile

ifeq ($(CONFIG_ZBOOT_ROM),y)

ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT) //自解压程序地址ZTEXTADDR

ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS)

else

ZTEXTADDR := 0

ZBSSADDR := ALIGN(8)

endif

默认值ZTEXTADDR= 0x00000000表示不使用。(只能通过uBoot的gunzip解压加载)

include/configs/st2410.h -n

127:#define CFG_LOAD_ADDR 0x33000000 /* default load address*///uImage存放地址

uBoot的do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);

函数将检验存放到0x33000000地址处的经过mkimage格式化的uImage数据的头部

typedef struct image_header {

uint32_t ih_magic; /* Image Header Magic Number */

uint32_t ih_hcrc; /* Image Header CRC Checksum */

uint32_t ih_time; /* Image Creation Timestamp */

uint32_t ih_size; /* Image Data Size */

uint32_t ih_load; /* Data Load Address */

uint32_t ih_ep; /* Entry Point Address */

uint32_t ih_dcrc; /* Image Data CRC Checksum */

uint8_t ih_os; /* Operating System */

uint8_t ih_arch; /* CPU architecture */

uint8_t ih_type; /* Image Type */

uint8_t ih_comp; /* Compression Type */

uint8_t ih_name[IH_NMLEN]; /* Image Name */

} image_header_t;

(ih_ep值为0x30008000,ih_load值为0x30008000)

如果头部各个域值和crc合法,那么do_bootm将调用如下gunzip解压函数对

0x33000000 +sizeof(image_header_t)地址处的压缩内核进行解压:

gunzip((void*)ntohl(hdr->ih_load),unc_len,(uchar *)data,(int*)&len);

1.hdr->ih_load 为输出数据地址0x30008000

2.unc_len 为gunzip解压输出数据上限值-8M,do_bootm函数前有定义#define CFG_BOOTM_LEN 0x800000,uint unc_len = CFG_BOOTM_LEN;

3.data 为输入数据地址data=0x33000000 +sizeof(image_header_t);

4.Len 为输入数据长度len = ntohl(hdr->ih_size );

解压完成后将会存储解压后数据的实际大小

压缩的Linux内核文件uImage,经由gunzip解压函数后,通过

do_bootm_linux (cmdtp, flag, argc, argv,addr, len_ptr, verify);

函数向Linux内核传递内核运行所需的3个参数,在bootm执行的流程中,可以看到会调用do_bootm_linux()在执行Linux内核,内核的起始地址如下:

void (*theKernel)(int zero, int arch, uint params);

image_header_t *hdr = &header;

theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);

header是uImage的头部,通过头部,得到内核映像起始的执行地址hdr->ih_ep为0x30008000,标识为theKernel。从中也可以看到,内核接受三个参数,第一个为0,第二个为系统的ID号,第三个是传入内核的参数。

在do_bootm_linux()的最后,会跳到内核去执行:

theKernel (0, bd->bi_arch_number, bd->bi_boot_params);

这样完成了Linux系统启动所需要3个参数的传递,至此uBoot的工作已经结束,Linux将在0x30008000地址处正式运行。

阅读(4021) | 评论(0) | 转发(0) |

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。