日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

U-Boot顶层Makefile分析

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 U-Boot顶层Makefile分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考:U-Boot頂層Makefile介紹
作者:一只青木呀
發布時間: 2020-10-22 16:22:17
網址:https://blog.csdn.net/weixin_45309916/article/details/109218569

目錄

  • 0、學習目的
  • 1、準備好uboot源碼
  • 2、分析頂層Makefile
    • 2.1、版本號
    • 2.2、MAKEFLAGS 變量
    • 2.3、命令輸出(參數V的效果)
    • 2.4、靜默輸出
    • 2.5、設置編譯結果輸出目錄
    • 2.6、代碼檢查
    • 2.7、模塊編譯
    • 2.8、獲取主機架構和系統
    • 2.9 、設置目標架構、交叉編譯器和配置文件
    • 2.10、調用 scripts/Kbuild.include
    • 2.11、交叉編譯工具變量設置
    • 3.12、導出其他變量
    • 2.13、make xxx_defconfig 過程
    • 2.14、 Makefile.build 腳本分析(接上一節內容)
      • 2.14.1、scripts_basic 目標對應的命令
      • 2.14.2、 %config 目標對應的命令
      • 總結make xxx_defconfig過程
    • 2.15、 make 編譯過程
      • 總結make命令的流程

0、學習目的

分析頂層Makefile主要是為了知道以后要改哪些東西。

Makefile配置好哪些C文件需要編譯,配置好以后通過make命令編譯即可。

1、準備好uboot源碼

這里分析的是2016.版本的uboot。

uboot源碼下載:https://blog.csdn.net/weixin_45309916/article/details/109176510

下載好后打開頂層Makefile。

一共是1600多行,接下來就開始分析啦

2、分析頂層Makefile

在閱讀 uboot 源碼之前,肯定是要先看一下頂層 Makefile,分析 gcc 版本代碼的時候一定是先從頂層 Makefile 開始的,然后再是子 Makefile,這樣通過層層分析 Makefile 即可了解整個工程的組織結構。頂層 Makefile 也就是 uboot 根目錄下的 Makefile 文件,由于頂層 Makefile 文件內容比較多,所以我們將其分開來看。

2.1、版本號

頂層 Makefile 一開始是版本號,內容如下(為了方便分析,頂層 Makefile 代碼段前段行號采用 Makefile 中的行號,因為 uboot 會更新,因此行號可能會與你所看的頂層 Makefile 有所不同):

VERSION 是主版本號, PATCHLEVEL 是補丁版本號, SUBLEVEL 是次版本號,這三個一起構成了 uboot 的版本號,比如當前的 uboot 版本號就是“2016.03”。 EXTRAVERSION 是附加版本信息, NAME 是和名字有關的,一般不使用這兩個。

2.2、MAKEFLAGS 變量

make 是支持遞歸調用的,也就是在 Makefile 中使用“make”命令來執行其他的Makefile文件,一般都是子目錄中的 Makefile 文件。假如在當前目錄下存在一個“subdir”子目錄,這個子目錄中又有其對應的 Makefile 文件,那么這個工程在編譯的時候其主目錄中的 Makefile 就可以調用子目錄中的 Makefile,以此來完成所有子目錄的編譯。主目錄的 Makefile 可以使用如下代碼來編譯這個子目錄:

$(MAKE) -C subdir

$(MAKE)就是調用“make”命令, -C 指定子目錄。有時候我們需要向子 make 傳遞變量,這個時候使用“export”來導出要傳遞給子 make 的變量即可,如果不希望哪個變量傳遞給子make 的話就使用“unexport”來聲明不導出:

export VARIABLE …… //導出變量給子 make 。 unexport VARIABLE…… //不導出變量給子 make。

有兩個特殊的變量:“SHELL”和“MAKEFLAGS”,這兩個變量除非使用“unexport”聲明,否則的話在整個make的執行過程中,它們的值始終自動的傳遞給子make。在uboot的主Makefile中有如下代碼:

MAKEFLAGS += -rR --include-dir=$(CURDIR)

上述代碼使用“+=”來給變量 MAKEFLAGS 追加了一些值,“-rR”表示禁止使用內置的隱含規則和變量定義,“–include-dir”指明搜索路徑, ”$(CURDIR)”表示當前目錄。

2.3、命令輸出(參數V的效果)

uboot 默認編譯(就是輸入編譯命令make -j12)是不會在終端中顯示完整的命令,都是短命令,如下圖所示:

在終端中輸出短命令雖然看起來很清爽,但是不利于分析 uboot 的編譯過程。可以通過設置變量“V=1“來實現完整的命令輸出(就是輸入編譯命令make V=1 -j12),這個在調試 uboot 的時候很有用,結果如下圖所示:

頂層 Makefile 中控制命令輸出的代碼如下:

上述代碼中先使用 ifeq 來判斷"$(origin V)"和"command line"是否相等。這里用到了 Makefile中的函數 origin, origin 和其他的函數不一樣,它不操作變量的值, origin 用于告訴你變量是哪來的,語法為:

$(origin <variable>)

variable 是變量名, origin 函數的返回值就是變量來源,因此( o r i g i n V ) 就 是 變 量 V 的 來 源 。 如 果 變 量 V 是 在 命 令 行 定 義 的 那 么 它 的 來 源 就 是 " c o m m a n d l i n e " , 這 樣 " (origin V)就是變量 V 的來源。如果變量 V 是在命令行定義的那么它的來源就是"command line",這樣"(originV)就是變量V的來源。如果變量V是在命令行定義的那么它的來源就是"commandline",這樣"(origin V)"和"commandline"就相等了。當這兩個相等的時候變量 KBUILD_VERBOSE 就等于 V 的值,比如在命令行中輸 入 “ V=1 “ 的 話 那 么 KBUILD_VERBOSE=1 。 如 果 沒 有 在 命 令 行 輸 入 V 的 話KBUILD_VERBOSE=0。

第 80 行判斷 KBUILD_VERBOSE 是否為 1,如果 KBUILD_VERBOSE 為 1 的話變量 quiet和 Q 都為空,如果 KBUILD_VERBOSE=0 的話變量 quiet 為“quiet_“,變量 Q 為“@” ,綜上所述:
V=1 的話:

KBUILD_VERBOSE=1 quiet= 空 。 Q= 空。

V=0 或者命令行不定義 V 的話:

KBUILD_VERBOSE=0 quiet= quiet_。 Q= @。

Makefile 中會用到變量 quiet 和 Q 來控制編譯的時候是否在終端輸出完整的命令,在頂層Makefile 中有很多如下所示的命令:

$(Q)$(MAKE) $(build)=tools

如果 V=0 的話上述命令展開就是“@ make $(build)=tools”, make 在執行的時候默認會在終端輸出命令,但是在命令前面加上“@”就不會在終端輸出命令了(shell腳本語法)。當 V=1 的時候 Q 就為空,上述命令就是“make $(build)=tools”,因此在 make 執行的過程,命令會被完整的輸出在終端上。

有些命令會有兩個版本,比如:

quiet_cmd_sym ?= SYM $@ cmd_sym ?= $(OBJDUMP) -t $< > $@

sym 命令分為“quiet_cmd_sym”和“cmd_sym”兩個版本,這兩個命令的功能都是一樣的,區別在于 make 執行的時候輸出的命令不同。 quiet_cmd_xxx 命令輸出信息少,也就是短命令,而 cmd_xxx 命令輸出信息多,也就是完整的命令。

如果變量 quiet 為空的話,整個命令都會輸出。
如果變量 quiet 為“quiet_”的話,僅輸出短版本。
如果變量 quiet 為“silent_”的話,整個命令都不會輸出。

2.4、靜默輸出

設置 V=0 或者在命令行中不定義 V 的話,編譯 uboot 的時候終端中顯示的短命令,但是還是會有命令輸出,有時候我們在編譯 uboot 的時候不需要輸出任何命令,這個時候就可以使用 uboot 的靜默輸出功能。編譯的時候使用“make -s”即可實現靜默輸出,頂層 Makefile中相應的代碼如下:

2.5、設置編譯結果輸出目錄

uboot 可以將編譯出來的目標文件輸出到單獨的目錄中,在 make 的時候使用“O”來指定輸出目錄,比如“make O=out”就是設置目標文件輸出到 out 目錄中。這么做是為了將源文件和編譯產生的文件分開,當然也可以不指定 O 參數,不指定的話源文件和編譯產生的文件都在同一個目錄內,一般我們不指定 O 參數。頂層 Makefile 中相關的代碼如下:

# 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),) ifeq ("$(origin O)", "command line")

判斷“O”是否來自于命令行,如果來自命令行的話條件成立, KBUILD_OUTPUT就為$(O),因此變量 KBUILD_OUTPUT 就是輸出目錄。

ifneq ($(KBUILD_OUTPUT),)

判斷 KBUILD_OUTPUT 是否為空。

KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \&& /bin/pwd)

調用 mkdir 命令,創建 KBUILD_OUTPUT 目錄,并且將創建成功以后的絕對路徑賦值給 KBUILD_OUTPUT。至此,通過 O 指定的輸出目錄就存在了。

2.6、代碼檢查

uboot 支持代碼檢查,使用命令“make C=1”使能代碼檢查,檢查那些需要重新編譯的文件。“make C=2”用于檢查所有的源碼文件,頂層 Makefile 中的代碼如下:

第 176 行判斷 C 是否來源于命令行,如果 C 來源于命令行,那就將 C 賦值給變量KBUILD_CHECKSRC,如果命令行沒有 C 的話 KBUILD_CHECKSRC 就為 0。

2.7、模塊編譯

在 uboot 中允許單獨編譯某個模塊,使用命令“ make M=dir”即可,舊語法“ makeSUBDIRS=dir”也是支持的。頂層 Makefile 中的代碼如下:

第 186 行 判 斷 是 否 定 義 了 SUBDIRS , 如 果 定 義 了 SUBDIRS , 變 量KBUILD_EXTMOD=SUBDIRS,這里是為了支持老語法“make SUBIDRS=dir”

第 190 行判斷是否在命令行定義了 M,如果定義了的話 KBUILD_EXTMOD=$(M)。

第 197 行判斷 KBUILD_EXTMOD 時為空,如果為空的話目標_all 依賴 all,因此要先編譯出 all。否則的話默認目標_all 依賴 modules,要先編譯出 modules,也就是編譯模塊。一般情況下我們不會在 uboot 中編譯模塊,所以此處會編譯 all 這個目標。

第 203 行判斷 KBUILD_SRC 是否為空,如果為空的話就設置變量 srctree 為當前目錄,即srctree 為“.”,一般不設置 KBUILD_SRC。

第 214 行設置變量 objtree 為當前目錄。

第 215 和 216 行分別設置變量 src 和 obj,都為當前目錄。

第 218 行設置 VPATH。

第 220 行導出變量 scrtree、 objtree 和 VPATH。

2.8、獲取主機架構和系統

接下來頂層 Makefile 會獲取主機架構和系統,也就是我們電腦的架構和系統,代碼如下:

第 227 行定義了一個變量 HOSTARCH,用于保存主機架構,這里調用 shell 命令“uname -m”獲取架構名稱,結果如下圖所示

從上圖可以看出當前電腦主機架構為“x86_64”, shell 中的“|”表示管道,意思是將左邊的輸出作為右邊的輸入, sed -e 是替換命令,“sed -e s/i.86/x86/”表示將管道輸入的字符串中的“i.86”替換為“x86”,其他的“sed -s”命令同理。對于我的電腦而言, HOSTARCH=x86_64。第 237 行定義了變量 HOSTOS,此變量用于保存主機 OS 的值,先使用 shell 命令“name -s”來獲取主機 OS,結果如下圖所示:

從上圖可以看出此時的主機 OS 為“Linux”,使用管道將“Linux”作為后面“tr ‘[:upper:]’’[:lower:]’”的輸入,“tr ‘[:upper:]’ ‘[:lower:]’”表示將所有的大寫字母替換為小寫字母,因此得到“linux”。最后同樣使用管道,將“linux”作為“sed -e ‘s/(cygwin).*/cygwin/’”的輸入,用于將cygwin.*替換為 cygwin。因此, HOSTOS=linux。

第 240 行導出 HOSTARCH=x86_64, HOSTOS=linux。

2.9 、設置目標架構、交叉編譯器和配置文件

編 譯 uboot 的 時 候 需 要 設 置 目 標 板 架 構 和 交 叉 編 譯 器 ,“ make ARCH=armCROSS_COMPILE=arm-linux-gnueabihf-”就是用于設置 ARCH 和 CROSS_COMPILE,在頂層Makefile 中代碼如下:

第 245 行判斷 HOSTARCH 和 ARCH 這兩個變量是否相等,主機架構(變量 HOSTARCH)是x86_64,而我們編譯的是 ARM 版本 uboot,肯定不相等,所以 CROS_COMPILE= arm-linuxgnueabihf-。

第 249 行定義變量 KCONFIG_CONFIG, uboot 是可以配置的,這里設置配置文件為.config,前面樹莓派學習過: .config 默認是沒有的,需要使用命令“make xxx_defconfig”對 uboot 進行配置,配置完成以后就會在 uboot 根目錄下生成.config。默認情況下.config 和xxx_defconfig 內容是一樣的,因為.config 就是從 xxx_defconfig 復制過來的。如果后續自行調整了 uboot 的一些配置參數,那么這些新的配置參數就添加到了.config 中,而不是 xxx_defconfig。相當于 xxx_defconfig 只是一些初始配置,而.config 里面的才是實時有效的配置。

2.10、調用 scripts/Kbuild.include

主 Makefile 會調用文件 scripts/Kbuild.include這個文件,頂層 Makefile 中代碼如下:

scripts/Kbuild.include文件部分內容:

在 uboot 的編譯過程中會用到 scripts/Kbuild.include 中的這些變量

2.11、交叉編譯工具變量設置

上面我們只是設置了 CROSS_COMPILE 的名字,但是交叉編譯器其他的工具還沒有設置,頂層 Makefile 中相關代碼如下:

3.12、導出其他變量

接下來在頂層 Makefile 會導出很多變量,代碼如下:

這些變量中大部分都已經在前面定義了,我們重點來看一下下面這幾個變量:

ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR


修改好頂層 Makefile 以后,命令行輸入以下命令:

make mytest

結果如圖下所示:

從上圖可以看到這 7 個變量的值,這 7 個變量是從哪里來的呢?在 uboot 根目錄下有個文件叫做 config.mk,這 7 個變量就是在 config.mk(在uboot源碼根目錄下) 里面定義的,打開 config.mk 內容如下:

  • 第 25 行 定 義 變 量 ARCH(架構) , 值 為 $(CONFIG_SYS_ARCH:"%"=%) , 也 就 是 提 取CONFIG_SYS_ARCH 里面雙引號“”之間的內容。比如 CONFIG_SYS_ARCH=“arm”的話,ARCH=arm

  • 第 26 行定義變量 CPU,值為$(CONFIG_SYS_CPU:"%"=%)。

  • 第 32 行定義變量 BOARD(板子),值為(CONFIG_SYS_BOARD:"%"=%)。

  • 第 34 行定義變量 VENDOR,值為$(CONFIG_SYS_VENDOR:"%"=%)。

  • 第 37 行定義變量 SOC,值為$(CONFIG_SYS_SOC:"%"=%)。

  • 第 44 行定義變量 CPUDIR(CPU目錄),值為 arch/( A R C H ) / c p u (ARCH)/cpu(ARCH)/cpu(if ( C P U ) , / (CPU),/(CPU),/(CPU),)。

  • 第 46 行 sinclude 和 include 的功能類似,在 Makefile 中都是讀取指定文件內容,這里讀取文件( s r c t r e e ) / a r c h / (srctree)/arch/(srctree)/arch/(ARCH)/config.mk 的內容。 sinclude 讀取的文件如果不存在的話不會報錯

  • 第 47 行讀取文件( s r c t r e e ) / (srctree)/(srctree)/(CPUDIR)/config.mk 的內容。

  • 第 50 行讀取文件( s r c t r e e ) / (srctree)/(srctree)/(CPUDIR)/$(SOC)/config.mk 的內容。

  • 第 54 行 定 義 變 量 BOARDDIR , 如 果 定 義 了 VENDOR 那 么BOARDDIR=( V E N D O R ) / (VENDOR)/(VENDOR)/(BOARD),否則的 BOARDDIR=$(BOARD)。

  • 第 60 行讀取文件( s r c t r e e ) / b o a r d / (srctree)/board/(srctree)/board/(BOARDDIR)/config.mk

接下來需要找到 CONFIG_SYS_ARCH、 CONFIG_SYS_CPU、 CONFIG_SYS_BOARD、CONFIG_SYS_VENDOR 和 CONFIG_SYS_SOC 這 5 個變量的值。這 5 個變量在 uboot 根目錄下的.config 文件中有定義,定義如下:

根據示例代碼可知:

ARCH = arm CPU = armv7 BOARD = mx6ullevk VENDOR = freescale SOC = mx6 CPUDIR = arch/arm/cpu/armv7 BOARDDIR = freescale/mx6ullevk

在 config.mk 中讀取的文件有:

arch/arm/config.mk arch/arm/cpu/armv7/config.mk arch/arm/cpu/armv7/mx6/config.mk (此文件不存在) board/ freescale/mx6ullevk/config.mk (此文件不存在)

2.13、make xxx_defconfig 過程

在編譯 uboot 之前要使用“make xxx_defconfig”命令來配置 uboot,那么這個配置過程是如何運行的呢?在頂層 Makefile 中有如下代碼:

xxx_defconfig 對應代碼第476行,下面有詳解:


第 422 行定義了變量 version_h,這變量保存版本號文件,此文件是自動生成的。文件include/generated/version_autogenerated.h 內容如下圖所示:

第 423 行定義了變量 timestamp_h,此變量保存時間戳文件,此文件也是自動生成的。文件include/generated/timestamp_autogenerated.h 內容如下圖所示:

  • 第 425 行定義了變量 no-dot-config-targets。

  • 第 429 行定義了變量 config-targets,初始值為 0。

  • 第 430 行定義了變量 mixed-targets,初始值為 0

  • 第 431 行定義了變量 dot-config,初始值為 1。

  • 第 433 行將 MAKECMDGOALS 中不符合 no-dot-config-targets 的部分過濾掉,剩下的如果不為空的話條件就成立。 MAKECMDGOALS 是 make 的一個環境變量,這個變量會保存你所指定的終極目標列表,比如執行“make mx6ull_alientek_emmc_defconfig”,那么 MAKECMDGOALS就為 mx6ull_alientek_emmc_defconfig。很明顯過濾后為空,所以條件不成立,變量 dot-config 依舊為 1。

  • 第439行判斷KBUILD_EXTMOD是否為空,如果KBUILD_EXTMOD為空的話條件成立,經過前面的分析,我們知道 KBUILD_EXTMOD 為空,所以條件成立。

  • 第 440 行將 MAKECMDGOALS 中不符合“config”和“%config”的部分過濾掉,如果剩下的部分不為空條件就成立,很明顯此處條件成立,變量 config-targets=1。

  • 第 442 行統計 MAKECMDGOALS 中的單詞個數,如果不為 1 的話條件成立。此處調用Makefile 中的 words 函數來統計單詞個數, words 函數格式如下:

$(words <text>)

很明顯, MAKECMDGOALS 的單詞個數是 1 個,所以條件不成立, mixed-targets 繼續為0。綜上所述,這些變量值如下:

config-targets = 1 mixed-targets = 0 dot-config = 1
  • 第 448 行如果變量 mixed-targets 為 1 的話條件成立,很明顯,條件不成立。

  • 第 465 行如果變量 config-targets 為 1 的話條件成立,很明顯,條件成立,執行這個分支。

  • 第 473 行,沒有目標與之匹配,所以不執行。

  • 第 476 行,有目標與之匹配,當輸入“make xxx_defconfig”的時候就會匹配到%config 目標,目標“%config”依賴于 scripts_basic、 outputmakefile 和 FORCE。

    • FORCE 在頂層 Makefile的 1610 行有如下定義:

      可以看出 FORCE 是沒有規則和依賴的,所以每次都會重新生成 FORCE。當 FORCE 作為其他目標的依賴時,由于 FORCE 總是被更新過的,因此依賴所在的規則總是會執行的
    • 依賴 scripts_basic 和 outputmakefile 在頂層 Makefile 中的內容如下:
    • 第 408 行,判斷 KBUILD_SRC 是否為空,只有變量 KBUILD_SRC 不為空的時候outputmakefile 才有意義,經過下面的代碼分析 KBUILD_SRC 為空,所以 outputmakefile 無效。只有 scripts_basic 是有效的。

    • 第 396~398 行是 scripts_basic 的規則,其對應的命令用到了變量 Q、 MAKE 和 build,其中:
Q=@或為空 //Q代表要不要顯示完整的命令行,無關緊要 MAKE=make

變量 build 是在 scripts/Kbuild.include 文件中有定義,定義如下:

從代碼可以看出 build=-f $(srctree)/scripts/Makefile.build obj,經過前面的分析可知,變量 srctree 為”.”,因此:

build=-f ./scripts/Makefile.build obj

scripts_basic 展開以后如下:

scripts_basic: @make -f ./scripts/Makefile.build obj=scripts/basic //也可以沒有@,視配置而定 @rm -f . tmp_quiet_recordmcount //也可以沒有@

scripts_basic 會調用文件./scripts/Makefile.build

接著回到示例代碼中的%config 處,內容如下:

%config: scripts_basic outputmakefile FORCE $(Q)$(MAKE) $(build)=scripts/kconfig $@

將命令展開就是:

@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig

同樣也跟文件./scripts/Makefile.build 有關,使用如下命令配置 uboot,并觀察其配置過程:

make mx6ull_14x14_ddr512_emmc_defconfig V=1

配置過程如下圖所示:

從上圖可以看出,我們的分析是正確的,接下來就要結合下面兩行命令重點分析一下文件 scripts/Makefile.build。
①、 scripts_basic 目標對應的命令

@make -f ./scripts/Makefile.build obj=scripts/basic

②、 %config 目標對應的命令

@make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig

2.14、 Makefile.build 腳本分析(接上一節內容)

從上一小節可知,“ make xxx_defconfig“配置 uboot 的時候如下兩行命令會執行腳本scripts/Makefile.build:

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

依次來分析一下:

2.14.1、scripts_basic 目標對應的命令

scripts_basic 目標對應的命令為: @make -f ./scripts/Makefile.build obj=scripts/basic。打開文件 scripts/Makefile.build,有如下代碼:

第 9 行定義了變量 prefix 值為 tpl。

第 10 行定義了變量 src,這里用到了函數 patsubst,此行代碼展開后為:

$(patsubst tpl/%,%, scripts/basic)

patsubst 是替換函數,格式如下:

$(patsubst <pattern>,<replacement>,<text>)

此函數用于在 text 中查找符合 pattern 的部分,如果匹配的話就用 replacement 替換掉。pattenr 是可以包含通配符“%”,如果 replacement 中也包含通配符“%”,那么 replacement 中的這個“%”將是 pattern 中的那個“%”所代表的字符串。函數的返回值為替換后的字符串。因此,第 10 行就是在“scripts/basic”中查找符合“tpl/%”的部分,然后將“tpl/”取消掉,但是“scripts/basic”沒有“tpl/”,所以 src= scripts/basic。

第 11 行判斷變量 obj 和 src 是否相等,相等的話條件成立,很明顯,此處條件成立。

第 12 行和第 9 行一樣,只是這里處理的是“spl”,“scripts/basic”里面也沒有“spl/”,所以src 繼續為 scripts/basic。

第 15 行因為變量 obj 和 src 相等,所以 prefix=.。

繼續分析 scripts/Makefile.build,有如下代碼:

將 kbuild-dir 展開后為:

$(if $(filter /%, scripts/basic), scripts/basic, ./scripts/basic)

因為沒有以“ /”為開頭的單詞,所以$(filter /%, scripts/basic)的結果為空, kbuilddir=./scripts/basic。
將 kbuild-file 展開后為:

$(if $(wildcard ./scripts/basic/Kbuild), ./scripts/basic/Kbuild, ./scripts/basic/Makefile)

因為 scrpts/basic 目錄中沒有 Kbuild 這個文件,所以 kbuild-file= ./scripts/basic/Makefile。最
后將 59 行展開,即:

include ./scripts/basic/Makefile

也就是讀取 scripts/basic 下面的 Makefile 文件。

繼續分析 scripts/Makefile.build,如下代碼:

__build 是默認目標,因為命令“@make -f ./scripts/Makefile.build obj=scripts/basic”沒有指定目標,所以會使用到默認目標: __build。在頂層 Makefile 中, KBUILD_BUILTIN 為 1,KBUILD_MODULES 為 0,因此展開后目標__build 為:

__build:$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always) @:

可以看出目標__build 有 5 個依賴: builtin-target、 lib-target、 extra-y、 subdir-ym 和 always。這 5 個依賴的具體內容我們就不通過源碼來分析了,直接在 scripts/Makefile.build 中輸入圖所示內容,將這 5 個變量的值打印出來:

執行如下命令:

make mx6ull_14x14_ddr512_emmc_defconfig V=1

結果如下圖所示:

從上圖可以看出,只有 always 有效,因此__build 最終為:

__build: scripts/basic/fixdep @:

__build 依賴于 scripts/basic/fixdep,所以要先 scripts/basic/fixdep.c 編譯,生成 fixdep,前面已經讀取了 scripts/basic/Makefile 文件。

綜上所述, scripts_basic 目標的作用就是編譯出 scripts/basic/fixdep 這個軟件(具體作用未知)。

2.14.2、 %config 目標對應的命令

%config 目 標 對 應 的 命 令 為 : @make -f ./scripts/Makefile.build obj=scripts/kconfigxxx_defconfig,各個變量值如下:

src= scripts/kconfig kbuild-dir = ./scripts/kconfig kbuild-file = ./scripts/kconfig/Makefile include ./scripts/kconfig/Makefile

可以看出, Makefilke.build 會讀取 scripts/kconfig/Makefile 中的內容,此文件有如下所示內容:

目標%_defconfig 剛好和我們輸入的 xxx_defconfig 匹配,所以會執行這條規則。依賴為$(obj)/conf,展開后就是 scripts/kconfig/conf。接下來就是檢查并生成依賴 scripts/kconfig/conf。conf 是主機軟件,到這里我們就打住,不要糾結 conf 是怎么編譯出來的,否則就越陷越深,太繞了,像 conf 這種主機所使用的工具類軟件我們一般不關心它是如何編譯產生的。如果一定要看是 conf 是怎么生成的,可以輸入如下命令重新配置 uboot,在重新配置 uboot 的過程中就會輸出 conf 編譯信息。

make distclean make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_ defconfig V=1


得到 scripts/kconfig/conf 以后就要執行目標%_defconfig 的命令:

$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)

相關的變量值如下:

silent=-s 或為空 SRCARCH=.. Kconfig=Kconfig

將其展開就是:

@ scripts/kconfig/conf --defconfig=arch/../configs/xxx_defconfig Kconfig

上述命令用到了 xxx_defconfig 文件,比如 mx6ull_alientek_emmc_defconfig。這里會將mx6ull_alientek_emmc_defconfig 中的配置輸出到.config 文件中,最終生成 uboot 根目錄下的.config 文件。

總結make xxx_defconfig過程


至此,make xxx_defconfig 就分析完了,接下來就要分析一下 u-boot.bin 是怎么生成的了。

2.15、 make 編譯過程

配置好 uboot 以后就可以直接 make 編譯了(也就是前面Makefile配置好哪些C文件需要編譯),因為沒有指明目標,所以會使用默認目標,主Makefile 中的默認目標如下:

目標_all 又依賴于 all,如下所示:

如 果 KBUILD_EXTMOD 為 空 的 話 _all 依 賴 于 all 。 這 里 不 編 譯 模 塊 , 所 以KBUILD_EXTMOD 肯定為空, _all 的依賴就是 all。在主 Makefile 中 all 目標規則如下:

從 802 行可以看出, all 目標依賴$(ALL-y),而在頂層 Makefile 中, ALL-y 如下:

從示例代碼代碼可以看出, ALL-y 包含 u-boot.srec、 u-boot.bin、 u-boot.sym、System.map、 u-boot.cfg 和 binary_size_check 這幾個文件。根據 uboot 的配置情況也可能包含其他的文件,比如:

ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin

CONFIG_ONENAND_U_BOOT 就是 uboot 中跟 ONENAND 配置有關的,如果我們使能了ONENAND,那么在.config 配置文件中就會有“CONFIG_ONENAND_U_BOOT=y”這一句。相當于 CONFIG_ONENAND_U_BOOT 是個變量,這個變量的值為“y”,所以展開以后就是:

ALL-y += u-boot-onenand.bin

這個就是.config 里面的配置參數的含義,這些參數其實都是變量,后面跟著變量值,會在頂層 Makefile 或者其他 Makefile 中調用這些變量。

ALL-y 里面有個 u-boot.bin,這個就是我們最終需要的 uboot 二進制可執行文件,所作的所有工作就是為了它。在頂層 Makefile 中找到 u-boot.bin 目標對應的規則,如下所示

第 825 行判斷 CONFIG_OF_SEPARATE 是否等于 y,如果相等,那條件就成立,在.config中搜索“CONFIG_OF_SEPARAT”,沒有找到,說明條件不成立。

第 832 行就是目標 u-boot.bin 的規則,目標 u-boot.bin 依賴于 u-boot-nodtb.bin,命令為$(callif_changed,copy) , 這 里 調 用 了 if_changed , if_changed 是 一 個 函 數 , 這 個 函 數 在scripts/Kbuild.include 中有定義,而頂層 Makefile 中會包含 scripts/Kbuild.include 文件,這個前面已經說過了。

if_changed 在 Kbuild.include 中的定義如下:

第 227 行為 if_changed 的描述,根據描述,在一些先決條件比目標新的時候,或者命令行有改變的時候, if_changed 就會執行一些命令。

第 257 行就是函數 if_changed, if_changed 函數引用的變量比較多,也比較繞,我們只需要知道它可以從 u-boot-nodtb.bin 生成 u-boot.bin 就行了。

既然 u-boot.bin 依賴于 u-boot-nodtb.bin,那么肯定要先生成 u-boot-nodtb.bin 文件,頂層Makefile 中相關代碼如下:

目標 u-boot-nodtb.bin 又依賴于 u-boot,頂層 Makefile 中 u-boot 相關規則如下:

目標 u-boot 依賴于 u-boot_init、 u-boot-main 和 u-boot.lds, u-boot_init 和 u-boot-main 是兩個變量,在頂層 Makefile 中有定義,值如下:

$ (head-y)跟 CPU 架構有關,我們使用的是 ARM 芯片,所以 head-y 在 arch/arm/Makefile 中被指定為:

head-y := arch/arm/cpu/$(CPU)/start.o

根據分析,我們知道 CPU=armv7,因此 head-y 展開以后就是:

head-y := arch/arm/cpu/armv7/start.o

因此:

u-boot-init= arch/arm/cpu/armv7/start.o

$(libs-y)在頂層 Makefile 中被定義為 uboot 所有子目錄下 build-in.o 的集合,代碼如下:


從上面的代碼可以看出, libs-y 都是 uboot 各子目錄的集合,最后:

libs-y := $(patsubst %/, %/built-in.o, $(libs-y))

這里調用了函數 patsubst,將 libs-y 中的“/”替換為”/built-in.o”,比如“drivers/dma/”就變為了“drivers/dma/built-in.o”,相當于將 libs-y 改為所有子目錄中 built-in.o 文件的集合。那么 uboot-main 就等于所有子目錄中 built-in.o 的集合。

這個規則就相當于將以 u-boot.lds 為鏈接腳本,將 arch/arm/cpu/armv7/start.o 和各個子目錄下的 built-in.o 鏈接在一起生成 u-boot。
u-boot.lds 的規則如下:

u-boot.lds: $(LDSCRIPT) prepare FORCE $(call if_changed_dep,cpp_lds)

接下來的重點就是各子目錄下的 built-in.o 是怎么生成的,以 drivers/gpio/built-in.o 為例,在drivers/gpio/目錄下會有個名為.built-in.o.cmd 的文件,此文件內容如下:

cmd_drivers/gpio/built-in.o := arm-linux-gnueabihf-ld.bfd -r -o drivers/gpio/built-in.o drivers/gpio/mxc_gpio.o

從命令“cmd_drivers/gpio/built-in.o”可以看出, drivers/gpio/built-in.o 這個文件是使用 ld 命令由文件 drivers/gpio/mxc_gpio.o 生成而來的, mxc_gpio.o 是 mxc_gpio.c 編譯生成的.o 文件,這個是 NXP 的 I.MX 系列的 GPIO 驅動文件。這里用到了 ld 的“-r”參數,參數含義如下:

-r –relocateable: 產生可重定向的輸出,比如,產生一個輸出文件它可再次作為‘ld’ 的輸入,這經常被叫做“部分鏈接”,當我們需要將幾個小的.o 文件鏈接成為一個.o 文件的時候,需要使用此選項。

最終將各個子目錄中的 built-in.o 文件鏈接在一起就形成了 u-boot,使用如下命令編譯 uboot就可以看到鏈接的過程:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_ defconfig V=1 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- V=1

編譯的時候會有如下圖所示內容輸出:

grep命令搜索ox87800000

將其整理一下,內容如下:

arm-linux-gnueabihf-ld.bfd -pie --gc-sections -Bstatic -Ttext 0x87800000 \ -o u-boot -T u-boot.lds \ arch/arm/cpu/armv7/start.o \ --start-group arch/arm/cpu/built-in.o \ arch/arm/cpu/armv7/built-in.o \ arch/arm/imx-common/built-in.o \ arch/arm/lib/built-in.o \ board/freescale/common/built-in.o \ board/freescale/mx6ull_alientek_emmc/built-in.o \ cmd/built-in.o \ common/built-in.o \ disk/built-in.o \ drivers/built-in.o \ drivers/dma/built-in.o \ drivers/gpio/built-in.o \ …… drivers/spi/built-in.o \ drivers/usb/dwc3/built-in.o \ drivers/usb/emul/built-in.o \ drivers/usb/eth/built-in.o \ drivers/usb/gadget/built-in.o \ drivers/usb/gadget/udc/built-in.o \ drivers/usb/host/built-in.o \ drivers/usb/musb-new/built-in.o \ drivers/usb/musb/built-in.o \ drivers/usb/phy/built-in.o \ drivers/usb/ulpi/built-in.o \ fs/built-in.o \ lib/built-in.o \ net/built-in.o \ test/built-in.o \ test/dm/built-in.o \ --end-group arch/arm/lib/eabi_compat.o \ -L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linuxgnueabihf/4.9.4 -lgcc -Map u-boot.map

可以看出最終是用 arm-linux-gnueabihf-ld.bfd 命令將 arch/arm/cpu/armv7/start.o 和其他眾多的 built_in.o 鏈接在一起,形成 u-boot。

目標 all 除了 u-boot.bin 以外還有其他的依賴,比如 u-boot.srec 、 u-boot.sym 、 System.map、u-boot.cfg 和 binary_size_check 等等,這些依賴的生成方法和 u-boot.bin 很類似

總結make命令的流程

make xxx_defconfig: 用于配置 uboot,這個命令最主要的目的就是生成.config 文件。

make:用于編譯 uboot,這個命令的主要工作就是生成二進制的 u-boot.bin 文件和其他的一些與 uboot 有關的文件,比如 u-boot.imx 等等

總結

以上是生活随笔為你收集整理的U-Boot顶层Makefile分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

91精品久久香蕉国产线看观看 | 九九视频网站 | 成人性生交大片免费观看网站 | 成人在线播放免费观看 | 国产精品丝袜在线 | 99中文字幕 | 国色天香在线 | 国产在线资源 | 久草国产精品 | 国产精品永久免费在线 | 手机成人在线 | 国产69精品久久99不卡的观看体验 | 亚洲欧美乱综合图片区小说区 | 国产视频美女 | 亚洲高清在线精品 | 久久无码精品一区二区三区 | 99国产成+人+综合+亚洲 欧美 | 亚州av成人| 天天操天天操天天爽 | 韩国一区二区av | 国产精品久久久久aaaa九色 | 少妇性xxx| 亚洲另类视频在线观看 | 久久精品视频99 | 狠狠的操狠狠的干 | 91在线精品观看 | 日韩有码专区 | 日韩区欠美精品av视频 | 激情五月开心 | 我爱av激情网 | 久久全国免费视频 | 91人人插| 一二三精品视频 | 免费高清在线观看成人 | 国产一区网址 | 久久精品成人欧美大片古装 | 97超碰人人澡人人爱学生 | 亚洲一二三在线 | www.夜夜操 | 99热 精品在线 | 成人av免费在线 | 亚洲另类交 | 在线看免费 | 91片黄在线观 | 亚洲视频,欧洲视频 | av资源在线看 | 亚洲无人区小视频 | 天堂激情网 | 一区二区三区动漫 | 一区二区三区 中文字幕 | 一级黄色在线视频 | 成人精品亚洲 | 亚洲视频综合 | 国产小视频你懂的 | 少妇bbw搡bbbb搡bbbb | 欧美一级专区免费大片 | 福利电影久久 | 久久成人久久 | 五月天色综合 | 国产黄色免费观看 | 超碰大片 | 欧美乱淫视频 | 手机成人av在线 | 日本韩国中文字幕 | 国产一级电影 | 免费看的黄色片 | 国产午夜麻豆影院在线观看 | 成人av在线影视 | www.狠狠干| 91九色网站 | 午夜av免费看 | 亚洲乱码在线观看 | 91av视频网 | 蜜臀久久99精品久久久无需会员 | 国产成a人亚洲精v品在线观看 | 欧美色图88 | 欧美激情第十页 | 97超碰人人爱 | 高潮久久久久久 | 天天se天天cao天天干 | 在线观看你懂的网站 | 成人黄色大片在线免费观看 | 国产精品美女久久久久久网站 | 99人成在线观看视频 | 黄色在线观看污 | 精品黄色片 | 五月天婷亚洲天综合网精品偷 | 91丨九色丨首页 | 国产中文自拍 | 大胆欧美gogo免费视频一二区 | 91精品免费在线 | 日韩大片免费在线观看 | 久久小视频 | 国产一级性生活 | 视频在线观看一区 | 国产又粗又猛又色又黄网站 | 亚洲黄色片一级 | 免费看黄的视频 | 日韩欧美一区二区三区视频 | 中文字幕一区二区在线观看 | 中文字幕在线播放日韩 | 97国产精品亚洲精品 | 色天天综合网 | 久久九精品 | 五月天久久精品 | 国产精品理论在线观看 | 亚洲 欧洲 国产 精品 | 2021av在线 | 成人精品视频久久久久 | 久久婷婷影视 | 欧美午夜性生活 | 色丁香婷婷 | 日本午夜在线观看 | 日韩av播放在线 | 中文字幕在线观看网 | 日狠狠 | 日韩精品一区二 | 国产精品理论在线观看 | 黄色日批网站 | 91资源在线播放 | 人人舔人人爱 | 亚洲最新在线 | 午夜av剧场| 在线中文字幕av观看 | 欧美色图另类 | www.一区二区三区 | 日韩动态视频 | 国产在线观看午夜 | 国产一级二级在线观看 | 婷婷深爱网 | 国产二区免费视频 | 日韩精品 在线视频 | 国产亚洲视频在线观看 | 亚洲成人黄色 | 日韩激情三级 | 夜夜天天干 | 久久香蕉国产精品麻豆粉嫩av | 久久久久久久综合色一本 | 成年美女黄网站色大片免费看 | 欧洲亚洲女同hd | 午夜精品久久久久99热app | 久久免费视频在线观看 | 久久国产精品99久久久久久老狼 | 欧美最猛性xxx | 国产精品乱码久久久久 | 激情五月播播久久久精品 | av黄免费看 | 午夜av在线电影 | 在线观看黄污 | 婷婷精品进入 | 91精品蜜桃 | 99精品久久久久久久 | 久久久午夜剧场 | 韩国av电影网 | 福利一区在线 | 国产福利一区二区三区视频 | 狠狠干狠狠久久 | 日日麻批40分钟视频免费观看 | 69亚洲精品| 色偷偷男人的天堂av | 一区二区视频播放 | 中文字幕资源在线 | 国内精品美女在线观看 | 精品国产91亚洲一区二区三区www | 国产中文字幕在线观看 | www.xxxx变态.com | 国产一在线精品一区在线观看 | 久久成人一区 | 日日夜夜天天久久 | 国产成人61精品免费看片 | 国产一级免费播放 | 国产99久久精品一区二区永久免费 | 日韩剧情 | 国产视频2 | 在线观看视频一区二区三区 | 天天色天天操天天爽 | 人人澡人人干 | 欧美一级特黄aaaaaa大片在线观看 | 国产成人一区二区精品非洲 | 国产精品午夜在线观看 | 久久国色夜色精品国产 | 五月婷婷久 | 亚洲午夜精品电影 | 久久久精品国产一区二区 | 午夜视频导航 | 美女露久久| 热久久99这里有精品 | 黄色软件视频网站 | 亚洲男男gaygay无套同网址 | 99久久精品午夜一区二区小说 | 成人超碰在线 | 欧美色插 | 九九免费在线观看 | av大全在线 | 国产区在线看 | 国产午夜av| 久久精品网站免费观看 | 国产不卡在线观看视频 | 天堂黄色片 | 国产手机视频在线观看 | 久久精品国产亚洲a | 久久久久99999 | 99久久久免费视频 | 日韩免费av网址 | 久日视频 | 国产精品午夜在线 | www.av中文字幕.com | 国内精品福利视频 | 在线观看mv的中文字幕网站 | 成年人视频在线 | 天天草av | 欧美巨大荫蒂茸毛毛人妖 | 日韩av一区二区三区在线观看 | 色香蕉视频 | 99热这里只有精品1 av中文字幕日韩 | 午夜视频在线瓜伦 | 69xxxx欧美 | 国产一区免费 | 久久曰视频 | 欧美综合久久久 | 麻豆国产在线播放 | 久久精品欧美一 | 天天综合网入口 | 伊人网站 | 中文在线a√在线 | 日韩欧美精品一区二区三区经典 | 成人黄色片免费看 | 久久久久久久久久福利 | 久草国产在线观看 | 亚洲视频免费在线看 | 国产亚洲精品bv在线观看 | 天天操天天摸天天干 | 天天做天天看 | 蜜臀久久99静品久久久久久 | 日韩电影精品一区 | 激情综合色综合久久 | 色天天综合久久久久综合片 | 97超碰站| 中文字幕第 | 免费在线观看日韩 | 欧美日韩一区三区 | 在线观看视频你懂的 | 干av在线 | 高清av中文字幕 | 婷婷新五月 | av在线观| 久久精品国产免费看久久精品 | 在线色亚洲| 超碰97中文| 亚洲视频每日更新 | 波多野结衣在线观看一区二区三区 | 一本一道久久a久久综合蜜桃 | 日本久久久久久久久久 | 日本久久91 | www.福利| 国产一级小视频 | 国产在线91精品 | 人人爽人人爽人人片 | 国产老太婆免费交性大片 | 亚洲人天堂 | 最新久久免费视频 | 7777精品伊人久久久大香线蕉 | 久久久受www免费人成 | 久久66热这里只有精品 | 国产精品久久久久免费观看 | 9999毛片| 日本高清中文字幕有码在线 | 亚洲成av人片一区二区梦乃 | 久久久久五月天 | 免费欧美高清视频 | 亚洲久久视频 | 九九热在线精品视频 | 日本久久久精品视频 | 在线观看视频国产一区 | 国产美女精品人人做人人爽 | 日韩久久一区二区 | 国产综合在线观看视频 | 四虎视频 | 99精品国产一区二区三区麻豆 | 日韩影视在线观看 | 中文字幕中文字幕在线中文字幕三区 | 日韩国产欧美在线视频 | 国产成人61精品免费看片 | 狠狠色丁香婷婷综合基地 | 国产亚洲情侣一区二区无 | 在线观看日韩视频 | 久99久视频| 毛片.com | 国产99久久久久 | av资源中文字幕 | 在线看成人片 | 日韩av资源在线观看 | 又黄又刺激又爽的视频 | 激情av综合| 99久久er热在这里只有精品15 | 成人动态视频 | 亚洲 综合 国产 精品 | 精品久久久免费 | 国产玖玖视频 | 国产在线观看中文字幕 | 日本狠狠色 | 99色网站 | 国产精品18久久久 | 国产成人黄色在线 | 国产在线播放一区二区三区 | 欧美国产视频在线 | 日本韩国中文字幕 | 不卡视频在线看 | 日本h视频在线观看 | 九月婷婷色 | 亚洲精品在线视频播放 | 午夜精品久久久久久 | 黄色大片入口 | 黄色大片网 | 欧美日韩免费一区 | 午夜精品一区二区三区在线 | 天天拍天天干 | 国产一级不卡视频 | 久久久免费在线观看 | 亚洲专区路线二 | 97在线免费观看视频 | 久久久国产精品免费 | 日本中文字幕免费观看 | 手机看片1042 | 久久66热这里只有精品 | 久久精品久久国产 | 国产小视频在线免费观看 | 91在线视频观看免费 | 亚洲视频久久久久 | 99久久久久国产精品免费 | 日韩欧美在线综合网 | 国产午夜精品一区二区三区嫩草 | 欧美日韩视频一区二区 | 亚洲国产精品影院 | 五月婷婷丁香六月 | 日韩在线观看第一页 | 免费看的毛片 | 国产成人99久久亚洲综合精品 | 中文字幕在线播放日韩 | 日本三级大片 | 永久免费的啪啪网站免费观看浪潮 | 一级成人免费视频 | 在线视频久久 | 久草在线视频首页 | 在线影院av | 五月婷综合网 | 黄a在线| 亚洲国产丝袜在线观看 | 国产亚洲无 | 日韩视频中文字幕 | 亚洲男人天堂2018 | 国产精品美女久久久久久久久 | 二区三区视频 | 91人人澡人人爽 | 国产成人av福利 | 免费观看一区二区三区视频 | 可以免费观看的av片 | 91中文字幕在线观看 | 国产综合激情 | 国产人成看黄久久久久久久久 | 亚洲最大av| 日韩有码第一页 | 四虎影视www | 久久成人黄色 | 99欧美精品 | 黄色成人小视频 | 欧美日韩一区二区三区视频 | 久久99精品国产 | 欧美性色xo影院 | 久久精品国产精品亚洲 | 中文字幕2021| 丁香色天天 | 伊人婷婷久久 | 国产亚洲精品久久久久久久久久 | 日韩高清免费电影 | 久久99精品一区二区三区三区 | 91网页版在线观看 | 免费看片成人 | 久久毛片网 | 午夜久久福利 | 亚洲高清免费在线 | 久久国产欧美日韩精品 | 久久99深爱久久99精品 | 99精品国自产在线 | 国产黄色片一级三级 | 五月婷婷色丁香 | 日韩中文字幕在线 | 最近免费中文视频 | av一级在线观看 | 四虎www.| 久久精品国产精品亚洲精品 | 日韩.com | 午夜精品一区二区三区在线观看 | 一区二区中文字幕在线播放 | 久久久久色 | 国产色拍拍拍拍在线精品 | av在线激情| 日韩欧美网址 | av中文字幕电影 | 免费a级毛片在线看 | 波多野结衣综合网 | 国产精品毛片一区二区 | 精品视频在线看 | 免费激情在线电影 | 夜夜躁日日躁 | 亚洲专区欧美 | 一区三区在线欧 | 精品免费一区二区三区 | 国产小视频在线看 | 国产精品免费久久久久影院仙踪林 | 久久综合久久综合九色 | 一区二区三区韩国免费中文网站 | 日日操天天操夜夜操 | 国产一级视频在线观看 | 九九九热精品免费视频观看网站 | 国产精品 中文在线 | 成年美女黄网站色大片免费看 | 亚洲小视频在线观看 | www日韩欧美 | 国产精品一区二区三区免费视频 | 中文字幕九九 | 一级做a视频 | 国产成人黄色网址 | 国产精品video | 久久国产美女视频 | 黄在线免费看 | 免费日韩三级 | 久久九九网站 | 色综合久久久久网 | 午夜天天操 | 黄色网在线播放 | 成人午夜在线观看 | 99re国产视频| 91精品视频在线免费观看 | 99麻豆视频| 激情av网址 | 丰满少妇高潮在线观看 | 国产高清精品在线 | 国产高清视频在线免费观看 | 国产无吗一区二区三区在线欢 | 九九热久久免费视频 | 久久免费视频网 | 国产精品视频最多的网站 | 日韩黄色av网站 | 超碰在线观看av.com | 国产精品久久久区三区天天噜 | 91精品国产99久久久久久久 | 在线观看中文字幕一区二区 | 97人人添人澡人人爽超碰动图 | 久久国产精品色av免费看 | 在线成人国产 | 国产亚洲精品久久久久久久久久 | 国产精品久久久毛片 | 在线天堂日本 | 在线免费av网 | 久久精品男人的天堂 | av经典在线| 日韩av片在线| 成人一级在线观看 | 黄色午夜 | 亚洲日本va午夜在线影院 | 久久久久五月 | 婷婷丁香激情五月 | 国产高清免费在线观看 | 亚洲精品影视 | 国产一区二区久久 | 欧美成人影音 | 国产福利一区二区三区视频 | 欧美日韩亚洲在线观看 | 美女黄濒| 特级毛片网 | 免费在线观看不卡av | 日韩理论在线观看 | av免费福利 | 91免费版成人 | 人人爱爱 | 精品久久久影院 | 狠狠干网 | 欧美性春潮 | 97超碰人人干 | 深夜激情影院 | 亚洲精品国产精品国自产观看浪潮 | 免费成人在线观看 | 亚洲日本三级 | 日韩久久久久久久久久久久 | 精品96久久久久久中文字幕无 | 久久精品一区二区三区视频 | 97久久精品午夜一区二区 | 主播av在线| 国产涩图| www.com黄| 久久不卡视频 | 欧美a免费 | 一区二区三区韩国免费中文网站 | 超碰国产97| 日韩a欧美| 在线观看日韩一区 | a国产精品 | 国产精品久久久久久久久久久久午夜片 | 午夜aaaa | 欧美性久久久久久 | 美女网站在线观看 | 国产精品福利久久久 | 人人干狠狠干 | 在线 精品 国产 | 欧美无极色| 欧美性大战久久久久 | 男女视频国产 | 日韩av免费一区二区 | 五月天色中色 | 久九视频 | 久久爱资源网 | 国产精品五月天 | 国内揄拍国内精品 | 日本性久久 | 久久综合操 | 色 中文字幕 | 国产成人av福利 | .精品久久久麻豆国产精品 亚洲va欧美 | 久久综合福利 | 一区二区三区 亚洲 | 在线v片| 国产一级一片免费播放放 | 成年人黄色免费网站 | 久久国产经典视频 | 日韩国产精品一区 | 欧美日韩国产精品一区二区亚洲 | 亚洲电影黄色 | 午夜美女av| 欧美激情va永久在线播放 | 久久中文精品视频 | 久久国产精品一区二区三区四区 | 婷婷久久婷婷 | 超碰97网站 | 91福利视频网站 | 九九热久久免费视频 | 99情趣网视频 | 高清不卡免费视频 | 国产一区二区日本 | 亚洲精品小视频 | 久久久久久久久网站 | 中文字幕在线久一本久 | 91视频-88av | 成人在线视频你懂的 | 日韩在线免费 | 天天搞夜夜骑 | 日本三级香港三级人妇99 | 欧美精品久久久久久久久免 | 成人国产精品一区 | 国产精品福利无圣光在线一区 | 蜜桃视频成人在线观看 | 精品在线免费观看 | 国产在线 一区二区三区 | 91麻豆精品国产自产在线游戏 | 久久黄网站 | 91欧美日韩国产 | 成人在线观看日韩 | 成人黄色大片在线观看 | 国产精品99久久久久久久久久久久 | 特级免费毛片 | 在线午夜电影神马影院 | 亚洲精品在线观看av | 99re国产| 激情欧美在线观看 | 日日日视频 | 欧美人人 | 亚洲午夜久久久久久久久 | 国产午夜精品一区二区三区欧美 | 色噜噜狠狠狠狠色综合久不 | 日韩在线视频不卡 | 亚洲国产视频直播 | 激情综合色综合久久综合 | 久久公开免费视频 | 成人午夜剧场在线观看 | 在线播放国产一区二区三区 | 伊人看片| 欧美久久成人 | www.久久色.com| www久久| 又黄又色又爽 | 激情综合五月天 | 久久99精品久久久久婷婷 | 国产精品女人网站 | 特黄特色特刺激视频免费播放 | 黄色av电影 | 国产一级免费观看视频 | 亚洲另类在线视频 | 日韩精品一区二区三区电影 | 国产一区免费看 | 亚洲另类视频在线观看 | 91成人在线观看高潮 | 国产精品久久久久久久久久久免费 | 欧美色图视频一区 | 永久免费毛片 | 成年人在线免费看视频 | 欧美日韩一区二区三区不卡 | 欧美大香线蕉线伊人久久 | 91av视频免费观看 | 91精品国产91久久久久久三级 | 日日夜夜中文字幕 | 成人久久精品视频 | 天天爽夜夜爽精品视频婷婷 | 正在播放国产一区二区 | 中文字幕在线观看完整 | 伊人午夜视频 | 91精品在线免费观看 | 久热爱| 免费看91的网站 | 久久香蕉国产精品麻豆粉嫩av | 成年人视频在线观看免费 | 中文字幕视频在线播放 | 久草免费资源 | 久久久视屏 | 9999精品 | 成人av一区二区在线观看 | 国产精品一区二区62 | 欧亚久久 | 国产69精品久久久久久久久久 | 色99中文字幕 | 特级xxxxx欧美 | 日韩综合第一页 | 一本到在线 | 成人免费观看网站 | 一区在线电影 | 国产xxxx| 成人黄色电影在线观看 | 97国产一区二区 | 91精品在线免费视频 | 97国产视频| 手机av在线不卡 | 精品国模一区二区 | 亚洲涩涩涩 | 97在线免费视频观看 | 69视频在线 | 91资源在线播放 | 色五月激情五月 | 日韩特级毛片 | 在线观看免费一区 | 国产精品一区二区 91 | 91在线精品一区二区 | 在线91播放 | 97精品久久 | 91精品国产99久久久久久久 | 在线观看视频国产一区 | 黄色一集片| 激情网第四色 | 亚洲第一av在线 | 久久高清免费视频 | 最新一区二区三区 | 免费视频97 | 最新不卡av | 国产小视频免费在线观看 | 日日夜夜添 | 色播激情五月 | 久久艹国产 | 91香蕉视频720p | 一级片免费在线 | 久草在线资源免费 | 欧美色久| 天天干天天在线 | 欧美日韩中文在线 | av导航福利 | 日韩欧美在线播放 | 精品女同一区二区三区在线观看 | 日韩系列在线 | 国产99久久九九精品免费 | 有没有在线观看av | 天堂在线一区 | 国产午夜精品久久久久久久久久 | 欧美伦理一区二区三区 | 亚洲精品国产精品国自产 | 黄色aa久久 | 91麻豆精品国产91久久久无限制版 | 亚洲精品美女在线观看播放 | 色综合五月| 国产精品久久二区 | 成人av在线影视 | 亚洲自拍av在线 | 99精品电影 | 视频在线一区 | 天天草av | 亚洲片在线| 热久久视久久精品18亚洲精品 | 精品国产乱码久久久久 | 精品在线观看一区二区三区 | 国产日韩高清在线 | 国产精品自产拍在线观看 | 国产精品久久久久久久久久免费看 | 久久国产亚洲视频 | www国产精品com | 精品一区二区亚洲 | 色综合五月 | 久久avav | 成人午夜精品久久久久久久3d | 国产成人免费网站 | 伊人资源站 | 韩国av免费观看 | 亚洲视频电影在线 | 国产黄色视| 麻豆视频国产在线观看 | 日韩在线 | 国产综合在线观看视频 | 欧美日本高清视频 | 国产一级黄色av | 国产精品乱码一区二三区 | 免费观看久久 | 亚洲精品视频中文字幕 | 日韩视频1 | 98精品国产自产在线观看 | 免费看v片 | 久草网在线观看 | 中文字幕亚洲欧美日韩 | 91九色蝌蚪视频在线 | 亚洲黄色在线免费观看 | 久久欧美综合 | 婷婷精品国产欧美精品亚洲人人爽 | 免费视频资源 | 激情影音 | 久久人人艹| 欧美日韩国产综合网 | 国产在线高清视频 | 日韩电影中文字幕在线观看 | 亚洲福利精品 | 九九九九热精品免费视频点播观看 | www91在线观看| 特片网久久 | 国产精品一区二区av日韩在线 | 久久久精品国产免费观看一区二区 | 国产一区二区网址 | 成人中文字幕av | 亚洲一区精品二人人爽久久 | 一级黄色片毛片 | 九九九热精品免费视频观看网站 | 国产在线欧美 | 婷婷六月综合亚洲 | 国产一区二区手机在线观看 | 黄色影院在线观看 | 日韩视频在线不卡 | 久久成人人人人精品欧 | 婷婷六月中文字幕 | 国产精品一区二区免费视频 | 国产精品免费久久久久久 | 欧美日韩免费在线视频 | 亚洲精品美女视频 | 黄色一级免费电影 | 黄色天堂在线观看 | 天天干天天操天天拍 | 国产精品久久久免费 | 欧美久久久久久久久中文字幕 | 九九免费在线视频 | 天堂入口网站 | 黄色精品免费 | 日韩一区精品 | 久久图 | 在线日本v二区不卡 | 亚洲视频久久 | 久久成年人网站 | 日本成人中文字幕在线观看 | 久久精品二区 | 久久99亚洲热视 | 日韩色在线 | 久久国产精品成人免费浪潮 | 国产麻豆视频网站 | 成在人线av | 欧美日韩伦理在线 | 丁香花在线视频观看免费 | 欧美污网站 | 国产91大片| 丁香六月激情婷婷 | 久久久高清 | 欧美日韩一区二区三区在线观看视频 | 国产99久久九九精品免费 | 婷婷爱五月天 | 99精品免费 | 中文字幕在线人 | 波多野结衣视频一区二区三区 | 最新免费中文字幕 | 日韩精品中文字幕在线观看 | 国产黄色片久久久 | 午夜av影院| avwww在线| 国产一区电影在线观看 | 国内视频一区二区 | 激情久久五月 | 在线成人免费电影 | www.夜夜骑.com | 欧美ⅹxxxxxx | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 日韩精品一区二区三区在线播放 | 伊人中文在线 | 久久久视频在线 | av福利在线看 | 国产精品麻豆果冻传媒在线播放 | 国产精品99久久久久久人免费 | 国产99久久久久久免费看 | 美女视频是黄的免费观看 | 日韩区视频 | 日韩免费大片 | 国产精品入口麻豆www | 成人免费视频视频在线观看 免费 | 中文字幕亚洲综合久久五月天色无吗'' | 91在线入口 | 国产精品久久网 | 国产一性一爱一乱一交 | 在线免费观看视频你懂的 | 69绿帽绿奴3pvideos | 国产精品毛片一区视频播 | 99精品久久久| 99精品久久精品一区二区 | 久久精品视频播放 | 韩国一区二区在线观看 | 色综合久久久久综合 | 黄色大片免费网站 | 欧美一级电影片 | 91在线免费视频 | 日韩专区中文字幕 | 香蕉网在线观看 | 日韩免费 | av韩国在线 | 美女视频是黄的免费观看 | av免费福利| 中文字幕在线观看免费观看 | 亚洲无线视频 | 欧美日韩国产二区三区 | 夜夜爽夜夜操 | 国产精品久久久av久久久 | 91在线视频在线观看 | 午夜精品一区二区三区免费 | 91成人短视频在线观看 | 色偷偷97 | 麻豆视频网址 | 免费亚洲黄色 | 免费看的黄色片 | 国产99久久久国产精品免费看 | 久久久久在线视频 | 99精品国产99久久久久久福利 | 又黄又爽又无遮挡免费的网站 | 爱爱av在线 | 中文字幕国产一区二区 | 国产精品观看 | 亚洲精品九九 | 91资源在线播放 | 午夜精品导航 | 操久久网| 国产精品一区久久久久 | 久青草电影| 亚洲欧美色婷婷 | 国产 在线观看 | 亚洲蜜桃在线 | 蜜臀av夜夜澡人人爽人人 | 夜夜爽88888免费视频4848 | 激情综合啪啪 | 国内精品毛片 | 久久不射影院 | 日韩电影中文字幕在线 | 免费福利在线视频 | 久久在线看 | 国产免费二区 | 国产99久久久精品 | 在线免费观看视频一区 | 黄色av成人在线 | 99在线精品视频 | 成人资源在线播放 | 丁香五香天综合情 | 99精品色 | 91精品在线播放 | 午夜精品一区二区三区四区 | 成人a免费 | 久久一区二区三区日韩 | 亚洲精品乱码久久久久久按摩 | 日日婷婷夜日日天干 | 国产精品日韩精品 | av一级片在线观看 | 国内精品久久久久影院一蜜桃 | 91chinese在线 | 亚洲精品乱码久久久久久蜜桃欧美 | 粉嫩av一区二区三区入口 | 国产91亚洲 | 中文字幕日本在线 | 美女网站在线观看 | 在线视频观看成人 | 午夜久久久久久久 | 婷婷5月色 | 久久久国内精品 | 欧美日产一区 | 国产99久久九九精品免费 | 四虎伊人 | 麻花传媒mv免费观看 | 国产无吗一区二区三区在线欢 | 午夜三级福利 | 免费观看的av网站 | 日本不卡一区二区三区在线观看 | 丁香在线观看完整电影视频 | 日韩欧美在线高清 | 在线国产能看的 | 一区二区男女 | 亚洲 欧美 另类人妖 | 97视频免费 | 日韩在线| 深爱婷婷网| 亚洲一级片免费观看 | 亚洲精品久 | 亚洲成人精品在线 | 免费在线视频一区二区 | 在线观看一区视频 | 久久久精品99 | 黄a网站 | 亚洲精品av中文字幕在线在线 | 国产精品免费一区二区 | 久久午夜网 | 国产美女精彩久久 | 天天干,天天操,天天射 | 九九视频精品在线 | 国产精品一区二区免费在线观看 | 黄色毛片在线看 | 九色在线 | 欧美韩国在线 | 九九热在线观看视频 | 亚洲最新视频在线 | 欧美一区二区三区不卡 | 日韩av一区二区三区在线观看 | 久久dvd | 欧美在线视频第一页 | 欧美 日韩 性 | 色噜噜在线观看 | 又色又爽又激情的59视频 | 日韩久久精品 | 久久综合免费视频影院 | 国产不卡av在线播放 | 中文字幕一区二区三区乱码在线 | 中文成人字幕 | 久久精品国产亚洲 | 欧美91精品国产自产 | 日本成人黄色片 | 亚洲欧美激情精品一区二区 | 国产成人高清 | 久久精品欧美视频 | 久久国语露脸国产精品电影 | 手机成人av在线 | 久草在线在线精品观看 | 国产亚洲人 | 91在线入口| 91精品在线播放 | 国产精品嫩草影院123 | jizz18欧美18| 精品毛片一区二区免费看 | 国产一区福利在线 | 久久精品免费看 | 韩国av电影在线观看 | 一级片视频免费观看 | 国产在线a视频 | 中文字幕色在线 | 亚洲资源视频 | 一级免费观看 | 国产又粗又猛又爽又黄的视频免费 | 亚洲一级黄色av | 日韩午夜在线 | 国产精品欧美激情在线观看 | 亚洲全部视频 | 免费看的毛片 | 色婷婷av国产精品 | 韩国av免费观看 | 在线观看精品国产 | 日韩精品免费一线在线观看 | 丁香五婷| 成人免费视频a | 精品免费久久 | 91精品国产欧美一区二区成人 | 毛片无卡免费无播放器 | 欧洲av不卡 | 久久国产视频网站 | 国产高清免费av | 2019精品手机国产品在线 | 日韩欧美视频一区二区 | 狠狠的干狠狠的操 | 国产亚州av| 国产日产精品一区二区三区四区的观看方式 | 国产大尺度视频 | 伊人欧美 | 欧美精品久久人人躁人人爽 | 久久久在线免费观看 | www.香蕉视频在线观看 | 久草www | 欧美在线观看视频免费 | 黄色在线免费观看网址 | 国产在线中文 | 国产中文字幕亚洲 | 日韩精品一区二区免费 | 免费黄色网址大全 | 麻豆免费视频 | 国产小视频福利在线 | 国产精品成 | 99九九免费视频 | 国产999视频 | 国产一区二区不卡在线 | 国产高清视频免费观看 | 97超碰影视 | 久久久精品成人 |