• uboot指令笔记


    ​ Linux的移植要复杂的多,在移植 Linux之前我们需要先移植一个 bootloader代码,这个 bootloader代码用于启动 Linux内核,bootloader有很多,常用的就是 U-Boot

    ​ 移植好 U-Boot以后再移植 Linux内核,移植完 Linux内核以后Linux还不能正常启动。

    ​ 还需要再移植一个根文件系统(rootfs),根文件系统里面包含了一些最常用的命令和文件。

    ​ 所以 U-Boot、Linux kernel和 rootfs这三者一起构成了一个完整的 Linux系统

    1.u-boot
    1.1 u-boot是啥

    ​ Linux系统要启动就必须需要一个 bootloader程序,也就说芯片上电以后先运行一段bootloader程序

    ​ 这段 bootloader程序会先初始化 DDR等外设,然后将 Linux内核从 flash(NAND,NOR FLASH,SD,MMC等)拷贝到 DDR中,最后启动 Linux内核

    ​ 它最主要的工作就是启动 Linux内核,bootloader和 Linux内核的关系就跟 PC上的 BIOS和 Windows的关系一样,bootloader就相当于 BIOS

    image-20221108221526114

    sudo apt-get install libncurses5-dev 
    tar -vxjf uboot-imx-2016.03-2.1.0-g8b546e4.tar.bz2  //解压文件
    
    • 1
    • 2

    mx6ull_alientek_emmc.sh

    使用chmod 777给shell脚本权限,在执行./mx6ull_alientek_emmc.sh脚本文件来重新编译uboot

    
    #!/bin/bash
    //sheel脚本第一行必须是"#!/bin/bash"或者"#!/bin/sh"
    
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean 
    // ARCH=arm设置目标为arm架构  CROSS_COMPILE用于指定所使用的交叉编译器
    // 这里等效于指令make distclean,目的是清除工程,建议在第一次使用时清理一下工程
    
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig 
    // make mx6ull_14x14_ddr512_emmc_defconfig  
    // 用于配置uboot,配置文件为 mx6ull_14x14_ddr512_emmc_defconfig 
    // 编译uboot时候根据自己的需求去配置uboot,支持USB 网络 SD卡等。
    // 在uboot中,可以通过make XXX_defconfig 来配置uboot,这个就是不同板子的配置文件,都在uboot/configs中
    
    make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12 
    // V=1 用于设置编译过程的信息输出级别
    // make -j12  使用12核来编译uboot,用于设置主机使用多少线程来编译uboot,最好设计成虚拟机的核心数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    U-Boot烧写和启动

    chmod 777 imxdownload 
    ./imxdownload u-boot.bin /dev/sdb
    
    • 1
    • 2

    ​ 烧写完成插到开发板上,BOOT设置成从SD卡打开,使用USB连接USB_TTL和电脑,将开发板的串口1连接到电脑上,使用MobaXterm设置好串口参数打开,最后复位开发板

    ​ 在MobaXterm出现**“Hit any key to stop autoboot: ”**倒计时的时候,按下键盘上的回车键,默认是 3秒倒计时。

    ​ 在 3秒倒计时结束如果没有按下回车键的话 uboot就会使用默认参数来启动 Linux内核

    ​ 如果在 3秒倒计时结束之前按下回车键,那么就会进入 uboot命令行模式

    U-Boot 2016.03 (Nov 08 2022 - 06:25:27 -0800)              
    //uboot版本号2016.03和编译时间2022.11.8
    
    CPU:   Freescale i.MX6ULL rev1.1 792 MHz (running at 396 MHz)  
    //CPU是飞思卡尔(被NXP收购)I.MX6ULL 频率是792MHz,当前运行在396MHz
    
    CPU:   Industrial temperature grade (-40C to 105C) at 36C
    // 工业级芯片,温度为-40度到105度
    
    Reset cause: POR
    // 复位原因,当前的复位原因是POR,芯片有一个POR_B引脚,将这个引脚拉低即可复位I.MX6ULL
    
    Board: I.MX6U ALPHA|MINI
    // 当前板子名字
    
    I2C:   ready
    // I2C准备就绪
    
    DRAM:  512 MiB
    // DRAM内存为512MB,这是EMMC的版本
    
    MMC:   FSL_SDHC: 0, FSL_SDHC: 1
    // 当前有两个MMC/SD卡控制器FSL_SDHC0和FSL_SDHC1了,板卡上FSL_SDHC0接的SD(TF)卡,FSL_SDHC1接的EMMC.
    
    *** Warning - bad CRC, using default environment
    Display: ATK-LCD-7-1024x600 (1024x600) 
    11 Video: 1024x600x24 
    // 没接LCD会显示第一行报错,当前的LCD型号是ATK-LCD-7-1024x600 (1024x600),格式为RGB888
    
    In:    serial
    Out:   serial
    Err:   serial
    // 标准输入,标准输出和标准错误所使用的终端,这里都是使用串口来作为终端
    
    switch to partitions #0, OK
    mmc0 is current device
    // 切换到emmc的第0个分区,当前u-boot是emmc版本,从emmc启动,为了方便烧写到SD卡,本质还是EMMC的。这里将EMMC作为默认存储器,也可以将SD卡来作为uboot的存储器。
    
    Net:   FEC1
    Error: FEC1 address not set.
    // 使用FEC1网口,一共有两个网口,并提示FEC1网络地址没有设置。
    
    Normal Boot
    // 正常启动,uboot要从emmc里面读取环境变量和参数信息来启动linux内核。
    Hit any key to stop autoboot:  0
    =>
    
    • 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
    1.2 u-boot常用命令
    help(?)查看命令的参考信息
    env
    bdinfo用于查看板子信息,DRAM的起始地址和大小、启动参数保存起始地址、波特率、sp(堆栈指针)起始地址等信息
    printenv用于输出环境变量信息,bootdelay是默认延时几秒
    version查看uboot版本
    setenv一般环境变量是存放在外部 flash中的,uboot启动的时候会将环境变量从 flash读取到DRAM,修改后保存回flash。 如果修改的环境变量值有空格,需要使用单引号
    saveenvDRAM中将修改后的环境变量保存到flash,比如 setenv bootdelay 5 saveenv 重新启动后裔uboot变为5秒倒计时
    setenv author junluoyu如果author不存在,这就是新建一个环境变量author,value为junluoyu
    setenv author删除环境变量,给对应的环境变量赋为空值,记得每次执行env命令都需要saveenv一次。
    memory accesss
    md[.b .w .l] address[# of objects][.b .w .l]对应byte word long,表示1个字节 2个字节以及4个字节 address是需要查看的内存起始地址 [# of objects]表示要查看的数据长度,单位是[.b .w .l],注意都是16进制的写法
    md.b 80000000 14查看0X800000000(800000000)开始的20(0x14)个字节的内存值
    nm[.b .w .l] address修改指定地址的内存值,在?的后面输入要修改后的数据12345678,输入后使用回车,按q离开
    mm[.b .w .l] address修改指定地址内存值,使用mm修改内存值的同时地址会递增,使用nm不会递增。
    mw [.b, .w, .l] address value [count]使用一个指定的数据来填充一段内存
    mw.l 80000000 0A0A0A0A 10 md.l 80000000 10以0X80000000为起始地址的0x10(16)个内存块(16*4=64字节)填充为0A0A0A0A
    cp [.b, .w, .l] source target count将DRAM中的数据从一段内存拷贝到另一段内存,或者把Nor Flash中的数据拷贝到DRAM中去。
    cp.l 800000000 80000100 10 md.l 80000000 10 md.l 80000100 10按4字节的格式将0x80000000处的地址拷贝到0x80000100处,长度为0x10个(16*4=64个字节)
    cmp [.b, .w, .l] addr1 addr2 count比较两段内存的数据是否相等 两个地址是内存首地址 count是需要比较的长度
    cmp.l 80000000 80000100 10比较0x80000000和0x80000100两个地址的64个字节是否相等
    Internet setting
    setenv ipaddr 192.168.10.50
    setenv ethaddr b8:ae:1d:01:00:00
    setenv gatewayip 192.168.10.1
    setenv netmask 255.255.255.0 setenv serverip 192.168.10.100
    saveenv
    电脑 192.168.10.200
    板卡 192.168.10.50
    Ubuntu主机地址为192.168.10.100 就是serverip
    ping 192.168.10.100是否跟Ubuntu主机进行通信,通过PING命令来验证 只能在uboot中ping其他机器,其他机器不能ping uboot,因为uboot没有对ping命令做处理。
    dhcp用于从路由器来获取ip地址,开发板必须连接到路由器上 DHCP不仅是获取IP地址,还会通过TFTP来启动linux内核 dhcp - boot image via network using DHCP/THCP protocol
    nfs
    nfs(Network File System)可以在uboot中使用nfs命令来将ubuntu中的linux镜像和设备树下载到开发板的DRAM中,方便调试linux镜像和设备树。网络调试时linux开发中最常用的调试方法。
    嵌入式 Linux通常是烧写到 EMMC、NAND Flash、SPI Flash等外置 flash
    nfs [loadAddress] [[hostIPaddr:]bootfilename]loadAddress是要保存的DRAM地址,[[hostIPaddr:]bootfilename] 是要下载的文件地址。
    nfs 80800000 192.168.10.100:/home/junluoyu/linux/zImage80800000是zImage保存的地址
    192.168.10.100:/home/junluoyu/linux/zImage表示存放在IP为192.168.10.100的ubuntu主机的位置
    tftp
    tftp [loadAddress] [[hostIPaddr:]bootfilename]loadAddress是文件在DRAM中的存放地址,[[hostIPaddr:]bootfilename] 是要下载的文件地址。 和nfs的区别是不需要输入文件在ubuntu的路径,只需要输入文件名
    tftp 80800000 zImage自动从tftp的文件夹里面将文件下载到对应的DRAM里面
    EMMC
    mmc info(mmcinfo)输出MMC设备数据,mmc包括emmc和sd卡
    mmc rescan扫描所有的MMC设备,包括EMMC和SD卡
    mmc list查看有几个mmc设备
    FSL_SDHC:0是 SD卡,FSL_SDHC:1(eMMC)是 EMMC
    默认会将 EMMC设置为当前 MMC设备
    mmc dev [dev] [part]切换当前MMC设备,[dev]是设备号,[part]是分区号,不写分区号默认分区为0
    mmc dev 0 //切换到SD卡,0为SD卡,1为emmc
    mmc part查看分区
    mmc read addr blk #cnt读取mmc设备的数据
    addr是数据读取到 DRAM中的地址,blk是要读取的块起始地址(十六进制),一个块是 512字节,这里的块和扇区是一个意思,在 MMC设备中我们通常说扇区,cnt是要读取的块数量(十六进制)
    mmc read 80800000 600 10从 EMMC的第 1536(0x600)个块开始,读取 16(0x10)个块的数据到 DRAM的0X80800000地址处
    mmc write addr blk# cn将数据写入到mmc设备,一个块为512字节,addr是数据写入到 DRAM中的地址
    mmc erase blk# cnt擦除MMC设备,blk为删除的起始块,cnt是需要擦除的数量
    FAT格式文件
    fatinfo []查询指定MMC设备分区的文件系统信息,interface表示接口,可以是mmc;dev是查询的设备号,part是查询的分区
    fatinfo mmc 1:1EMMC分区1的文件系统格式,为FAT32格式
    fatls [] [directory]查询FAT格式设备的目录和文件信息,directory是查询的目录
    fstype :用于查看MMC设备某个分区的文件系统格式
    fstype mmc 1:0
    fstype mmc 1:1
    fstype mmc 1:2
    EMMC默认有三个分区,分区0的格式未知,因为分区0存放uboot并且没有格式化。分区1的格式为fat,存放linux镜像和设备树;分区2存放的是ext4,用于存放linux的根文件系统(rootfs)
    fatload [ [ [ [bytes [pos]]]]]将指定的文件读取到DRAM中,bytes为读取多少字节的数据,pos是要读取的文件相当于文件首地址的偏移,如果bytes为0或者省略表示从文件首地址来开始读取。
    fatwrite 将DRAM中的数据写入到MMC设备中。
    EXT文件格式 ext2 ext4类似FAT
    ext4ls ext2lsext4ls mmc 1:2
    查询emmc分区2的文件和目录
    ext4load ext2load将指定的文件读取到DRAM中
    ext4write将DRAM中的文件写入MMC
    NAND必须使用NAND板子以及对应的NAND-uboot
    nand info打印nand信息
    nand device如果板子支持多片NAND,就可以用命令切换当前的NAND,这需要CPU有两个NAND控制器
    nand erase擦除NAND Flash,NAND的特性决定了写数据之前一定要对写入的数据才能进行擦除
    nand erase[.spread] [clean] off size从指定地址开始,擦除指定大小的区域
    nand erase.part [clean] aprtition擦除指定的分区
    nand erase.chip [clean]全篇擦除
    nand write addr off size向指定的地址写入指定的数据
    addr是要写入的数据首地址,off是 NAND中的目的地址,size是要写入的数据大小
    nand read addr off size用于从NAND中的指定地址读取指定大小的数据到DRAM中
    addr是目的地址,off是要读取的NAND中的数据源地址,size是需要读取的数据大小
    BOOT
    bootz [addr [initrd[:size]] [fdt]]将linux镜像文件和设备树文件存到DRAM中,再使用bootz命令来启动。
    addr是linux镜像文件再DRAM中的位置;
    initrd是initrd文件在DRAM中的地址,如果不使用initrd的话使用’-‘来代替
    fdt就是设备树文件在DRAM的地址
    tftp 80800000 zImage
    tftp 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb
    bootz 80800000 - 83000000
    使用tftp下载linux镜像文件和设备树到DRAM里面,最后以命令bootz启动
    fatload mmc 1:1 80800000 zImage
    fatload mmc 1:1 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb
    bootz 80800000 - 83000000
    先使用命令 fatls查看要下 EMMC的分区 1中有没有 Linux镜像文件和设备树文件,如果没有的话fatwrite命令将 tftp中的 zImage和 imx6ull-14x14-emmc-4.3-800x480-c.dtb文件烧写到 EMMC的分区 1中。
    使用命令 fatload将 zImage和 imx6ull-14x14-emmc-4.3-800x480-c.dtb文件拷贝到 DRAM中,地址分别为 0X808000000X83000000,最后使用 bootz启动
    bootm addrbootm用于启动uImage镜像文件,不使用设备树时直接bootm addr
    bootm [addr [initrd[:size]] [fdt]]使用设备树和bootz一样
    boot读取环境变量bootcmd来启动linux系统
    setenv bootcmd ‘tftp 80800000 zImage;
    tftp 83000000 imx6ull-14x14-emmc-4.3-800x480-c.dtb;
    bootz 80800000 - 83000000’
    saveenv
    boot
    使用saveenv将bootcmd保存起来,然后直接输入boot命令来实现从网络中启动Linux系统。uboot的倒计时就是结束后启动bootcmd中的启动项命令
    其他命令
    reset复位重启
    go addr[arg …]用于跳到指定地址处执行应用
    tftp 87800000 printf.bin
    go 87800000
    将程序加载到指定的DRAM上,再启动,可以使用go命令来在uboot中运行裸机例程
    run可以自定义不同的启动环境变量,切换启动方式使用run mybootxxx(emmc或者net或者nand)
    mtest [start [end [pattern [iterations]]]]测试开发板的DDR,start时DRAM开始地址,end为结束地址
    mtest 80000000 80001000 启动memoey的测试,使用ctrl+c结束

    网络连接设置

    image-20221109142945644

    image-20221109143225484

    更新EMMC的uboot

    mmc dev 1 0                //切换到 EMMC分区 0 
    tftp 80800000 u-boot.imx   //下载 u-boot.imx到 DRAM 
    mmc write 80800000 2 32E   //烧写 u-boot.imx到 EMMC中 ,不能将imx写入到SD卡或者EMMC的前两个块,里面保存分区表
    mmc partconf 1 1 0 0       //分区配置,EMMC需要这一步!
    
    • 1
    • 2
    • 3
    • 4

    更新EMMC的linux镜像

    tftp 80800000 zImage                      //下载zImage到 DRAM 
    fatwrite mmc 1:1 80800000 zImage 6788f8   //emmc的1区存放linux镜像,这里的6788f8是字节的数目
    fatls mmc  1:1                            //查看emmc的分区1
    
    • 1
    • 2
    • 3
    1.3 顶层Makefile(完全没有看懂)

    Makefile

    #
    # SPDX-License-Identifier:	GPL-2.0+
    #
    
    VERSION = 2016  #主版本号
    PATCHLEVEL = 03 #补丁版本号                  
    SUBLEVEL =      #次版本号
    EXTRAVERSION =  #附加版本信息
    NAME =          #名字
    
    # *DOCUMENTATION*
    # To see a list of typical targets execute "make help"
    # More info can be located in ./README
    # Comments in this file are targeted only to the developer, do not
    # expect to learn how to build the kernel reading this file.
    
    # o Do not use make's built-in rules and variables
    #   (this increases performance and avoids hard-to-debug behaviour);
    # o Look for make include files relative to root of kernel src
    MAKEFLAGS += -rR --include-dir=$(CURDIR)
    # -rR表示禁止使用内置的隐含规则和变量定义
    # --include-dir 指明搜索路径
    # $(CURDIR) 表示当前目录
    
    # $(MAKE) -C subdir  调用make命令指定子目录
    # export VARIABLE ...导出变量给子make
    # unexport VARIABLE ...不导出变量给子make
    # SHELL 和 MAKEFLAGS 除非使用unexport声明。否则的话在make执行中始终传递给子make
    
    # Avoid funny character set dependencies
    unexport LC_ALL
    LC_COLLATE=C
    LC_NUMERIC=C
    export LC_COLLATE LC_NUMERIC
    
    # Avoid interference with shell env settings
    unexport GREP_OPTIONS
    
    # We are using a recursive build, so we need to do a little thinking
    # to get the ordering right.
    #
    # Most importantly: sub-Makefiles should only ever modify files in
    # their own directory. If in some directory we have a dependency on
    # a file in another dir (which doesn't happen often, but it's often
    # unavoidable when linking the built-in.o targets which finally
    # turn into vmlinux), we will call a sub make in that other dir, and
    # after that we are sure that everything which is in that other dir
    # is now up to date.
    #
    # The only cases where we need to modify files which have global
    # effects are thus separated out and done before the recursive
    # descending is started. They are now explicitly listed as the
    # prepare rule.
    
    # Beautify output
    # ---------------------------------------------------------------------------
    #
    # Normally, we echo the whole command before executing it. By making
    # that echo $($(quiet)$(cmd)), we now have the possibility to set
    # $(quiet) to choose other forms of output instead, e.g.
    #
    #         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
    #         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
    #
    # If $(quiet) is empty, the whole command will be printed.
    # If it is set to "quiet_", only the short version will be printed.
    # If it is set to "silent_", nothing will be printed at all, since
    # the variable $(silent_cmd_cc_o_c) doesn't exist.
    #
    # A simple variant is to prefix commands with $(Q) - that's useful
    # for commands that shall be hidden in non-verbose mode.
    #
    #	$(Q)ln $@ :<
    #
    # If KBUILD_VERBOSE equals 0 then the above command will be hidden.
    # If KBUILD_VERBOSE equals 1 then the above command is displayed.
    #
    # To put more focus on warnings, be less verbose as default
    # Use 'make V=1' to see the full commands
    
    # uboot默认编译时v=0,在make前面加上@,不会在终端显示完整的命令,都是短命令
    # 使用 V = 1来是实现完整的命令输出,在调试的时候很有用
    ifeq ("$(origin V)", "command line")
      # $(origin ) 返回变量variable的变量来源,是命令行来的就来自"command line"
      KBUILD_VERBOSE = $(V)  #输入 V = 1, 这个时候KBUILD_VERBOSE的数值就是1
    endif
    ifndef KBUILD_VERBOSE
      KBUILD_VERBOSE = 0     #没有在命令行输入V的数值,那么就有KBUILD_VERBOSE的数值就是0
    endif
    
    ifeq ($(KBUILD_VERBOSE),1)
      quiet =
      Q =
    else
      quiet=quiet_
      Q = @
    endif
    # Makefile会使用quiet和Q来控制编译的时候是否在终端输出完整的命令
    # $(Q)$(MAKE)$(build)=tools
    # 如果V=0, @make $(build)=tools,make在执行会默认终端输出命令,加@不会在终端输出命令
    # 如果V=1,就是make $(build)=tools,此时命令就会完整的输出在终端
    
    # 如果变量quiet为空的时候,整个命令都会输出            cmd_xxx
    # 如果变量quiet为"quiet_"的话,仅输出短版本           quiet_cmd_xxx
    # 如果变量quiet为"silent_"的话,整个命令都不会输出    silent_cmd_xxx
    
    
    # If the user is running make -s (silent mode), suppress echoing of
    # commands
    # make -s 实现静默输出
    
    ifneq ($(filter 4.%,$(MAKE_VERSION)),)	# make-4
    # $(filter,),以pattern模式过滤text字符串中的单词  %为通配符
    ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
    # $(firstword) 用于取出text字符串中的第一个单词
    # MAKEFLAGS的第一个单词时xrRs
      quiet=silent_
    endif
    else					# make-3.8x
    ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
      quiet=silent_
    endif
    endif
    
    export quiet Q KBUILD_VERBOSE
    # make O=out 设置目标文件输出到out目录中
    # kbuild supports saving output files in a separate directory.
    # To locate output files in a separate directory two syntaxes are supported.
    # In both cases the working directory must be the root of the kernel src.
    # 1) O=
    # Use "make O=dir/to/store/output/files/"
    #
    # 2) Set KBUILD_OUTPUT
    # Set the environment variable KBUILD_OUTPUT to point to the directory
    # where the output files shall be placed.
    # export KBUILD_OUTPUT=dir/to/store/output/files/
    # make
    #
    # The O= assignment takes precedence over the KBUILD_OUTPUT environment
    # variable.
    
    # KBUILD_SRC is set on invocation of make in OBJ directory
    # KBUILD_SRC is not intended to be used by the regular user (for now)
    ifeq ($(KBUILD_SRC),)
    
    # OK, Make called in directory where kernel src resides
    # Do we want to locate output files in a separate directory?
    ifeq ("$(origin O)", "command line")
      KBUILD_OUTPUT := $(O)
    endif
    
    # That's our default target when none is given on the command line
    PHONY := _all
    _all:
    
    # Cancel implicit rules on top Makefile
    $(CURDIR)/Makefile Makefile: ;
    
    ifneq ($(KBUILD_OUTPUT),)
    # Invoke a second make in the output directory, passing relevant variables
    # check that the output directory actually exists
    saved-output := $(KBUILD_OUTPUT)
    KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
    								&& /bin/pwd)
    $(if $(KBUILD_OUTPUT),, \
         $(error failed to create output directory "$(saved-output)"))
    
    PHONY += $(MAKECMDGOALS) sub-make
    
    $(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
    	@:
    
    sub-make: FORCE
    	$(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \
    	-f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))
    
    # Leave processing to above invocation of make
    skip-makefile := 1
    endif # ifneq ($(KBUILD_OUTPUT),)
    endif # ifeq ($(KBUILD_SRC),)
    
    # We process the rest of the Makefile if this is the final invocation of make
    ifeq ($(skip-makefile),)
    
    # Do not print "Entering directory ...",
    # but we want to display it when entering to the output directory
    # so that IDEs/editors are able to understand relative filenames.
    MAKEFLAGS += --no-print-directory
    
    # make C=1 使能代码检查
    # make C=2 用于检查所有的源码文件
    
    # Call a source code checker (by default, "sparse") as part of the
    # C compilation.
    #
    # Use 'make C=1' to enable checking of only re-compiled files.
    # Use 'make C=2' to enable checking of *all* source files, regardless
    # of whether they are re-compiled or not.
    #
    # See the file "Documentation/sparse.txt" for more details, including
    # where to get the "sparse" utility.
    
    ifeq ("$(origin C)", "command line")
      KBUILD_CHECKSRC = $(C)
    endif
    ifndef KBUILD_CHECKSRC
      KBUILD_CHECKSRC = 0
    endif
    
    # 允许单独编译某个模块 make M=dir 
    # Use make M=dir to specify directory of external module to build
    # Old syntax make ... SUBDIRS=$PWD is still supported
    # Setting the environment variable KBUILD_EXTMOD take precedence
    ifdef SUBDIRS
      KBUILD_EXTMOD ?= $(SUBDIRS)
    endif
    # 支持老语法 make SUBDIRS = dir
    
    ifeq ("$(origin M)", "command line")
      KBUILD_EXTMOD := $(M)
    endif
    
    # If building an external module we do not care about the all: rule
    # but instead _all depend on modules
    PHONY += all
    ifeq ($(KBUILD_EXTMOD),)
    _all: all          #为空的时候,目标_all依赖于all
    else
    _all: modules      #不为空的话。就去编译特定的模块
    endif
    
    ifeq ($(KBUILD_SRC),)
            # building in the source tree
            srctree := .
    else
            ifeq ($(KBUILD_SRC)/,$(dir $(CURDIR)))
                    # building in a subdirectory of the source tree
                    srctree := ..
            else
                    srctree := $(KBUILD_SRC)
            endif
    endif
    objtree		:= .
    src		:= $(srctree)   #当前目录
    obj		:= $(objtree)   #当前目录
    
    VPATH		:= $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
    
    export srctree objtree VPATH
    
    # Make sure CDPATH settings don't interfere
    unexport CDPATH
    
    #########################################################################
    # Makefile获取主机架构和系统,也就是我们电脑的架构和系统
    HOSTARCH := $(shell uname -m | \
    	sed -e s/i.86/x86/ \
    	    -e s/sun4u/sparc64/ \
    	    -e s/arm.*/arm/ \
    	    -e s/sa110/arm/ \
    	    -e s/ppc64/powerpc/ \
    	    -e s/ppc/powerpc/ \
    	    -e s/macppc/powerpc/\
    	    -e s/sh.*/sh/)
    # HOSTARCH用于保存主机架构,调用uname-m 为x86_64
    # |是将左边的输出作为右边的输入
    # sed -e s/i.86/x86/    sed -e s将输入的i.86替换为x86
    
    HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
    	    sed -e 's/\(cygwin\).*/cygwin/')
    # 用于保存主机OS的值,使用uname -s来获取主机os
    # uname -s 为linux
    # 将"Linux"作为后面tr '[:upper:]' '[:lower:]'的输入,tr '[:upper:]' '[:lower:]'表示将所有的大写字母替换为小写字母,最后得到linux
    # 将linux作为 sed -e 's/\(cygwin\).*/cygwin/' 的输入,用于将cygwin.* 替换为cygwin
    
    # HOSTARCH=x86_64,HOSTOS=linux
    
    export	HOSTARCH HOSTOS
    
    #########################################################################
    # 设置ARCH 和CROSS_COMPILE
    
    # set default to nothing for native builds
    ifeq ($(HOSTARCH),$(ARCH))  
    # HOSTARCH是x86_64 ARCH是ARM
    CROSS_COMPILE ?=
    endif
    
    # ARCH ?= arm
    # CROSS_COMPILE ?= arm-linux-gnueabihf-
    
    KCONFIG_CONFIG	?= .config
    # 设置配置文件为.config,默认是没有的,使用命令 make xxx_defconfig对uboot进行配置
    # xxx_defconfig只是一些初始配置,而.config里面的才是实时有效的配置
    export KCONFIG_CONFIG
    
    # SHELL used by kbuild
    CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
    	  else if [ -x /bin/bash ]; then echo /bin/bash; \
    	  else echo sh; fi ; fi)
    
    HOSTCC       = cc
    HOSTCXX      = c++
    HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
    HOSTCXXFLAGS = -O2
    
    ifeq ($(HOSTOS),cygwin)
    HOSTCFLAGS	+= -ansi
    endif
    
    # Mac OS X / Darwin's C preprocessor is Apple specific.  It
    # generates numerous errors and warnings.  We want to bypass it
    # and use GNU C's cpp.	To do this we pass the -traditional-cpp
    # option to the compiler.  Note that the -traditional-cpp flag
    # DOES NOT have the same semantics as GNU C's flag, all it does
    # is invoke the GNU preprocessor in stock ANSI/ISO C fashion.
    #
    # Apple's linker is similar, thanks to the new 2 stage linking
    # multiple symbol definitions are treated as errors, hence the
    # -multiply_defined suppress option to turn off this error.
    #
    ifeq ($(HOSTOS),darwin)
    # get major and minor product version (e.g. '10' and '6' for Snow Leopard)
    DARWIN_MAJOR_VERSION	= $(shell sw_vers -productVersion | cut -f 1 -d '.')
    DARWIN_MINOR_VERSION	= $(shell sw_vers -productVersion | cut -f 2 -d '.')
    
    os_x_before	= $(shell if [ $(DARWIN_MAJOR_VERSION) -le $(1) -a \
    	$(DARWIN_MINOR_VERSION) -le $(2) ] ; then echo "$(3)"; else echo "$(4)"; fi ;)
    
    # Snow Leopards build environment has no longer restrictions as described above
    HOSTCC       = $(call os_x_before, 10, 5, "cc", "gcc")
    HOSTCFLAGS  += $(call os_x_before, 10, 4, "-traditional-cpp")
    HOSTLDFLAGS += $(call os_x_before, 10, 5, "-multiply_defined suppress")
    
    # since Lion (10.7) ASLR is on by default, but we use linker generated lists
    # in some host tools which is a problem then ... so disable ASLR for these
    # tools
    HOSTLDFLAGS += $(call os_x_before, 10, 7, "", "-Xlinker -no_pie")
    endif
    
    # Decide whether to build built-in, modular, or both.
    # Normally, just do built-in.
    
    KBUILD_MODULES :=
    KBUILD_BUILTIN := 1
    
    # If we have only "make modules", don't compile built-in objects.
    # When we're building modules with modversions, we need to consider
    # the built-in objects during the descend as well, in order to
    # make sure the checksums are up to date before we record them.
    
    ifeq ($(MAKECMDGOALS),modules)
      KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
    endif
    
    # If we have "make  modules", compile modules
    # in addition to whatever we do anyway.
    # Just "make" or "make all" shall build modules as well
    
    # U-Boot does not need modules
    #ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
    #  KBUILD_MODULES := 1
    #endif
    
    #ifeq ($(MAKECMDGOALS),)
    #  KBUILD_MODULES := 1
    #endif
    
    export KBUILD_MODULES KBUILD_BUILTIN
    export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
    
    # 调用scripts/Kbuild.include 这个文件,这个里面有很多变量
    # We need some generic definitions (do not try to remake the file).
    scripts/Kbuild.include: ;
    include scripts/Kbuild.include
    
    # 交叉编译工具变量设置
    # Make variables (CC, etc...)
    
    AS		= $(CROSS_COMPILE)as
    # Always use GNU ld
    ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)
    LD		= $(CROSS_COMPILE)ld.bfd
    else
    LD		= $(CROSS_COMPILE)ld
    endif
    CC		= $(CROSS_COMPILE)gcc
    CPP		= $(CC) -E
    AR		= $(CROSS_COMPILE)ar
    NM		= $(CROSS_COMPILE)nm
    LDR		= $(CROSS_COMPILE)ldr
    STRIP		= $(CROSS_COMPILE)strip
    OBJCOPY		= $(CROSS_COMPILE)objcopy
    OBJDUMP		= $(CROSS_COMPILE)objdump
    AWK		= awk
    PERL		= perl
    PYTHON		= python
    DTC		= dtc
    CHECK		= sparse
    
    CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
    		  -Wbitwise -Wno-return-void -D__CHECK_ENDIAN__ $(CF)
    
    KBUILD_CPPFLAGS := -D__KERNEL__ -D__UBOOT__
    
    KBUILD_CFLAGS   := -Wall -Wstrict-prototypes \
    		   -Wno-format-security \
    		   -fno-builtin -ffreestanding
    KBUILD_AFLAGS   := -D__ASSEMBLY__
    
    # Read UBOOTRELEASE from include/config/uboot.release (if it exists)
    UBOOTRELEASE = $(shell cat include/config/uboot.release 2> /dev/null)
    UBOOTVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
    
    # 导出很多变量
    export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION
    export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR
    # 这7个变量在其他文件里面定义的,在config.mk中定义的
    # ARCH = arm 
    # CPU = armv7 
    # BOARD = mx6ullevk 
    # VENDOR = freescale 
    # SOC = mx6 
    # CPUDIR = arch/arm/cpu/armv7 
    # BOARDDIR = freescale/mx6ullevk 
    
    export CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS LD CC
    export CPP AR NM LDR STRIP OBJCOPY OBJDUMP
    export MAKE AWK PERL PYTHON
    export HOSTCXX HOSTCXXFLAGS DTC CHECK CHECKFLAGS
    
    export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS
    export KBUILD_CFLAGS KBUILD_AFLAGS
    
    # When compiling out-of-tree modules, put MODVERDIR in the module
    # tree rather than in the kernel tree. The kernel tree might
    # even be read-only.
    export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions
    
    # Files to ignore in find ... statements
    
    export RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o    \
    			  -name CVS -o -name .pc -o -name .hg -o -name .git \) \
    			  -prune -o
    export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn \
    			 --exclude CVS --exclude .pc --exclude .hg --exclude .git
    
    # ===========================================================================
    # Rules shared between *config targets and build targets
    
    # Basic helpers built in scripts/
    PHONY += scripts_basic
    scripts_basic:
    	$(Q)$(MAKE) $(build)=scripts/basic
    	$(Q)rm -f .tmp_quiet_recordmcount
    
    # To avoid any implicit rule to kick in, define an empty command.
    scripts/basic/%: scripts_basic ;
    
    PHONY += outputmakefile
    # outputmakefile generates a Makefile in the output directory, if using a
    # separate output directory. This allows convenient use of make in the
    # output directory.
    outputmakefile:
    ifneq ($(KBUILD_SRC),)
    	$(Q)ln -fsn $(srctree) source
    	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
    	    $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
    endif
    
    
    # make xxx_defconfig命令来配置uboot
    # To make sure we do not include .config for any of the *config targets
    # catch them early, and hand them over to scripts/kconfig/Makefile
    # It is allowed to specify more targets when calling make, including
    # mixing *config targets and build targets.
    # For example 'make oldconfig all'.
    # Detect when mixed targets is specified, and make a second invocation
    # of make so .config is not included in this case either (for *config).
    
    version_h := include/generated/version_autogenerated.h
    # 保存版本号文件,这个文件是自动生成的
    timestamp_h := include/generated/timestamp_autogenerated.h
    # 保存时间戳文件
    
    no-dot-config-targets := clean clobber mrproper distclean \
    			 help %docs check% coccicheck \
    			 ubootversion backup
    
    config-targets := 0
    mixed-targets  := 0
    dot-config     := 1
    
    ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
    	ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
    		dot-config := 0
    	endif
    endif
    # 将 MAKECMDGOALS中不符合 no-dot-config-targets的部分过滤掉,剩下的如果不为空的话条件就成立。MAKECMDGOALS是 make的一个环境变量,这个变量会保存你所指定的终极目标列表,比如执行“make mx6ull_alientek_emmc_defconfig” ,那么 MAKECMDGOALS就为 mx6ull_alientek_emmc_defconfig。很明显过滤后为空,所以条件不成立,变量 dot-config依旧为 1。 
    
    ifeq ($(KBUILD_EXTMOD),)
            ifneq ($(filter config %config,$(MAKECMDGOALS)),)
                    config-targets := 1
                    ifneq ($(words $(MAKECMDGOALS)),1)
                    # 使用words来统计单词个数
                            mixed-targets := 1
                    endif
            endif
    endif
    
    ifeq ($(mixed-targets),1)
    # ===========================================================================
    # We're called with mixed targets (*config and build targets).
    # Handle them one by one.
    
    PHONY += $(MAKECMDGOALS) __build_one_by_one
    
    $(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one
    	@:
    
    __build_one_by_one:
    	$(Q)set -e; \
    	for i in $(MAKECMDGOALS); do \
    		$(MAKE) -f $(srctree)/Makefile $$i; \
    	done
    
    else
    ifeq ($(config-targets),1)
    # ===========================================================================
    # *config targets only - make sure prerequisites are updated, and descend
    # in scripts/kconfig to make the *config target
    
    KBUILD_DEFCONFIG := sandbox_defconfig
    export KBUILD_DEFCONFIG KBUILD_KCONFIG
    
    config: scripts_basic outputmakefile FORCE
    	$(Q)$(MAKE) $(build)=scripts/kconfig $@
    
    %config: scripts_basic outputmakefile FORCE
    	$(Q)$(MAKE) $(build)=scripts/kconfig $@
    
    else
    # ===========================================================================
    # Build targets only - this includes vmlinux, arch specific targets, clean
    # targets and others. In general all targets except *config targets.
    
    ifeq ($(dot-config),1)
    # Read in config
    -include include/config/auto.conf
    
    # Read in dependencies to all Kconfig* files, make sure to run
    # oldconfig if changes are detected.
    -include include/config/auto.conf.cmd
    
    # To avoid any implicit rule to kick in, define an empty command
    $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
    
    # If .config is newer than include/config/auto.conf, someone tinkered
    # with it and forgot to run make oldconfig.
    # if auto.conf.cmd is missing then we are probably in a cleaned tree so
    # we execute the config step to be sure to catch updated Kconfig files
    include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
    	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
    	@# If the following part fails, include/config/auto.conf should be
    	@# deleted so "make silentoldconfig" will be re-run on the next build.
    	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \
    		{ rm -f include/config/auto.conf; false; }
    	@# include/config.h has been updated after "make silentoldconfig".
    	@# We need to touch include/config/auto.conf so it gets newer
    	@# than include/config.h.
    	@# Otherwise, 'make silentoldconfig' would be invoked twice.
    	$(Q)touch include/config/auto.conf
    
    -include include/autoconf.mk
    -include include/autoconf.mk.dep
    
    # We want to include arch/$(ARCH)/config.mk only when include/config/auto.conf
    # is up-to-date. When we switch to a different board configuration, old CONFIG
    # macros are still remaining in include/config/auto.conf. Without the following
    # gimmick, wrong config.mk would be included leading nasty warnings/errors.
    ifneq ($(wildcard $(KCONFIG_CONFIG)),)
    ifneq ($(wildcard include/config/auto.conf),)
    autoconf_is_old := $(shell find . -path ./$(KCONFIG_CONFIG) -newer \
    						include/config/auto.conf)
    ifeq ($(autoconf_is_old),)
    include config.mk
    include arch/$(ARCH)/Makefile
    endif
    endif
    endif
    
    # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
    # that (or fail if absent).  Otherwise, search for a linker script in a
    # standard location.
    
    ifndef LDSCRIPT
    	#LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds.debug
    	ifdef CONFIG_SYS_LDSCRIPT
    		# need to strip off double quotes
    		LDSCRIPT := $(srctree)/$(CONFIG_SYS_LDSCRIPT:"%"=%)
    	endif
    endif
    
    # If there is no specified link script, we look in a number of places for it
    ifndef LDSCRIPT
    	ifeq ($(wildcard $(LDSCRIPT)),)
    		LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds
    	endif
    	ifeq ($(wildcard $(LDSCRIPT)),)
    		LDSCRIPT := $(srctree)/$(CPUDIR)/u-boot.lds
    	endif
    	ifeq ($(wildcard $(LDSCRIPT)),)
    		LDSCRIPT := $(srctree)/arch/$(ARCH)/cpu/u-boot.lds
    	endif
    endif
    
    else
    # Dummy target needed, because used as prerequisite
    include/config/auto.conf: ;
    endif # $(dot-config)
    
    ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
    KBUILD_CFLAGS	+= -Os
    else
    KBUILD_CFLAGS	+= -O2
    endif
    
    KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
    KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks)
    
    KBUILD_CFLAGS	+= -g
    # $(KBUILD_AFLAGS) sets -g, which causes gcc to pass a suitable -g
    # option to the assembler.
    KBUILD_AFLAGS	+= -g
    
    # Report stack usage if supported
    ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-stack-usage.sh $(CC)),y)
    	KBUILD_CFLAGS += -fstack-usage
    endif
    
    KBUILD_CFLAGS += $(call cc-option,-Wno-format-nonliteral)
    
    # turn jbsr into jsr for m68k
    ifeq ($(ARCH),m68k)
    ifeq ($(findstring 3.4,$(shell $(CC) --version)),3.4)
    KBUILD_AFLAGS += -Wa,-gstabs,-S
    endif
    endif
    
    # Prohibit date/time macros, which would make the build non-deterministic
    KBUILD_CFLAGS   += $(call cc-option,-Werror=date-time)
    
    include scripts/Makefile.extrawarn
    
    # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
    KBUILD_CPPFLAGS += $(KCPPFLAGS)
    KBUILD_AFLAGS += $(KAFLAGS)
    KBUILD_CFLAGS += $(KCFLAGS)
    
    # Use UBOOTINCLUDE when you must reference the include/ directory.
    # Needed to be compatible with the O= option
    UBOOTINCLUDE    := \
    		-Iinclude \
    		$(if $(KBUILD_SRC), -I$(srctree)/include) \
    		$(if $(CONFIG_SYS_THUMB_BUILD), $(if $(CONFIG_HAS_THUMB2),, \
    			-I$(srctree)/arch/$(ARCH)/thumb1/include),) \
    		-I$(srctree)/arch/$(ARCH)/include \
    		-include $(srctree)/include/linux/kconfig.h
    
    NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
    CHECKFLAGS     += $(NOSTDINC_FLAGS)
    
    # FIX ME
    cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \
    							$(NOSTDINC_FLAGS)
    c_flags := $(KBUILD_CFLAGS) $(cpp_flags)
    
    #########################################################################
    # U-Boot objects....order is important (i.e. start must be first)
    
    HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makefile),y,n)
    
    libs-y += lib/
    libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
    libs-$(CONFIG_OF_EMBED) += dts/
    libs-y += fs/
    libs-y += net/
    libs-y += disk/
    libs-y += drivers/
    libs-y += drivers/dma/
    libs-y += drivers/gpio/
    libs-y += drivers/i2c/
    libs-y += drivers/mmc/
    libs-y += drivers/mtd/
    libs-$(CONFIG_CMD_NAND) += drivers/mtd/nand/
    libs-y += drivers/mtd/onenand/
    libs-$(CONFIG_CMD_UBI) += drivers/mtd/ubi/
    libs-y += drivers/mtd/spi/
    libs-y += drivers/net/
    libs-y += drivers/net/phy/
    libs-y += drivers/pci/
    libs-y += drivers/power/ \
    	drivers/power/fuel_gauge/ \
    	drivers/power/mfd/ \
    	drivers/power/pmic/ \
    	drivers/power/battery/ \
    	drivers/power/regulator/
    libs-y += drivers/spi/
    libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/
    libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/
    libs-$(CONFIG_ALTERA_SDRAM) += drivers/ddr/altera/
    libs-y += drivers/serial/
    libs-y += drivers/usb/dwc3/
    libs-y += drivers/usb/emul/
    libs-y += drivers/usb/eth/
    libs-y += drivers/usb/gadget/
    libs-y += drivers/usb/gadget/udc/
    libs-y += drivers/usb/host/
    libs-y += drivers/usb/musb/
    libs-y += drivers/usb/musb-new/
    libs-y += drivers/usb/phy/
    libs-y += drivers/usb/ulpi/
    libs-y += cmd/
    libs-y += common/
    libs-$(CONFIG_API) += api/
    libs-$(CONFIG_HAS_POST) += post/
    libs-y += test/
    libs-y += test/dm/
    libs-$(CONFIG_UT_ENV) += test/env/
    
    libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
    
    libs-y := $(sort $(libs-y))
    
    u-boot-dirs	:= $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples
    
    u-boot-alldirs	:= $(sort $(u-boot-dirs) $(patsubst %/,%,$(filter %/, $(libs-))))
    
    libs-y		:= $(patsubst %/, %/built-in.o, $(libs-y))
    
    u-boot-init := $(head-y)
    u-boot-main := $(libs-y)
    
    
    # Add GCC lib
    ifeq ($(CONFIG_USE_PRIVATE_LIBGCC),y)
    PLATFORM_LIBGCC = arch/$(ARCH)/lib/lib.a
    else
    PLATFORM_LIBGCC := -L $(shell dirname `$(CC) $(c_flags) -print-libgcc-file-name`) -lgcc
    endif
    PLATFORM_LIBS += $(PLATFORM_LIBGCC)
    export PLATFORM_LIBS
    export PLATFORM_LIBGCC
    
    # Special flags for CPP when processing the linker script.
    # Pass the version down so we can handle backwards compatibility
    # on the fly.
    LDPPFLAGS += \
    	-include $(srctree)/include/u-boot/u-boot.lds.h \
    	-DCPUDIR=$(CPUDIR) \
    	$(shell $(LD) --version | \
    	  sed -ne 's/GNU ld version \([0-9][0-9]*\)\.\([0-9][0-9]*\).*/-DLD_MAJOR=\1 -DLD_MINOR=\2/p')
    
    #########################################################################
    #########################################################################
    
    ifneq ($(CONFIG_BOARD_SIZE_LIMIT),)
    BOARD_SIZE_CHECK = \
    	@actual=`wc -c $@ | awk '{print $$1}'`; \
    	limit=`printf "%d" $(CONFIG_BOARD_SIZE_LIMIT)`; \
    	if test $$actual -gt $$limit; then \
    		echo "$@ exceeds file size limit:" >&2 ; \
    		echo "  limit:  $$limit bytes" >&2 ; \
    		echo "  actual: $$actual bytes" >&2 ; \
    		echo "  excess: $$((actual - limit)) bytes" >&2; \
    		exit 1; \
    	fi
    else
    BOARD_SIZE_CHECK =
    endif
    
    # Statically apply RELA-style relocations (currently arm64 only)
    ifneq ($(CONFIG_STATIC_RELA),)
    # $(1) is u-boot ELF, $(2) is u-boot bin, $(3) is text base
    DO_STATIC_RELA = \
    	start=$$($(NM) $(1) | grep __rel_dyn_start | cut -f 1 -d ' '); \
    	end=$$($(NM) $(1) | grep __rel_dyn_end | cut -f 1 -d ' '); \
    	tools/relocate-rela $(2) $(3) $$start $$end
    else
    DO_STATIC_RELA =
    endif
    
    # Always append ALL so that arch config.mk's can add custom ones
    ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg binary_size_check
    
    ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin
    ifeq ($(CONFIG_SPL_FSL_PBL),y)
    ALL-$(CONFIG_RAMBOOT_PBL) += u-boot-with-spl-pbl.bin
    else
    ifneq ($(CONFIG_SECURE_BOOT), y)
    # For Secure Boot The Image needs to be signed and Header must also
    # be included. So The image has to be built explicitly
    ALL-$(CONFIG_RAMBOOT_PBL) += u-boot.pbl
    endif
    endif
    ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin
    ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img
    ALL-$(CONFIG_TPL) += tpl/u-boot-tpl.bin
    ALL-$(CONFIG_OF_SEPARATE) += u-boot.dtb
    ifeq ($(CONFIG_SPL_FRAMEWORK),y)
    ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb.img
    endif
    ALL-$(CONFIG_OF_HOSTFILE) += u-boot.dtb
    ifneq ($(CONFIG_SPL_TARGET),)
    ALL-$(CONFIG_SPL) += $(CONFIG_SPL_TARGET:"%"=%)
    endif
    ALL-$(CONFIG_REMAKE_ELF) += u-boot.elf
    ALL-$(CONFIG_EFI_APP) += u-boot-app.efi
    ALL-$(CONFIG_EFI_STUB) += u-boot-payload.efi
    
    ifneq ($(BUILD_ROM),)
    ALL-$(CONFIG_X86_RESET_VECTOR) += u-boot.rom
    endif
    
    # enable combined SPL/u-boot/dtb rules for tegra
    ifeq ($(CONFIG_TEGRA)$(CONFIG_SPL),yy)
    ALL-y += u-boot-tegra.bin u-boot-nodtb-tegra.bin
    ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb-tegra.bin
    endif
    
    # Add optional build target if defined in board/cpu/soc headers
    ifneq ($(CONFIG_BUILD_TARGET),)
    ALL-y += $(CONFIG_BUILD_TARGET:"%"=%)
    endif
    
    LDFLAGS_u-boot += $(LDFLAGS_FINAL)
    ifneq ($(CONFIG_SYS_TEXT_BASE),)
    LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE)
    endif
    
    # Normally we fill empty space with 0xff
    quiet_cmd_objcopy = OBJCOPY $@
    cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
    	$(OBJCOPYFLAGS_$(@F)) $< $@
    
    # Provide a version which does not do this, for use by EFI
    quiet_cmd_zobjcopy = OBJCOPY $@
    cmd_zobjcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
    
    quiet_cmd_efipayload = OBJCOPY $@
    cmd_efipayload = $(OBJCOPY) -I binary -O $(EFIPAYLOAD_BFDTARGET) -B $(EFIPAYLOAD_BFDARCH) $< $@
    
    quiet_cmd_mkimage = MKIMAGE $@
    cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \
    	$(if $(KBUILD_VERBOSE:1=), >/dev/null)
    
    quiet_cmd_cat = CAT     $@
    cmd_cat = cat $(filter-out $(PHONY), $^) > $@
    
    append = cat $(filter-out $< $(PHONY), $^) >> $@
    
    quiet_cmd_pad_cat = CAT     $@
    cmd_pad_cat = $(cmd_objcopy) && $(append) || rm -f $@
    
    all:		$(ALL-y)
    ifneq ($(CONFIG_SYS_GENERIC_BOARD),y)
    	@echo "===================== WARNING ======================"
    	@echo "Please convert this board to generic board."
    	@echo "Otherwise it will be removed by the end of 2014."
    	@echo "See doc/README.generic-board for further information"
    	@echo "===================================================="
    endif
    ifeq ($(CONFIG_DM_I2C_COMPAT),y)
    	@echo "===================== WARNING ======================"
    	@echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove"
    	@echo "(possibly in a subsequent patch in your series)"
    	@echo "before sending patches to the mailing list."
    	@echo "===================================================="
    endif
    
    PHONY += dtbs
    dtbs dts/dt.dtb: checkdtc u-boot
    	$(Q)$(MAKE) $(build)=dts dtbs
    
    quiet_cmd_copy = COPY    $@
          cmd_copy = cp $< $@
    
    ifeq ($(CONFIG_OF_SEPARATE),y)
    u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE
    	$(call if_changed,cat)
    
    u-boot.bin: u-boot-dtb.bin FORCE
    	$(call if_changed,copy)
    else
    u-boot.bin: u-boot-nodtb.bin FORCE
    	$(call if_changed,copy)
    endif
    
    %.imx: %.bin
    	$(Q)$(MAKE) $(build)=arch/arm/imx-common $@
    
    u-boot.dtb: dts/dt.dtb
    	$(call cmd,copy)
    
    OBJCOPYFLAGS_u-boot.hex := -O ihex
    
    OBJCOPYFLAGS_u-boot.srec := -O srec
    
    u-boot.hex u-boot.srec: u-boot FORCE
    	$(call if_changed,objcopy)
    
    OBJCOPYFLAGS_u-boot-nodtb.bin := -O binary \
    		$(if $(CONFIG_X86_RESET_VECTOR),-R .start16 -R .resetvec)
    
    binary_size_check: u-boot-nodtb.bin FORCE
    	@file_size=$(shell wc -c u-boot-nodtb.bin | awk '{print $$1}') ; \
    	map_size=$(shell cat u-boot.map | \
    		awk '/_image_copy_start/ {start = $$1} /_image_binary_end/ {end = $$1} END {if (start != "" && end != "") print "ibase=16; " toupper(end) " - " toupper(start)}' \
    		| sed 's/0X//g' \
    		| bc); \
    	if [ "" != "$$map_size" ]; then \
    		if test $$map_size -ne $$file_size; then \
    			echo "u-boot.map shows a binary size of $$map_size" >&2 ; \
    			echo "  but u-boot-nodtb.bin shows $$file_size" >&2 ; \
    			exit 1; \
    		fi \
    	fi
    
    u-boot-nodtb.bin: u-boot FORCE
    	$(call if_changed,objcopy)
    	$(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))
    	$(BOARD_SIZE_CHECK)
    
    u-boot.ldr:	u-boot
    		$(CREATE_LDR_ENV)
    		$(LDR) -T $(CONFIG_CPU) -c $@ $< $(LDR_FLAGS)
    		$(BOARD_SIZE_CHECK)
    
    OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex
    
    OBJCOPYFLAGS_u-boot.ldr.srec := -I binary -O srec
    
    u-boot.ldr.hex u-boot.ldr.srec: u-boot.ldr FORCE
    	$(call if_changed,objcopy)
    
    #
    # U-Boot entry point, needed for booting of full-blown U-Boot
    # from the SPL U-Boot version.
    #
    ifndef CONFIG_SYS_UBOOT_START
    CONFIG_SYS_UBOOT_START := 0
    endif
    
    # Create a file containing the configuration options the image was built with
    quiet_cmd_cpp_cfg = CFG     $@
    cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
    	-DDO_DEPS_ONLY -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $<
    
    MKIMAGEFLAGS_u-boot.img = -A $(ARCH) -T firmware -C none -O u-boot \
    	-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
    	-n "U-Boot $(UBOOTRELEASE) for $(BOARD) board"
    
    MKIMAGEFLAGS_u-boot-dtb.img = $(MKIMAGEFLAGS_u-boot.img)
    
    MKIMAGEFLAGS_u-boot.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \
    	-T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)
    
    MKIMAGEFLAGS_u-boot-spl.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \
    	-T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)
    
    MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
    		-R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage
    
    u-boot-dtb.img u-boot.img u-boot.kwb u-boot.pbl: u-boot.bin FORCE
    	$(call if_changed,mkimage)
    
    u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE
    	$(call if_changed,mkimage)
    
    u-boot.sha1:	u-boot.bin
    		tools/ubsha1 u-boot.bin
    
    u-boot.dis:	u-boot
    		$(OBJDUMP) -d $< > $@
    
    u-boot.cfg:	include/config.h FORCE
    	$(call if_changed,cpp_cfg)
    
    ifdef CONFIG_TPL
    SPL_PAYLOAD := tpl/u-boot-with-tpl.bin
    else
    SPL_PAYLOAD := u-boot.bin
    endif
    
    OBJCOPYFLAGS_u-boot-with-spl.bin = -I binary -O binary \
    				   --pad-to=$(CONFIG_SPL_PAD_TO)
    u-boot-with-spl.bin: spl/u-boot-spl.bin $(SPL_PAYLOAD) FORCE
    	$(call if_changed,pad_cat)
    
    MKIMAGEFLAGS_lpc32xx-spl.img = -T lpc32xximage -a $(CONFIG_SPL_TEXT_BASE)
    
    lpc32xx-spl.img: spl/u-boot-spl.bin FORCE
    	$(call if_changed,mkimage)
    
    OBJCOPYFLAGS_lpc32xx-boot-0.bin = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO)
    
    lpc32xx-boot-0.bin: lpc32xx-spl.img FORCE
    	$(call if_changed,objcopy)
    
    OBJCOPYFLAGS_lpc32xx-boot-1.bin = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO)
    
    lpc32xx-boot-1.bin: lpc32xx-spl.img FORCE
    	$(call if_changed,objcopy)
    
    lpc32xx-full.bin: lpc32xx-boot-0.bin lpc32xx-boot-1.bin u-boot.img FORCE
    	$(call if_changed,cat)
    
    CLEAN_FILES += lpc32xx-*
    
    OBJCOPYFLAGS_u-boot-with-tpl.bin = -I binary -O binary \
    				   --pad-to=$(CONFIG_TPL_PAD_TO)
    tpl/u-boot-with-tpl.bin: tpl/u-boot-tpl.bin u-boot.bin FORCE
    	$(call if_changed,pad_cat)
    
    SPL: spl/u-boot-spl.bin FORCE
    	$(Q)$(MAKE) $(build)=arch/arm/imx-common $@
    
    u-boot-with-spl.imx u-boot-with-nand-spl.imx: SPL u-boot.bin FORCE
    	$(Q)$(MAKE) $(build)=arch/arm/imx-common $@
    
    MKIMAGEFLAGS_u-boot.ubl = -n $(UBL_CONFIG) -T ublimage -e $(CONFIG_SYS_TEXT_BASE)
    
    u-boot.ubl: u-boot-with-spl.bin FORCE
    	$(call if_changed,mkimage)
    
    MKIMAGEFLAGS_u-boot-spl.ais = -s -n $(if $(CONFIG_AIS_CONFIG_FILE), \
    	$(srctree)/$(CONFIG_AIS_CONFIG_FILE:"%"=%),"/dev/null") \
    	-T aisimage -e $(CONFIG_SPL_TEXT_BASE)
    spl/u-boot-spl.ais: spl/u-boot-spl.bin FORCE
    	$(call if_changed,mkimage)
    
    OBJCOPYFLAGS_u-boot.ais = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO)
    u-boot.ais: spl/u-boot-spl.ais u-boot.img FORCE
    	$(call if_changed,pad_cat)
    
    u-boot-signed.sb: u-boot.bin spl/u-boot-spl.bin
    	$(Q)$(MAKE) $(build)=arch/arm/cpu/arm926ejs/mxs u-boot-signed.sb
    u-boot.sb: u-boot.bin spl/u-boot-spl.bin
    	$(Q)$(MAKE) $(build)=arch/arm/cpu/arm926ejs/mxs u-boot.sb
    
    # On x600 (SPEAr600) U-Boot is appended to U-Boot SPL.
    # Both images are created using mkimage (crc etc), so that the ROM
    # bootloader can check its integrity. Padding needs to be done to the
    # SPL image (with mkimage header) and not the binary. Otherwise the resulting image
    # which is loaded/copied by the ROM bootloader to SRAM doesn't fit.
    # The resulting image containing both U-Boot images is called u-boot.spr
    MKIMAGEFLAGS_u-boot-spl.img = -A $(ARCH) -T firmware -C none \
    	-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) -n XLOADER
    spl/u-boot-spl.img: spl/u-boot-spl.bin FORCE
    	$(call if_changed,mkimage)
    
    OBJCOPYFLAGS_u-boot.spr = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \
    			  --gap-fill=0xff
    u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE
    	$(call if_changed,pad_cat)
    
    ifneq ($(CONFIG_ARCH_SOCFPGA),)
    quiet_cmd_socboot = SOCBOOT $@
    cmd_socboot = cat	spl/u-boot-spl.sfp spl/u-boot-spl.sfp	\
    			spl/u-boot-spl.sfp spl/u-boot-spl.sfp	\
    			u-boot.img > $@ || rm -f $@
    u-boot-with-spl.sfp: spl/u-boot-spl.sfp u-boot.img FORCE
    	$(call if_changed,socboot)
    endif
    
    # x86 uses a large ROM. We fill it with 0xff, put the 16-bit stuff (including
    # reset vector) at the top, Intel ME descriptor at the bottom, and U-Boot in
    # the middle.
    ifneq ($(CONFIG_X86_RESET_VECTOR),)
    rom: u-boot.rom FORCE
    
    IFDTOOL=$(objtree)/tools/ifdtool
    IFDTOOL_FLAGS  = -f 0:$(objtree)/u-boot.dtb
    IFDTOOL_FLAGS += -m 0x$(shell $(NM) u-boot |grep _dt_ucode_base_size |cut -d' ' -f1)
    IFDTOOL_FLAGS += -U $(CONFIG_SYS_TEXT_BASE):$(objtree)/u-boot-nodtb.bin
    IFDTOOL_FLAGS += -w $(CONFIG_SYS_X86_START16):$(objtree)/u-boot-x86-16bit.bin
    IFDTOOL_FLAGS += -C
    
    ifneq ($(CONFIG_HAVE_INTEL_ME),)
    IFDTOOL_ME_FLAGS  = -D $(srctree)/board/$(BOARDDIR)/descriptor.bin
    IFDTOOL_ME_FLAGS += -i ME:$(srctree)/board/$(BOARDDIR)/me.bin
    endif
    
    ifneq ($(CONFIG_HAVE_MRC),)
    IFDTOOL_FLAGS += -w $(CONFIG_X86_MRC_ADDR):$(srctree)/board/$(BOARDDIR)/mrc.bin
    endif
    
    ifneq ($(CONFIG_HAVE_FSP),)
    IFDTOOL_FLAGS += -w $(CONFIG_FSP_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_FSP_FILE)
    endif
    
    ifneq ($(CONFIG_HAVE_CMC),)
    IFDTOOL_FLAGS += -w $(CONFIG_CMC_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_CMC_FILE)
    endif
    
    ifneq ($(CONFIG_HAVE_VGA_BIOS),)
    IFDTOOL_FLAGS += -w $(CONFIG_VGA_BIOS_ADDR):$(srctree)/board/$(BOARDDIR)/$(CONFIG_VGA_BIOS_FILE)
    endif
    
    quiet_cmd_ifdtool = IFDTOOL $@
    cmd_ifdtool  = $(IFDTOOL) -c -r $(CONFIG_ROM_SIZE) u-boot.tmp;
    ifneq ($(CONFIG_HAVE_INTEL_ME),)
    cmd_ifdtool += $(IFDTOOL) $(IFDTOOL_ME_FLAGS) u-boot.tmp;
    endif
    cmd_ifdtool += $(IFDTOOL) $(IFDTOOL_FLAGS) u-boot.tmp;
    cmd_ifdtool += mv u-boot.tmp $@
    
    u-boot.rom: u-boot-x86-16bit.bin u-boot.bin FORCE
    	$(call if_changed,ifdtool)
    
    OBJCOPYFLAGS_u-boot-x86-16bit.bin := -O binary -j .start16 -j .resetvec
    u-boot-x86-16bit.bin: u-boot FORCE
    	$(call if_changed,objcopy)
    endif
    
    ifneq ($(CONFIG_SUNXI),)
    OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \
    				   --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff
    u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img FORCE
    	$(call if_changed,pad_cat)
    endif
    
    ifneq ($(CONFIG_TEGRA),)
    OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE)
    u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot-nodtb.bin FORCE
    	$(call if_changed,pad_cat)
    
    OBJCOPYFLAGS_u-boot-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE)
    u-boot-tegra.bin: spl/u-boot-spl u-boot.bin FORCE
    	$(call if_changed,pad_cat)
    
    u-boot-dtb-tegra.bin: u-boot-tegra.bin FORCE
    	$(call if_changed,copy)
    endif
    
    OBJCOPYFLAGS_u-boot-app.efi := $(OBJCOPYFLAGS_EFI)
    u-boot-app.efi: u-boot FORCE
    	$(call if_changed,zobjcopy)
    
    u-boot.bin.o: u-boot.bin FORCE
    	$(call if_changed,efipayload)
    
    u-boot-payload.lds: $(LDSCRIPT_EFI) FORCE
    	$(call if_changed_dep,cpp_lds)
    
    # Rule to link the EFI payload which contains a stub and a U-Boot binary
    quiet_cmd_u-boot_payload ?= LD      $@
          cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
          -T u-boot-payload.lds arch/x86/cpu/call32.o \
          lib/efi/efi.o lib/efi/efi_stub.o u-boot.bin.o \
          $(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
    
    u-boot-payload: u-boot.bin.o u-boot-payload.lds FORCE
    	$(call if_changed,u-boot_payload)
    
    OBJCOPYFLAGS_u-boot-payload.efi := $(OBJCOPYFLAGS_EFI)
    u-boot-payload.efi: u-boot-payload FORCE
    	$(call if_changed,zobjcopy)
    
    u-boot-img.bin: spl/u-boot-spl.bin u-boot.img FORCE
    	$(call if_changed,cat)
    
    #Add a target to create boot binary having SPL binary in PBI format
    #concatenated with u-boot binary. It is need by PowerPC SoC having
    #internal SRAM <= 512KB.
    MKIMAGEFLAGS_u-boot-spl.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
    		-R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage \
    		-A $(ARCH) -a $(CONFIG_SPL_TEXT_BASE)
    
    spl/u-boot-spl.pbl: spl/u-boot-spl.bin FORCE
    	$(call if_changed,mkimage)
    
    ifeq ($(ARCH),arm)
    UBOOT_BINLOAD := u-boot.img
    else
    UBOOT_BINLOAD := u-boot.bin
    endif
    
    OBJCOPYFLAGS_u-boot-with-spl-pbl.bin = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO) \
    			  --gap-fill=0xff
    
    u-boot-with-spl-pbl.bin: spl/u-boot-spl.pbl $(UBOOT_BINLOAD) FORCE
    	$(call if_changed,pad_cat)
    
    # PPC4xx needs the SPL at the end of the image, since the reset vector
    # is located at 0xfffffffc. So we can't use the "u-boot-img.bin" target
    # and need to introduce a new build target with the full blown U-Boot
    # at the start padded up to the start of the SPL image. And then concat
    # the SPL image to the end.
    
    OBJCOPYFLAGS_u-boot-img-spl-at-end.bin := -I binary -O binary \
    	--pad-to=$(CONFIG_UBOOT_PAD_TO) --gap-fill=0xff
    u-boot-img-spl-at-end.bin: u-boot.img spl/u-boot-spl.bin FORCE
    	$(call if_changed,pad_cat)
    
    # Create a new ELF from a raw binary file.  This is useful for arm64
    # where static relocation needs to be performed on the raw binary,
    # but certain simulators only accept an ELF file (but don't do the
    # relocation).
    # FIXME refactor dts/Makefile to share target/arch detection
    u-boot.elf: u-boot.bin
    	@$(OBJCOPY)  -B aarch64 -I binary -O elf64-littleaarch64 \
    		$< u-boot-elf.o
    	@$(LD) u-boot-elf.o -o $@ \
    		--defsym=_start=$(CONFIG_SYS_TEXT_BASE) \
    		-Ttext=$(CONFIG_SYS_TEXT_BASE)
    
    # Rule to link u-boot
    # May be overridden by arch/$(ARCH)/config.mk
    quiet_cmd_u-boot__ ?= LD      $@
          cmd_u-boot__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_u-boot) -o $@ \
          -T u-boot.lds $(u-boot-init)                             \
          --start-group $(u-boot-main) --end-group                 \
          $(PLATFORM_LIBS) -Map u-boot.map
    
    quiet_cmd_smap = GEN     common/system_map.o
    cmd_smap = \
    	smap=`$(call SYSTEM_MAP,u-boot) | \
    		awk '$$2 ~ /[tTwW]/ {printf $$1 $$3 "\\\\000"}'` ; \
    	$(CC) $(c_flags) -DSYSTEM_MAP="\"$${smap}\"" \
    		-c $(srctree)/common/system_map.c -o common/system_map.o
    
    u-boot:	$(u-boot-init) $(u-boot-main) u-boot.lds FORCE
    	$(call if_changed,u-boot__)
    ifeq ($(CONFIG_KALLSYMS),y)
    	$(call cmd,smap)
    	$(call cmd,u-boot__) common/system_map.o
    endif
    
    quiet_cmd_sym ?= SYM     $@
          cmd_sym ?= $(OBJDUMP) -t $< > $@
    u-boot.sym: u-boot FORCE
    	$(call if_changed,sym)
    
    # The actual objects are generated when descending,
    # make sure no implicit rule kicks in
    $(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ;
    
    # Handle descending into subdirectories listed in $(vmlinux-dirs)
    # Preset locale variables to speed up the build process. Limit locale
    # tweaks to this spot to avoid wrong language settings when running
    # make menuconfig etc.
    # Error messages still appears in the original language
    
    PHONY += $(u-boot-dirs)
    $(u-boot-dirs): prepare scripts
    	$(Q)$(MAKE) $(build)=$@
    
    tools: prepare
    # The "tools" are needed early
    $(filter-out tools, $(u-boot-dirs)): tools
    # The "examples" conditionally depend on U-Boot (say, when USE_PRIVATE_LIBGCC
    # is "yes"), so compile examples after U-Boot is compiled.
    examples: $(filter-out examples, $(u-boot-dirs))
    
    define filechk_uboot.release
    	echo "$(UBOOTVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))"
    endef
    
    # Store (new) UBOOTRELEASE string in include/config/uboot.release
    include/config/uboot.release: include/config/auto.conf FORCE
    	$(call filechk,uboot.release)
    
    
    # Things we need to do before we recursively start building the kernel
    # or the modules are listed in "prepare".
    # A multi level approach is used. prepareN is processed before prepareN-1.
    # archprepare is used in arch Makefiles and when processed asm symlink,
    # version.h and scripts_basic is processed / created.
    
    # Listed in dependency order
    PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
    
    # prepare3 is used to check if we are building in a separate output directory,
    # and if so do:
    # 1) Check that make has not been executed in the kernel src $(srctree)
    prepare3: include/config/uboot.release
    ifneq ($(KBUILD_SRC),)
    	@$(kecho) '  Using $(srctree) as source for U-Boot'
    	$(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \
    		echo >&2 "  $(srctree) is not clean, please run 'make mrproper'"; \
    		echo >&2 "  in the '$(srctree)' directory.";\
    		/bin/false; \
    	fi;
    endif
    
    # prepare2 creates a makefile if using a separate output directory
    prepare2: prepare3 outputmakefile
    
    prepare1: prepare2 $(version_h) $(timestamp_h) \
                       include/config/auto.conf
    ifeq ($(CONFIG_HAVE_GENERIC_BOARD),)
    ifeq ($(CONFIG_SYS_GENERIC_BOARD),y)
    	@echo >&2 "  Your architecture does not support generic board."
    	@echo >&2 "  Please undefine CONFIG_SYS_GENERIC_BOARD in your board config file."
    	@/bin/false
    endif
    endif
    ifeq ($(wildcard $(LDSCRIPT)),)
    	@echo >&2 "  Could not find linker script."
    	@/bin/false
    endif
    
    archprepare: prepare1 scripts_basic
    
    prepare0: archprepare FORCE
    	$(Q)$(MAKE) $(build)=.
    
    # All the preparing..
    prepare: prepare0
    
    # Generate some files
    # ---------------------------------------------------------------------------
    
    define filechk_version.h
    	(echo \#define PLAIN_VERSION \"$(UBOOTRELEASE)\"; \
    	echo \#define U_BOOT_VERSION \"U-Boot \" PLAIN_VERSION; \
    	echo \#define CC_VERSION_STRING \"$$($(CC) --version | head -n 1)\"; \
    	echo \#define LD_VERSION_STRING \"$$($(LD) --version | head -n 1)\"; )
    endef
    
    # The SOURCE_DATE_EPOCH mechanism requires a date that behaves like GNU date.
    # The BSD date on the other hand behaves different and would produce errors
    # with the misused '-d' switch.  Respect that and search a working date with
    # well known pre- and suffixes for the GNU variant of date.
    define filechk_timestamp.h
    	(if test -n "$${SOURCE_DATE_EPOCH}"; then \
    		SOURCE_DATE="@$${SOURCE_DATE_EPOCH}"; \
    		DATE=""; \
    		for date in gdate date.gnu date; do \
    			$${date} -u -d "$${SOURCE_DATE}" >/dev/null 2>&1 && DATE="$${date}"; \
    		done; \
    		if test -n "$${DATE}"; then \
    			LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DATE "%b %d %C%y"'; \
    			LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TIME "%T"'; \
    			LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TZ "%z"'; \
    			LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \
    		else \
    			return 42; \
    		fi; \
    	else \
    		LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \
    		LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \
    		LC_ALL=C date +'#define U_BOOT_TZ "%z"'; \
    		LC_ALL=C date +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \
    	fi)
    endef
    
    $(version_h): include/config/uboot.release FORCE
    	$(call filechk,version.h)
    
    $(timestamp_h): $(srctree)/Makefile FORCE
    	$(call filechk,timestamp.h)
    
    # ---------------------------------------------------------------------------
    quiet_cmd_cpp_lds = LDS     $@
    cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
    		-D__ASSEMBLY__ -x assembler-with-cpp -P -o $@ $<
    
    u-boot.lds: $(LDSCRIPT) prepare FORCE
    	$(call if_changed_dep,cpp_lds)
    
    spl/u-boot-spl.bin: spl/u-boot-spl
    	@:
    spl/u-boot-spl: tools prepare $(if $(CONFIG_OF_SEPARATE),dts/dt.dtb)
    	$(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
    
    spl/sunxi-spl.bin: spl/u-boot-spl
    	@:
    
    spl/u-boot-spl.sfp: spl/u-boot-spl
    	@:
    
    spl/boot.bin: spl/u-boot-spl
    	@:
    
    tpl/u-boot-tpl.bin: tools prepare
    	$(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all
    
    TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include)
    
    FIND := find
    FINDFLAGS := -L
    
    tags ctags:
    		ctags -w -o ctags `$(FIND) $(FINDFLAGS) $(TAG_SUBDIRS) \
    						-name '*.[chS]' -print`
    		ln -s ctags tags
    
    etags:
    		etags -a -o etags `$(FIND) $(FINDFLAGS) $(TAG_SUBDIRS) \
    						-name '*.[chS]' -print`
    cscope:
    		$(FIND) $(FINDFLAGS) $(TAG_SUBDIRS) -name '*.[chS]' -print > \
    						cscope.files
    		cscope -b -q -k
    
    SYSTEM_MAP = \
    		$(NM) $1 | \
    		grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
    		LC_ALL=C sort
    System.map:	u-boot
    		@$(call SYSTEM_MAP,$<) > $@
    
    checkdtc:
    	@if test $(call dtc-version) -lt 0104; then \
    		echo '*** Your dtc is too old, please upgrade to dtc 1.4 or newer'; \
    		false; \
    	fi
    
    #########################################################################
    
    # ARM relocations should all be R_ARM_RELATIVE (32-bit) or
    # R_AARCH64_RELATIVE (64-bit).
    checkarmreloc: u-boot
    	@RELOC="`$(CROSS_COMPILE)readelf -r -W $< | cut -d ' ' -f 4 | \
    		grep R_A | sort -u`"; \
    	if test "$$RELOC" != "R_ARM_RELATIVE" -a \
    		 "$$RELOC" != "R_AARCH64_RELATIVE"; then \
    		echo "$< contains unexpected relocations: $$RELOC"; \
    		false; \
    	fi
    
    env: scripts_basic
    	$(Q)$(MAKE) $(build)=tools/$@
    
    tools-only: scripts_basic $(version_h) $(timestamp_h)
    	$(Q)$(MAKE) $(build)=tools
    
    tools-all: export HOST_TOOLS_ALL=y
    tools-all: env tools ;
    
    cross_tools: export CROSS_BUILD_TOOLS=y
    cross_tools: tools ;
    
    .PHONY : CHANGELOG
    CHANGELOG:
    	git log --no-merges U-Boot-1_1_5.. | \
    	unexpand -a | sed -e 's/\s\s*$$//' > $@
    
    include/license.h: tools/bin2header COPYING
    	cat COPYING | gzip -9 -c | ./tools/bin2header license_gzip > include/license.h
    #########################################################################
    
    ###
    # Cleaning is done on three levels.
    # make clean     Delete most generated files
    #                Leave enough to build external modules
    # make mrproper  Delete the current configuration, and all generated files
    # make distclean Remove editor backup files, patch leftover files and the like
    
    # Directories & files removed with 'make clean'
    CLEAN_DIRS  += $(MODVERDIR) \
    	       $(foreach d, spl tpl, $(patsubst %,$d/%, \
    			$(filter-out include, $(shell ls -1 $d 2>/dev/null))))
    
    CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h \
    	       boot* u-boot* MLO* SPL System.map
    
    # Directories & files removed with 'make mrproper'
    MRPROPER_DIRS  += include/config include/generated spl tpl \
    		  .tmp_objdiff
    MRPROPER_FILES += .config .config.old include/autoconf.mk* include/config.h \
    		  ctags etags TAGS cscope* GPATH GTAGS GRTAGS GSYMS
    
    # clean - Delete most, but leave enough to build external modules
    #
    clean: rm-dirs  := $(CLEAN_DIRS)
    clean: rm-files := $(CLEAN_FILES)
    
    clean-dirs	:= $(foreach f,$(u-boot-alldirs),$(if $(wildcard $(srctree)/$f/Makefile),$f))
    
    clean-dirs      := $(addprefix _clean_, $(clean-dirs) doc/DocBook)
    
    PHONY += $(clean-dirs) clean archclean
    $(clean-dirs):
    	$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
    
    # TODO: Do not use *.cfgtmp
    clean: $(clean-dirs)
    	$(call cmd,rmdirs)
    	$(call cmd,rmfiles)
    	@find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \
    		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
    		-o -name '*.ko.*' -o -name '*.su' -o -name '*.cfgtmp' \
    		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
    		-o -name '*.symtypes' -o -name 'modules.order' \
    		-o -name modules.builtin -o -name '.tmp_*.o.*' \
    		-o -name '*.gcno' \) -type f -print | xargs rm -f
    
    # mrproper - Delete all generated files, including .config
    #
    mrproper: rm-dirs  := $(wildcard $(MRPROPER_DIRS))
    mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
    mrproper-dirs      := $(addprefix _mrproper_,scripts)
    
    PHONY += $(mrproper-dirs) mrproper archmrproper
    $(mrproper-dirs):
    	$(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
    
    mrproper: clean $(mrproper-dirs)
    	$(call cmd,rmdirs)
    	$(call cmd,rmfiles)
    	@rm -f arch/*/include/asm/arch
    
    # distclean
    #
    PHONY += distclean
    
    distclean: mrproper
    	@find $(srctree) $(RCS_FIND_IGNORE) \
    		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
    		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
    		-o -name '.*.rej' -o -name '*%' -o -name 'core' \
    		-o -name '*.pyc' \) \
    		-type f -print | xargs rm -f
    	@rm -f boards.cfg
    
    backup:
    	F=`basename $(srctree)` ; cd .. ; \
    	gtar --force-local -zcvf `LC_ALL=C date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F
    
    help:
    	@echo  'Cleaning targets:'
    	@echo  '  clean		  - Remove most generated files but keep the config'
    	@echo  '  mrproper	  - Remove all generated files + config + various backup files'
    	@echo  '  distclean	  - mrproper + remove editor backup and patch files'
    	@echo  ''
    	@echo  'Configuration targets:'
    	@$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
    	@echo  ''
    	@echo  'Other generic targets:'
    	@echo  '  all		  - Build all necessary images depending on configuration'
    	@echo  '* u-boot	  - Build the bare u-boot'
    	@echo  '  dir/            - Build all files in dir and below'
    	@echo  '  dir/file.[oisS] - Build specified target only'
    	@echo  '  dir/file.lst    - Build specified mixed source/assembly target only'
    	@echo  '                    (requires a recent binutils and recent build (System.map))'
    	@echo  '  tags/ctags	  - Generate ctags file for editors'
    	@echo  '  etags		  - Generate etags file for editors'
    	@echo  '  cscope	  - Generate cscope index'
    	@echo  '  ubootrelease	  - Output the release version string (use with make -s)'
    	@echo  '  ubootversion	  - Output the version stored in Makefile (use with make -s)'
    	@echo  ''
    	@echo  'Static analysers'
    	@echo  '  checkstack      - Generate a list of stack hogs'
    	@echo  ''
    	@echo  'Documentation targets:'
    	@$(MAKE) -f $(srctree)/doc/DocBook/Makefile dochelp
    	@echo  ''
    	@echo  '  make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
    	@echo  '  make V=2   [targets] 2 => give reason for rebuild of target'
    	@echo  '  make O=dir [targets] Locate all output files in "dir", including .config'
    	@echo  '  make C=1   [targets] Check all c source with $$CHECK (sparse by default)'
    	@echo  '  make C=2   [targets] Force check of all c source with $$CHECK'
    	@echo  '  make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections'
    	@echo  '  make W=n   [targets] Enable extra gcc checks, n=1,2,3 where'
    	@echo  '		1: warnings which may be relevant and do not occur too often'
    	@echo  '		2: warnings which occur quite often but may still be relevant'
    	@echo  '		3: more obscure warnings, can most likely be ignored'
    	@echo  '		Multiple levels can be combined with W=12 or W=123'
    	@echo  ''
    	@echo  'Execute "make" or "make all" to build all targets marked with [*] '
    	@echo  'For further info see the ./README file'
    
    
    # Documentation targets
    # ---------------------------------------------------------------------------
    %docs: scripts_basic FORCE
    	$(Q)$(MAKE) $(build)=scripts build_docproc
    	$(Q)$(MAKE) $(build)=doc/DocBook $@
    
    # Dummies...
    PHONY += prepare scripts
    prepare: ;
    scripts: ;
    
    endif #ifeq ($(config-targets),1)
    endif #ifeq ($(mixed-targets),1)
    
    PHONY += checkstack ubootrelease ubootversion
    
    checkstack:
    	$(OBJDUMP) -d u-boot $$(find . -name u-boot-spl) | \
    	$(PERL) $(src)/scripts/checkstack.pl $(ARCH)
    
    ubootrelease:
    	@echo "$(UBOOTVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))"
    
    ubootversion:
    	@echo $(UBOOTVERSION)
    
    # Single targets
    # ---------------------------------------------------------------------------
    # Single targets are compatible with:
    # - build with mixed source and output
    # - build with separate output dir 'make O=...'
    # - external modules
    #
    #  target-dir => where to store outputfile
    #  build-dir  => directory in kernel source tree to use
    
    ifeq ($(KBUILD_EXTMOD),)
            build-dir  = $(patsubst %/,%,$(dir $@))
            target-dir = $(dir $@)
    else
            zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@)))
            build-dir  = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash))
            target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
    endif
    
    %.s: %.c prepare scripts FORCE
    	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
    %.i: %.c prepare scripts FORCE
    	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
    %.o: %.c prepare scripts FORCE
    	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
    %.lst: %.c prepare scripts FORCE
    	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
    %.s: %.S prepare scripts FORCE
    	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
    %.o: %.S prepare scripts FORCE
    	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
    %.symtypes: %.c prepare scripts FORCE
    	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
    
    # Modules
    /: prepare scripts FORCE
    	$(cmd_crmodverdir)
    	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
    	$(build)=$(build-dir)
    %/: prepare scripts FORCE
    	$(cmd_crmodverdir)
    	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
    	$(build)=$(build-dir)
    %.ko: prepare scripts FORCE
    	$(cmd_crmodverdir)
    	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1)   \
    	$(build)=$(build-dir) $(@:.ko=.o)
    	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
    
    # FIXME Should go into a make.lib or something
    # ===========================================================================
    
    quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN   $(wildcard $(rm-dirs)))
          cmd_rmdirs = rm -rf $(rm-dirs)
    
    quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN   $(wildcard $(rm-files)))
          cmd_rmfiles = rm -f $(rm-files)
    
    # read all saved command lines
    
    targets := $(wildcard $(sort $(targets)))
    cmd_files := $(wildcard .*.cmd $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
    
    ifneq ($(cmd_files),)
      $(cmd_files): ;	# Do not try to update included dependency files
      include $(cmd_files)
    endif
    
    endif	# skip-makefile
    
    PHONY += FORCE
    FORCE:
    
    # Declare the contents of the .PHONY variable as phony.  We keep that
    # information in a variable so we can use it in if_changed and friends.
    .PHONY: $(PHONY)
    
    
    • 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
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
    • 498
    • 499
    • 500
    • 501
    • 502
    • 503
    • 504
    • 505
    • 506
    • 507
    • 508
    • 509
    • 510
    • 511
    • 512
    • 513
    • 514
    • 515
    • 516
    • 517
    • 518
    • 519
    • 520
    • 521
    • 522
    • 523
    • 524
    • 525
    • 526
    • 527
    • 528
    • 529
    • 530
    • 531
    • 532
    • 533
    • 534
    • 535
    • 536
    • 537
    • 538
    • 539
    • 540
    • 541
    • 542
    • 543
    • 544
    • 545
    • 546
    • 547
    • 548
    • 549
    • 550
    • 551
    • 552
    • 553
    • 554
    • 555
    • 556
    • 557
    • 558
    • 559
    • 560
    • 561
    • 562
    • 563
    • 564
    • 565
    • 566
    • 567
    • 568
    • 569
    • 570
    • 571
    • 572
    • 573
    • 574
    • 575
    • 576
    • 577
    • 578
    • 579
    • 580
    • 581
    • 582
    • 583
    • 584
    • 585
    • 586
    • 587
    • 588
    • 589
    • 590
    • 591
    • 592
    • 593
    • 594
    • 595
    • 596
    • 597
    • 598
    • 599
    • 600
    • 601
    • 602
    • 603
    • 604
    • 605
    • 606
    • 607
    • 608
    • 609
    • 610
    • 611
    • 612
    • 613
    • 614
    • 615
    • 616
    • 617
    • 618
    • 619
    • 620
    • 621
    • 622
    • 623
    • 624
    • 625
    • 626
    • 627
    • 628
    • 629
    • 630
    • 631
    • 632
    • 633
    • 634
    • 635
    • 636
    • 637
    • 638
    • 639
    • 640
    • 641
    • 642
    • 643
    • 644
    • 645
    • 646
    • 647
    • 648
    • 649
    • 650
    • 651
    • 652
    • 653
    • 654
    • 655
    • 656
    • 657
    • 658
    • 659
    • 660
    • 661
    • 662
    • 663
    • 664
    • 665
    • 666
    • 667
    • 668
    • 669
    • 670
    • 671
    • 672
    • 673
    • 674
    • 675
    • 676
    • 677
    • 678
    • 679
    • 680
    • 681
    • 682
    • 683
    • 684
    • 685
    • 686
    • 687
    • 688
    • 689
    • 690
    • 691
    • 692
    • 693
    • 694
    • 695
    • 696
    • 697
    • 698
    • 699
    • 700
    • 701
    • 702
    • 703
    • 704
    • 705
    • 706
    • 707
    • 708
    • 709
    • 710
    • 711
    • 712
    • 713
    • 714
    • 715
    • 716
    • 717
    • 718
    • 719
    • 720
    • 721
    • 722
    • 723
    • 724
    • 725
    • 726
    • 727
    • 728
    • 729
    • 730
    • 731
    • 732
    • 733
    • 734
    • 735
    • 736
    • 737
    • 738
    • 739
    • 740
    • 741
    • 742
    • 743
    • 744
    • 745
    • 746
    • 747
    • 748
    • 749
    • 750
    • 751
    • 752
    • 753
    • 754
    • 755
    • 756
    • 757
    • 758
    • 759
    • 760
    • 761
    • 762
    • 763
    • 764
    • 765
    • 766
    • 767
    • 768
    • 769
    • 770
    • 771
    • 772
    • 773
    • 774
    • 775
    • 776
    • 777
    • 778
    • 779
    • 780
    • 781
    • 782
    • 783
    • 784
    • 785
    • 786
    • 787
    • 788
    • 789
    • 790
    • 791
    • 792
    • 793
    • 794
    • 795
    • 796
    • 797
    • 798
    • 799
    • 800
    • 801
    • 802
    • 803
    • 804
    • 805
    • 806
    • 807
    • 808
    • 809
    • 810
    • 811
    • 812
    • 813
    • 814
    • 815
    • 816
    • 817
    • 818
    • 819
    • 820
    • 821
    • 822
    • 823
    • 824
    • 825
    • 826
    • 827
    • 828
    • 829
    • 830
    • 831
    • 832
    • 833
    • 834
    • 835
    • 836
    • 837
    • 838
    • 839
    • 840
    • 841
    • 842
    • 843
    • 844
    • 845
    • 846
    • 847
    • 848
    • 849
    • 850
    • 851
    • 852
    • 853
    • 854
    • 855
    • 856
    • 857
    • 858
    • 859
    • 860
    • 861
    • 862
    • 863
    • 864
    • 865
    • 866
    • 867
    • 868
    • 869
    • 870
    • 871
    • 872
    • 873
    • 874
    • 875
    • 876
    • 877
    • 878
    • 879
    • 880
    • 881
    • 882
    • 883
    • 884
    • 885
    • 886
    • 887
    • 888
    • 889
    • 890
    • 891
    • 892
    • 893
    • 894
    • 895
    • 896
    • 897
    • 898
    • 899
    • 900
    • 901
    • 902
    • 903
    • 904
    • 905
    • 906
    • 907
    • 908
    • 909
    • 910
    • 911
    • 912
    • 913
    • 914
    • 915
    • 916
    • 917
    • 918
    • 919
    • 920
    • 921
    • 922
    • 923
    • 924
    • 925
    • 926
    • 927
    • 928
    • 929
    • 930
    • 931
    • 932
    • 933
    • 934
    • 935
    • 936
    • 937
    • 938
    • 939
    • 940
    • 941
    • 942
    • 943
    • 944
    • 945
    • 946
    • 947
    • 948
    • 949
    • 950
    • 951
    • 952
    • 953
    • 954
    • 955
    • 956
    • 957
    • 958
    • 959
    • 960
    • 961
    • 962
    • 963
    • 964
    • 965
    • 966
    • 967
    • 968
    • 969
    • 970
    • 971
    • 972
    • 973
    • 974
    • 975
    • 976
    • 977
    • 978
    • 979
    • 980
    • 981
    • 982
    • 983
    • 984
    • 985
    • 986
    • 987
    • 988
    • 989
    • 990
    • 991
    • 992
    • 993
    • 994
    • 995
    • 996
    • 997
    • 998
    • 999
    • 1000
    • 1001
    • 1002
    • 1003
    • 1004
    • 1005
    • 1006
    • 1007
    • 1008
    • 1009
    • 1010
    • 1011
    • 1012
    • 1013
    • 1014
    • 1015
    • 1016
    • 1017
    • 1018
    • 1019
    • 1020
    • 1021
    • 1022
    • 1023
    • 1024
    • 1025
    • 1026
    • 1027
    • 1028
    • 1029
    • 1030
    • 1031
    • 1032
    • 1033
    • 1034
    • 1035
    • 1036
    • 1037
    • 1038
    • 1039
    • 1040
    • 1041
    • 1042
    • 1043
    • 1044
    • 1045
    • 1046
    • 1047
    • 1048
    • 1049
    • 1050
    • 1051
    • 1052
    • 1053
    • 1054
    • 1055
    • 1056
    • 1057
    • 1058
    • 1059
    • 1060
    • 1061
    • 1062
    • 1063
    • 1064
    • 1065
    • 1066
    • 1067
    • 1068
    • 1069
    • 1070
    • 1071
    • 1072
    • 1073
    • 1074
    • 1075
    • 1076
    • 1077
    • 1078
    • 1079
    • 1080
    • 1081
    • 1082
    • 1083
    • 1084
    • 1085
    • 1086
    • 1087
    • 1088
    • 1089
    • 1090
    • 1091
    • 1092
    • 1093
    • 1094
    • 1095
    • 1096
    • 1097
    • 1098
    • 1099
    • 1100
    • 1101
    • 1102
    • 1103
    • 1104
    • 1105
    • 1106
    • 1107
    • 1108
    • 1109
    • 1110
    • 1111
    • 1112
    • 1113
    • 1114
    • 1115
    • 1116
    • 1117
    • 1118
    • 1119
    • 1120
    • 1121
    • 1122
    • 1123
    • 1124
    • 1125
    • 1126
    • 1127
    • 1128
    • 1129
    • 1130
    • 1131
    • 1132
    • 1133
    • 1134
    • 1135
    • 1136
    • 1137
    • 1138
    • 1139
    • 1140
    • 1141
    • 1142
    • 1143
    • 1144
    • 1145
    • 1146
    • 1147
    • 1148
    • 1149
    • 1150
    • 1151
    • 1152
    • 1153
    • 1154
    • 1155
    • 1156
    • 1157
    • 1158
    • 1159
    • 1160
    • 1161
    • 1162
    • 1163
    • 1164
    • 1165
    • 1166
    • 1167
    • 1168
    • 1169
    • 1170
    • 1171
    • 1172
    • 1173
    • 1174
    • 1175
    • 1176
    • 1177
    • 1178
    • 1179
    • 1180
    • 1181
    • 1182
    • 1183
    • 1184
    • 1185
    • 1186
    • 1187
    • 1188
    • 1189
    • 1190
    • 1191
    • 1192
    • 1193
    • 1194
    • 1195
    • 1196
    • 1197
    • 1198
    • 1199
    • 1200
    • 1201
    • 1202
    • 1203
    • 1204
    • 1205
    • 1206
    • 1207
    • 1208
    • 1209
    • 1210
    • 1211
    • 1212
    • 1213
    • 1214
    • 1215
    • 1216
    • 1217
    • 1218
    • 1219
    • 1220
    • 1221
    • 1222
    • 1223
    • 1224
    • 1225
    • 1226
    • 1227
    • 1228
    • 1229
    • 1230
    • 1231
    • 1232
    • 1233
    • 1234
    • 1235
    • 1236
    • 1237
    • 1238
    • 1239
    • 1240
    • 1241
    • 1242
    • 1243
    • 1244
    • 1245
    • 1246
    • 1247
    • 1248
    • 1249
    • 1250
    • 1251
    • 1252
    • 1253
    • 1254
    • 1255
    • 1256
    • 1257
    • 1258
    • 1259
    • 1260
    • 1261
    • 1262
    • 1263
    • 1264
    • 1265
    • 1266
    • 1267
    • 1268
    • 1269
    • 1270
    • 1271
    • 1272
    • 1273
    • 1274
    • 1275
    • 1276
    • 1277
    • 1278
    • 1279
    • 1280
    • 1281
    • 1282
    • 1283
    • 1284
    • 1285
    • 1286
    • 1287
    • 1288
    • 1289
    • 1290
    • 1291
    • 1292
    • 1293
    • 1294
    • 1295
    • 1296
    • 1297
    • 1298
    • 1299
    • 1300
    • 1301
    • 1302
    • 1303
    • 1304
    • 1305
    • 1306
    • 1307
    • 1308
    • 1309
    • 1310
    • 1311
    • 1312
    • 1313
    • 1314
    • 1315
    • 1316
    • 1317
    • 1318
    • 1319
    • 1320
    • 1321
    • 1322
    • 1323
    • 1324
    • 1325
    • 1326
    • 1327
    • 1328
    • 1329
    • 1330
    • 1331
    • 1332
    • 1333
    • 1334
    • 1335
    • 1336
    • 1337
    • 1338
    • 1339
    • 1340
    • 1341
    • 1342
    • 1343
    • 1344
    • 1345
    • 1346
    • 1347
    • 1348
    • 1349
    • 1350
    • 1351
    • 1352
    • 1353
    • 1354
    • 1355
    • 1356
    • 1357
    • 1358
    • 1359
    • 1360
    • 1361
    • 1362
    • 1363
    • 1364
    • 1365
    • 1366
    • 1367
    • 1368
    • 1369
    • 1370
    • 1371
    • 1372
    • 1373
    • 1374
    • 1375
    • 1376
    • 1377
    • 1378
    • 1379
    • 1380
    • 1381
    • 1382
    • 1383
    • 1384
    • 1385
    • 1386
    • 1387
    • 1388
    • 1389
    • 1390
    • 1391
    • 1392
    • 1393
    • 1394
    • 1395
    • 1396
    • 1397
    • 1398
    • 1399
    • 1400
    • 1401
    • 1402
    • 1403
    • 1404
    • 1405
    • 1406
    • 1407
    • 1408
    • 1409
    • 1410
    • 1411
    • 1412
    • 1413
    • 1414
    • 1415
    • 1416
    • 1417
    • 1418
    • 1419
    • 1420
    • 1421
    • 1422
    • 1423
    • 1424
    • 1425
    • 1426
    • 1427
    • 1428
    • 1429
    • 1430
    • 1431
    • 1432
    • 1433
    • 1434
    • 1435
    • 1436
    • 1437
    • 1438
    • 1439
    • 1440
    • 1441
    • 1442
    • 1443
    • 1444
    • 1445
    • 1446
    • 1447
    • 1448
    • 1449
    • 1450
    • 1451
    • 1452
    • 1453
    • 1454
    • 1455
    • 1456
    • 1457
    • 1458
    • 1459
    • 1460
    • 1461
    • 1462
    • 1463
    • 1464
    • 1465
    • 1466
    • 1467
    • 1468
    • 1469
    • 1470
    • 1471
    • 1472
    • 1473
    • 1474
    • 1475
    • 1476
    • 1477
    • 1478
    • 1479
    • 1480
    • 1481
    • 1482
    • 1483
    • 1484
    • 1485
    • 1486
    • 1487
    • 1488
    • 1489
    • 1490
    • 1491
    • 1492
    • 1493
    • 1494
    • 1495
    • 1496
    • 1497
    • 1498
    • 1499
    • 1500
    • 1501
    • 1502
    • 1503
    • 1504
    • 1505
    • 1506
    • 1507
    • 1508
    • 1509
    • 1510
    • 1511
    • 1512
    • 1513
    • 1514
    • 1515
    • 1516
    • 1517
    • 1518
    • 1519
    • 1520
    • 1521
    • 1522
    • 1523
    • 1524
    • 1525
    • 1526
    • 1527
    • 1528
    • 1529
    • 1530
    • 1531
    • 1532
    • 1533
    • 1534
    • 1535
    • 1536
    • 1537
    • 1538
    • 1539
    • 1540
    • 1541
    • 1542
    • 1543
    • 1544
    • 1545
    • 1546
    • 1547
    • 1548
    • 1549
    • 1550
    • 1551
    • 1552
    • 1553
    • 1554
    • 1555
    • 1556
    • 1557
    • 1558
    • 1559
    • 1560
    • 1561
    • 1562
    • 1563
    • 1564
    • 1565
    • 1566
    • 1567
    • 1568
    • 1569
    • 1570
    • 1571
    • 1572
    • 1573
    • 1574
    • 1575
    • 1576
    • 1577
    • 1578
    • 1579
    • 1580
    • 1581
    • 1582
    • 1583
    • 1584
    • 1585
    • 1586
    • 1587
    • 1588
    • 1589
    • 1590
    • 1591
    • 1592
    • 1593
    • 1594
    • 1595
    • 1596
    • 1597
    • 1598
    • 1599
    • 1600
    • 1601
    • 1602
    • 1603
    • 1604
    • 1605
    • 1606
    • 1607
    • 1608
    • 1609
    • 1610
    • 1611
    • 1612
    • 1613
    • 1614
    • 1615
    • 1616
    • 1617
    • 1618
    • 1619
    • 1620
    • 1621
    • 1622
    • 1623
    • 1624
    • 1625
    • 1626
    • 1627
    • 1628
    • 1629
    • 1630
    • 1631
    • 1632
    • 1633
    • 1634
    • 1635
    • 1636
    • 1637
    • 1638
    • 1639
    • 1640
    • 1641
    • 1642
    • 1643
    • 1644
    • 1645
    • 1646
    • 1647
    • 1648
    • 1649
    • 1650
    • 1651
    • 1652
    • 1653
    • 1654
    • 1655
    • 1656
    • 1657
    • 1658
    • 1659
    • 1660
    • 1661
    • 1662
    • 1663
    • 1664
    • 1665
    • 1666
    • 1667
    • 1668
    • 1669
    • 1670
    • 1671
    • 1672
    • 1673
    • 1674
    • 1675
    • 1676
    • 1677
    • 1678
    • 1679

    在使用make xxx_defconfig的时候,会执行脚本scripts/Makefile.build

    @make -f ./scripts/Makefile.build obj=scripts/basic 
    @make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig 
    
    • 1
    • 2

    image-20221113231938240

    scripts/Makefile.build

    # ==========================================================================
    # Building
    # ==========================================================================
    #
    # SPDX-License-Identifier:	GPL-2.0
    #
    
    # Modified for U-Boot
    prefix := tpl
    src := $(patsubst $(prefix)/%,%,$(obj))
    ifeq ($(obj),$(src))
    prefix := spl
    src := $(patsubst $(prefix)/%,%,$(obj))
    ifeq ($(obj),$(src))
    prefix := .
    endif
    endif
    
    PHONY := __build
    __build:
    
    # Init all relevant variables used in kbuild files so
    # 1) they have correct type
    # 2) they do not inherit any value from the environment
    obj-y :=
    obj-m :=
    lib-y :=
    lib-m :=
    always :=
    targets :=
    subdir-y :=
    subdir-m :=
    EXTRA_AFLAGS   :=
    EXTRA_CFLAGS   :=
    EXTRA_CPPFLAGS :=
    EXTRA_LDFLAGS  :=
    asflags-y  :=
    ccflags-y  :=
    cppflags-y :=
    ldflags-y  :=
    
    subdir-asflags-y :=
    subdir-ccflags-y :=
    
    # Read auto.conf if it exists, otherwise ignore
    # Modified for U-Boot
    -include include/config/auto.conf
    -include $(prefix)/include/autoconf.mk
    include scripts/Makefile.uncmd_spl
    
    include scripts/Kbuild.include
    
    # For backward compatibility check that these variables do not change
    save-cflags := $(CFLAGS)
    
    # The filename Kbuild has precedence over Makefile
    kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
    # $(if $(filter /%, scripts/basic),  scripts/basic, ./scripts/basic)
    # $(filter /%, scripts/basic) 没有/开头的单词,所以结果为空
    kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
    # kbuild-dir = ./scripts/basic
    # 展开为$(if $(wildcard ./scripts/basic/Kbuild), ./scripts/basic/Kbuild, ./scripts/basic/Makefile) 
    # kbuild-file = ./scripts/basic/Makefile
    include $(kbuild-file)
    
    # Added for U-Boot
    asflags-y  += $(PLATFORM_CPPFLAGS)
    ccflags-y  += $(PLATFORM_CPPFLAGS)
    cppflags-y += $(PLATFORM_CPPFLAGS)
    
    # If the save-* variables changed error out
    ifeq ($(KBUILD_NOPEDANTIC),)
            ifneq ("$(save-cflags)","$(CFLAGS)")
                    $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y)
            endif
    endif
    
    include scripts/Makefile.lib
    
    ifdef host-progs
    ifneq ($(hostprogs-y),$(host-progs))
    $(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please replace with hostprogs-y!)
    hostprogs-y += $(host-progs)
    endif
    endif
    
    # Do not include host rules unless needed
    ifneq ($(hostprogs-y)$(hostprogs-m),)
    include scripts/Makefile.host
    endif
    
    # Uncommented for U-Boot
    #  We need to create output dicrectory for SPL and TPL even for in-tree build
    #ifneq ($(KBUILD_SRC),)
    # Create output directory if not already present
    _dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
    
    # Create directories for object files if directory does not exist
    # Needed when obj-y := dir/file.o syntax is used
    _dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
    #endif
    
    ifndef obj
    $(warning kbuild: Makefile.build is included improperly)
    endif
    
    # ===========================================================================
    
    ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),)
    lib-target := $(obj)/lib.a
    endif
    
    ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),)
    builtin-target := $(obj)/built-in.o
    endif
    
    modorder-target := $(obj)/modules.order
    
    # We keep a list of all modules in $(MODVERDIR)
    
    __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
    	 $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
    	 $(subdir-ym) $(always)
    	@:
    # __build为默认目标
    # __build:$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always) @: 
    
    # Linus' kernel sanity checking tool
    ifneq ($(KBUILD_CHECKSRC),0)
      ifeq ($(KBUILD_CHECKSRC),2)
        quiet_cmd_force_checksrc = CHECK   $<
              cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
      else
          quiet_cmd_checksrc     = CHECK   $<
                cmd_checksrc     = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
      endif
    endif
    
    # Do section mismatch analysis for each module/built-in.o
    ifdef CONFIG_DEBUG_SECTION_MISMATCH
      cmd_secanalysis = ; scripts/mod/modpost $@
    endif
    
    # Compile C sources (.c)
    # ---------------------------------------------------------------------------
    
    # Default is built-in, unless we know otherwise
    modkern_cflags =                                          \
    	$(if $(part-of-module),                           \
    		$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
    		$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL))
    quiet_modtag := $(empty)   $(empty)
    
    $(real-objs-m)        : part-of-module := y
    $(real-objs-m:.o=.i)  : part-of-module := y
    $(real-objs-m:.o=.s)  : part-of-module := y
    $(real-objs-m:.o=.lst): part-of-module := y
    
    $(real-objs-m)        : quiet_modtag := [M]
    $(real-objs-m:.o=.i)  : quiet_modtag := [M]
    $(real-objs-m:.o=.s)  : quiet_modtag := [M]
    $(real-objs-m:.o=.lst): quiet_modtag := [M]
    
    $(obj-m)              : quiet_modtag := [M]
    
    # Default for not multi-part modules
    modname = $(basetarget)
    
    $(multi-objs-m)         : modname = $(modname-multi)
    $(multi-objs-m:.o=.i)   : modname = $(modname-multi)
    $(multi-objs-m:.o=.s)   : modname = $(modname-multi)
    $(multi-objs-m:.o=.lst) : modname = $(modname-multi)
    $(multi-objs-y)         : modname = $(modname-multi)
    $(multi-objs-y:.o=.i)   : modname = $(modname-multi)
    $(multi-objs-y:.o=.s)   : modname = $(modname-multi)
    $(multi-objs-y:.o=.lst) : modname = $(modname-multi)
    
    quiet_cmd_cc_s_c = CC $(quiet_modtag)  $@
    cmd_cc_s_c       = $(CC) $(c_flags) $(DISABLE_LTO) -fverbose-asm -S -o $@ $<
    
    $(obj)/%.s: $(src)/%.c FORCE
    	$(call if_changed_dep,cc_s_c)
    
    quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
    cmd_cc_i_c       = $(CPP) $(c_flags)   -o $@ $<
    
    $(obj)/%.i: $(src)/%.c FORCE
    	$(call if_changed_dep,cc_i_c)
    
    cmd_gensymtypes =                                                           \
        $(CPP) -D__GENKSYMS__ $(c_flags) $< |                                   \
        $(GENKSYMS) $(if $(1), -T $(2))                                         \
         $(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX))             \
         $(if $(KBUILD_PRESERVE),-p)                                            \
         -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
    
    quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
    cmd_cc_symtypes_c =                                                         \
        set -e;                                                                 \
        $(call cmd_gensymtypes,true,$@) >/dev/null;                             \
        test -s $@ || rm -f $@
    
    $(obj)/%.symtypes : $(src)/%.c FORCE
    	$(call cmd,cc_symtypes_c)
    
    # C (.c) files
    # The C file is compiled and updated dependency information is generated.
    # (See cmd_cc_o_c + relevant part of rule_cc_o_c)
    
    quiet_cmd_cc_o_c = CC $(quiet_modtag)  $@
    
    ifndef CONFIG_MODVERSIONS
    cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
    
    else
    # When module versioning is enabled the following steps are executed:
    # o compile a .tmp_.o from .c
    # o if .tmp_.o doesn't contain a __ksymtab version, i.e. does
    #   not export symbols, we just rename .tmp_.o to .o and
    #   are done.
    # o otherwise, we calculate symbol versions using the good old
    #   genksyms on the preprocessed source and postprocess them in a way
    #   that they are usable as a linker script
    # o generate .o from .tmp_.o using the linker to
    #   replace the unresolved symbols __crc_exported_symbol with
    #   the actual value of the checksum generated by genksyms
    
    cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
    cmd_modversions =								\
    	if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then		\
    		$(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes))	\
    		    > $(@D)/.tmp_$(@F:.o=.ver);					\
    										\
    		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 			\
    			-T $(@D)/.tmp_$(@F:.o=.ver);				\
    		rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);		\
    	else									\
    		mv -f $(@D)/.tmp_$(@F) $@;					\
    	fi;
    endif
    
    ifdef CONFIG_FTRACE_MCOUNT_RECORD
    ifdef BUILD_C_RECORDMCOUNT
    ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
      RECORDMCOUNT_FLAGS = -w
    endif
    # Due to recursion, we must skip empty.o.
    # The empty.o file is created in the make process in order to determine
    #  the target endianness and word size. It is made before all other C
    #  files, including recordmcount.
    sub_cmd_record_mcount =					\
    	if [ $(@) != "scripts/mod/empty.o" ]; then	\
    		$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)";	\
    	fi;
    recordmcount_source := $(srctree)/scripts/recordmcount.c \
    		    $(srctree)/scripts/recordmcount.h
    else
    sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
    	"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
    	"$(if $(CONFIG_64BIT),64,32)" \
    	"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
    	"$(LD)" "$(NM)" "$(RM)" "$(MV)" \
    	"$(if $(part-of-module),1,0)" "$(@)";
    recordmcount_source := $(srctree)/scripts/recordmcount.pl
    endif
    cmd_record_mcount =						\
    	if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" =	\
    	     "$(CC_FLAGS_FTRACE)" ]; then			\
    		$(sub_cmd_record_mcount)			\
    	fi;
    endif
    
    define rule_cc_o_c
    	$(call echo-cmd,checksrc) $(cmd_checksrc)			  \
    	$(call echo-cmd,cc_o_c) $(cmd_cc_o_c);				  \
    	$(cmd_modversions)						  \
    	$(call echo-cmd,record_mcount)					  \
    	$(cmd_record_mcount)						  \
    	scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' >    \
    	                                              $(dot-target).tmp;  \
    	rm -f $(depfile);						  \
    	mv -f $(dot-target).tmp $(dot-target).cmd
    endef
    
    # Built-in and composite module parts
    $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
    	$(call cmd,force_checksrc)
    	$(call if_changed_rule,cc_o_c)
    
    # Single-part modules are special since we need to mark them in $(MODVERDIR)
    
    $(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
    	$(call cmd,force_checksrc)
    	$(call if_changed_rule,cc_o_c)
    	@{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
    
    quiet_cmd_cc_lst_c = MKLST   $@
          cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
    		     $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
    				     System.map $(OBJDUMP) > $@
    
    $(obj)/%.lst: $(src)/%.c FORCE
    	$(call if_changed_dep,cc_lst_c)
    
    # Compile assembler sources (.S)
    # ---------------------------------------------------------------------------
    
    modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
    
    $(real-objs-m)      : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
    $(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
    
    quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
    cmd_as_s_S       = $(CPP) $(a_flags)   -o $@ $<
    
    $(obj)/%.s: $(src)/%.S FORCE
    	$(call if_changed_dep,as_s_S)
    
    quiet_cmd_as_o_S = AS $(quiet_modtag)  $@
    cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
    
    $(obj)/%.o: $(src)/%.S FORCE
    	$(call if_changed_dep,as_o_S)
    
    targets += $(real-objs-y) $(real-objs-m) $(lib-y)
    targets += $(extra-y) $(MAKECMDGOALS) $(always)
    
    # Linker scripts preprocessor (.lds.S -> .lds)
    # ---------------------------------------------------------------------------
    quiet_cmd_cpp_lds_S = LDS     $@
          cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
    	                     -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
    
    $(obj)/%.lds: $(src)/%.lds.S FORCE
    	$(call if_changed_dep,cpp_lds_S)
    
    # ASN.1 grammar
    # ---------------------------------------------------------------------------
    quiet_cmd_asn1_compiler = ASN.1   $@
          cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \
    				$(subst .h,.c,$@) $(subst .c,.h,$@)
    
    .PRECIOUS: $(objtree)/$(obj)/%-asn1.c $(objtree)/$(obj)/%-asn1.h
    
    $(obj)/%-asn1.c $(obj)/%-asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
    	$(call cmd,asn1_compiler)
    
    # Build the compiled-in targets
    # ---------------------------------------------------------------------------
    
    # To build objects in subdirs, we need to descend into the directories
    $(sort $(subdir-obj-y)): $(subdir-ym) ;
    
    #
    # Rule to compile a set of .o files into one .o file
    #
    ifdef builtin-target
    quiet_cmd_link_o_target = LD      $@
    # If the list of objects to link is empty, just create an empty built-in.o
    cmd_link_o_target = $(if $(strip $(obj-y)),\
    		      $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \
    		      $(cmd_secanalysis),\
    		      rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@)
    
    $(builtin-target): $(obj-y) FORCE
    	$(call if_changed,link_o_target)
    
    targets += $(builtin-target)
    endif # builtin-target
    
    #
    # Rule to create modules.order file
    #
    # Create commands to either record .ko file or cat modules.order from
    # a subdirectory
    modorder-cmds =						\
    	$(foreach m, $(modorder),			\
    		$(if $(filter %/modules.order, $m),	\
    			cat $m;, echo kernel/$m;))
    
    $(modorder-target): $(subdir-ym) FORCE
    	$(Q)(cat /dev/null; $(modorder-cmds)) > $@
    
    #
    # Rule to compile a set of .o files into one .a file
    #
    ifdef lib-target
    quiet_cmd_link_l_target = AR      $@
    cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y)
    
    $(lib-target): $(lib-y) FORCE
    	$(call if_changed,link_l_target)
    
    targets += $(lib-target)
    endif
    
    #
    # Rule to link composite objects
    #
    #  Composite objects are specified in kbuild makefile as follows:
    #    -objs := 
    #  or
    #    -y    := 
    link_multi_deps =                     \
    $(filter $(addprefix $(obj)/,         \
    $($(subst $(obj)/,,$(@:.o=-objs)))    \
    $($(subst $(obj)/,,$(@:.o=-y)))), $^)
    
    quiet_cmd_link_multi-y = LD      $@
    cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis)
    
    quiet_cmd_link_multi-m = LD [M]  $@
    cmd_link_multi-m = $(cmd_link_multi-y)
    
    $(multi-used-y): FORCE
    	$(call if_changed,link_multi-y)
    $(call multi_depend, $(multi-used-y), .o, -objs -y)
    
    $(multi-used-m): FORCE
    	$(call if_changed,link_multi-m)
    	@{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
    $(call multi_depend, $(multi-used-m), .o, -objs -y)
    
    targets += $(multi-used-y) $(multi-used-m)
    
    
    # Descending
    # ---------------------------------------------------------------------------
    
    PHONY += $(subdir-ym)
    $(subdir-ym):
    	$(Q)$(MAKE) $(build)=$@
    
    # Add FORCE to the prequisites of a target to force it to be always rebuilt.
    # ---------------------------------------------------------------------------
    
    PHONY += FORCE
    
    FORCE:
    
    # Read all saved command lines and dependencies for the $(targets) we
    # may be building above, using $(if_changed{,_dep}). As an
    # optimization, we don't need to read them if the target does not
    # exist, we will rebuild anyway in that case.
    
    targets := $(wildcard $(sort $(targets)))
    cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
    
    ifneq ($(cmd_files),)
      include $(cmd_files)
    endif
    
    # Declare the contents of the .PHONY variable as phony.  We keep that
    # information in a variable se we can use it in if_changed and friends.
    
    .PHONY: $(PHONY)
    
    
    • 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
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457

    make 命令流程

    在这里插入图片描述

  • 相关阅读:
    基于UDP丢包统计程序设计
    docker 安装jenkins
    前端课后作业
    Win10 + Ubuntu 双系统完美避坑删除 Ubuntu 教程
    STM32微控制 -STM32命名规则-STM32寄存器缩写列表-STM32存储器和总线架构
    3种等待方式,让你学会Selenium设置自动化等待测试脚本!
    分享一下微信付费文章功能怎么做
    D - Range = √Sum 构造,F - Strange Memory 树上启发式合并
    【图像分割】基于模糊C均值聚类算法CGFFCM实现彩色图像分割附matlab代码
    leetcode 13. 罗马数字转整数
  • 原文地址:https://blog.csdn.net/qq_38863842/article/details/127780673