• 生成boot.img流程 (makefile文件)


    **Mkbootimg.c:**========================================================
    if argc>2
    strcmp(arg,second/cmdline/kernel/ramdisk...)==> 设置值/偏移量(eg:bootimg = val /kernel_offset=strtoul(...))
    设置地址 eg :hdr.page_size = ....
    赋值hdr.magic
    判断cmdline长度是否过长
    
    
    ==》给boot_img_hdr hdr结构体变量赋值==》
    然后用load_file函数判断该地址对应的文件是否存在==》
    hdr添加哈希值==》
    打开bootimg文件,写入hdr==》
    在bootimg文件中写入padding,长度为pagesize-(itemsize&pagemask)
    
    **生成boot.img的Makefile=**===============================================
    #INTERNAL_BOOTIMAGES_ARGS是环境变量,用于指定Android系统启动时的内核引导参数(影响系统初始化、内存分配、设备驱动等)
    INTERNAL_BOOTIMAGE_ARGS := \
    	# 用于将前缀字符串 --second 添加到每个 $(INSTANLLED_2NBOOTLOADER_TARGET) 字符串之前,返回值是一个新的字符串列表
    	$(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
    	--kernel $(INSTALLED_KERNEL_TARGET) \
    	--ramdisk $(INSTALLED_RAMDISK_TARGET)
    
    #从环境变量INTERNAL_BOOTIMAGE_ARGS中过滤以--开头的字符传参数,并将剩余的参数作为INTERNAL_BOOTIMAGE_FILES变量的值
    #$(filter-out pattern ,text)用于匹配符合指定模式pattern的字符串,并返回未匹配的字符串列表text
    INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS))
    INTERNAL_BOOTIMAGE_FILES += $(INSTALLED_BOARDDTB_TARGET)
    
    #$(strip去除开头和结尾空格
    BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE))
    ifdef BOARD_KERNEL_CMDLINE  判断BOARD_KERNEL_CMDLINE是否被定义
      INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)" 将--cmdline "$(BOARD_KERNEL_CMDLINE)(加括号可能是为了保存空格)"加到INTERNAL_BOOTIMAGE_ARGS内核环境变量末尾
    endif
    
    
    BOARD_KERNEL_BASE := $(strip $(BOARD_KERNEL_BASE))
    ifdef BOARD_KERNEL_BASE
      INTERNAL_BOOTIMAGE_ARGS += --base $(BOARD_KERNEL_BASE)
    endif
    
    BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE))
    ifdef BOARD_KERNEL_PAGESIZE
      INTERNAL_BOOTIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE)
    endif
    
    BOARD_KERNEL_OFFSET := $(strip $(BOARD_KERNEL_OFFSET))
    ifdef BOARD_KERNEL_OFFSET
      INTERNAL_BOOTIMAGE_ARGS += --kernel_offset $(BOARD_KERNEL_OFFSET)
    endif
    
    同上
    
    #PRODUCT_BUILD_SECURE_BOOT_IMAGE是GNU Make(开源的构建自动化工具,根据makefile来管理和维护软件项目的构建过程)中定义的变量,用于判断INSTALLED_BOOTIMAGE_TARGET中变量的值
    ifneq ($(PRODUCT_BUILD_SECURE_BOOT_IMAGE_DIRECTLY),true)
    	INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
    else
    	INSTALLED_BOOTIMAGE_TARGET_NOT_SIGNED := $(PRODUCT_OUT)/boot.img
    	#将字符串encrypt拼接在$(INSTALLED_BOOTIMAGE_TARGET_NOT_SIGNED)变量后,可用于生成指定后缀名的文件名或路径
    	INSTALLED_BOOTIMAGE_TARGET := $(INSTALLED_BOOTIMAGE_TARGET_NOT_SIGNED).encrypt
    endif#ifeq ($(PRODUCT_BUILD_SECURE_BOOT_IMAGE_DIRECTLY),true)
    
    ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true)
    #call intermediates-dir-for函数用于生成由PRODUCT_OUT目录开始的/生成目标文件的中间文件目录(中间文件指软件构件过程中生成的非最终目标文件)
    #call intermediates-dir-for 参数1:EXECUTABLES是给定的模块类型
    #call intermediates-dir-for 参数2:boot_img是给定模块名
    #call intermediates-dir-for 参数3:空字符串是可选的子文件目录组成的目录路径,该路径通常用于存储临时文件,如编译过程中生成的对象文件、依赖关系文件等...
    #总之,这句话的含义是构建中产生boot_img模块的中间文件目录
    tmp_dir_for_image := $(call intermediates-dir-for,EXECUTABLES,boot_img)/bootimg
    INTERNAL_BOOTIMAGE_ARGS += --tmpdir $(tmp_dir_for_image)
    INTERNAL_BOOTIMAGE_ARGS += --genext2fs $(MKEXT2IMG)
    
    ifeq ($(TARGET_BOOTIMAGE_USE_EXTLINUX),true)
    INTERNAL_BOOTIMAGE_ARGS += --extlinuxconf $(TARGET_BOOTIMAGE_EXTLINUX_CONFIG)
    endif
    
    #结果:定义了一个规则用于生成目标文件$(INSTALLED_BOOTIMAGE_TARGET),规则的依赖项是$(MKEXT2IMG)$(INTERNAL_BOOTIMAGE_FILES)
    #$(call pretty,"Target boot image: $@")调用打印美化函数pretty打印
    #$(MKEXT2BOOTIMG)是一个工具或脚本的路径,用于生成boot image文件。$(INTERNAL_BOOTIMAGE_ARGS)是一组参数,用于配置生成过程的详细选项
    #--output $@表示将生成的文件保存为目标文件$(INSTALLED_BOOTIMAGE_TARGET)
    $(INSTALLED_BOOTIMAGE_TARGET): $(MKEXT2IMG) $(INTERNAL_BOOTIMAGE_FILES)
    	$(call pretty,"Target boot image: $@")
    	$(hide) $(MKEXT2BOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
    
    #.PHONY是一个伪目标,不管是否存在与该目标同名的文件或文件夹,它都应该被看作需要执行的目标;
    #bootimage-nodeps是一个伪目标,并不依赖于其他目标。==》即使没有bootimage-nodeps文件,make工具也会执行与该目标相关的命令或规则
    .PHONY: bootimage-nodeps
    bootimage-nodeps: $(MKEXT2IMG) 命令:依赖项
    	@echo "make $@: ignoring dependencies"打印消息,正在执行无视依赖项的操作
    	#$(hide是一个函数  用于隐藏命令的输出  使其在执行过程中不被显示出来
    	#--output $(INSTALLED_BOOTIMAGE_TARGET)将生成的文件保存至$(INSTALLED_BOOTIMAGE_TARGET
    	$(hide) $(MKEXT2BOOTIMG)(工具/脚本路径==》用于生成boot.img) $(INTERNAL_BOOTIMAGE_ARGS)(参数,配置生成过程的详细选项) --output $(INSTALLED_BOOTIMAGE_TARGET)
    
    else ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY)) # TARGET_BOOTIMAGE_USE_EXT2 != true
    ifneq ($(strip $(filter --%,$(BOARD_MKBOOTIMG_ARGS))),)
      INTERNAL_BOOTIMAGE_ARGS += $(strip $(BOARD_MKBOOTIMG_ARGS))
    endif
    
    # Check mkbootimg tool args: can't have two --second 
    #检查INTERNAL_BOOTIMAGE_ARGS中是否有>=2个--seconcd参数,有的话输出错误信息,终止编译,避免生成错误的boot image文件
    #$(words计算--second参数的个数
    #(filter选取为--second的参数
    ifeq ($(words $(filter --second,$(INTERNAL_BOOTIMAGE_ARGS))),2)
    #error会输出错误信息到命令行中,终止整个makefile的执行,显示变量(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS))
      $(error ERROR: find two --second args! $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS))
    endif
    
    #目标文件:生成目标文件的三个依赖项$(MKBOOTIMG)$(INTERNAL_BOOTIMAGE_FILES)$(BOOT_SIGNER),这三个文件其中一个发生变化时,makefile会重新生成目标文件
    $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(BOOT_SIGNER)
    	$(call pretty,"Target boot image: $@")
    	#隐藏执行生成boot.img文件的命令 结果输出在$(INSTALLED_BOOTIMAGE_TARGET)$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $@
    	#对生成的boot image文件进行签名,从而确保该文件没有被篡改过,其中/boot是Android系统中保存签名证书和公钥所需的目录
    	#$(BOOT_SIGNER)是签名工具的路径
    	#$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8   和    $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pe是用于签名的私钥和公钥
    	#$@表示要签名文件的名称  即之前生成的boot.img文件
    	$(BOOT_SIGNER) /boot $@ $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $@
    #这段主要是生成安全启动镜像
    ifeq ($(PRODUCT_BUILD_SECURE_BOOT_IMAGE_DIRECTLY),true)  该变量为真的话,生成安全启动镜像
    	$(hide) mv $@ $(INSTALLED_BOOTIMAGE_TARGET_NOT_SIGNED)将目标文件$@移动到$(INSTALLED_BOOTIMAGE_TARGET_NOT_SIGNED)
    	$(hide) $(PRODUCT_AML_SECUREBOOT_SIGNIMAGE) \使用工具$(PRODUCT_AML_SECUREBOOY_SIGNIMAGE)进行签名
    		--input $(INSTALLED_BOOTIMAGE_TARGET_NOT_SIGNED) \输入文件为$(INSTALLED_BOOTIMAGE_TARGET_NOT_SIGNED
    		--output $@ 文件输出路径
    	$(hide) @echo "$@: installed amlosgic encrypted kernel for verified boot"提示信息
    endif # ifeq ($(PRODUCT_BUILD_SECURE_BOOT_IMAGE_DIRECTLY),true)
    	#检查生成的安全启动镜像的大小是否超过指定的最大限制,即$(BOARD_BOOTIMAGE_PARTITION_SIZE))
    	$(hide) $(call assert-max-image-size,$@,$(BOARD_BOOTIMAGE_PARTITION_SIZE))
    
    
    .PHONY: bootimage-nodeps
    bootimage-nodeps: $(MKBOOTIMG) $(BOOT_SIGNER)
    	@echo "make $@: ignoring dependencies"
    	$(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output $(INSTALLED_BOOTIMAGE_TARGET)
    	$(BOOT_SIGNER) /boot $(INSTALLED_BOOTIMAGE_TARGET) $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).pk8 $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_VERITY_SIGNING_KEY).x509.pem $(INSTALLED_BOOTIMAGE_TARGET)
    	$(hide) $(call assert-max-image-size,$(INSTALLED_BOOTIMAGE_TARGET),$(BOARD_BOOTIMAGE_PARTITION_SIZE))
    
    else # PRODUCT_SUPPORTS_VERITY != true
    #筛选出前缀为--%的参数,去除掉其前后空格;如果$(BOARD_MKBOOTIMG_ARGS))有这样的参数的话,将这些参数追加到INTERNAL_BOOTIMAGE_ARGS中
    #可以将一些额外命令行的参数传递给mkbootimg工具,并将其添加到生成安全启动镜像的命令行中
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
  • 相关阅读:
    PyTorch基础(18)-- torch.stack()方法
    C - Bound Found
    万字总结:分布式系统的38个知识点
    调用后台接口实现Excel导出功能
    性早熟和微生物群:性激素-肠道菌群轴的作用
    Springboot大学生健康报送系统的设计与实现毕业设计源码091005
    猿桌派第三季开播在即,打开出海浪潮下的开发者新视野
    运算符
    DAC测试实验——FPGA学习笔记7
    Matlab/simulink光伏发电的恒定电压法MPPT仿真(持续更新)
  • 原文地址:https://blog.csdn.net/JIAY_WX/article/details/132907937