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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

uboot启动流程详细分析(基于i.m6ull)

發布時間:2024/1/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uboot启动流程详细分析(基于i.m6ull) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

uboot介紹

uboot就是一段引導程序在加載系統內核之前,完成硬件初始化,內存映射,為后續內核的引導提供一個良好的環境。uboot是bootloader的一種,全稱為universal boot loader。

一、uboot的makefile

1.1 makefile整體解析過程

為了生成u-boot.bin這個文件,首先要生成構成u-boot.bin的各個庫文件、目標文件。為了各個庫文件、目標文件就必須進入各個子目錄執行其中的Makefile。由此,確定了整個編譯的命令和順序。

1.2 makefile整體編譯過程

  • 首先,根據各個庫文件、目標文件出現的先后順序,依次進入各個子目錄編譯從而生成這些目標
  • 然后,回到頂層目錄,繼續執行頂層Makefile的總目標,最后生成u-boot.bin。

uboot的編譯分為兩步:配置、編譯。

(1)第一步:配置,執行make pangu_basic_defconfig進行配置,生成.config文件

(2)第二步:編譯,執行make進行編譯,生成u-boot.bin

二、uboot啟動流程

  • uboot分為 uboot-spl 和 uboot 兩個組成部分。

uboot啟動分三個階段

  • BL0
    ROM上的固化程序(Boot Rom)

  • BL1(u-boot-spl)

    • 初始化部分時鐘(和SDRAM相關)
    • 初始化DDR(外部SDRAM)
    • 從存儲介質上(比如SD\eMMC\nand flash)將BL2鏡像加載到SDRAM上
    • 驗證BL2鏡像的合法性
    • 跳轉到BL2鏡像所在的地址上
  • BL2 (uboot)
    • 初始化部分硬件,包括時鐘、內存等等
    • 加載內核到內存上
    • 加載文件系統、atags或者dtb到內存上
    • 根據操作系統啟動要求正確配置好一些硬件

    啟動操作系統

    2.1 uboot的鏈接文件(u-boot.lds)

    鏈接文件的作用

  • 指定代碼段和數據段、只讀數據段在內存中的存放地址;(地址具體為i.m6ull , 其他芯片可能不是 0X87800000)

    • u-boot.map 是 uboot 的映射文件,看到某個文件或者函數鏈接到了哪個地址,

    • __image_copy_start 為 0X87800000,而.text 的起始地址也是0X87800000。

    • vectors 段保存中斷向量表,vectors 段的起始地址也是 0X87800000,說明整個 uboot 的起始地址就是 0X87800000,

    • 這也是為什么我們裸機例程的鏈接起始地址選擇 0X87800000 了,目的就是為了和 uboot 一致。

  • 指定代碼的入口地址;

    • 連接文件中找到程序的入口點:_start, 其中_start 在文件 arch/arm/lib/vectors.S 。
  • 2.2 uboot啟動流程

    第一階段(uboot-spl , 入口是上述lds文件中分析的_start)

    • SPL是Secondary Program Loader的簡稱,第二階段程序加載器,這里所謂的第二階段是相對于SOC中的Boot ROM來說的

    Boot ROM會通過檢測啟動方式來加載第二階段bootloader。uboot已經是一個bootloader了,那么為什么還多一個uboot spl呢?

    • 這個主要原因是對于一些SOC來說,它的內部SRAM可能會比較小,小到無法裝載下一個完整的uboot鏡像,那么就需要spl,它主要負責初始化外部RAM和環境,并加載真正的uboot鏡像到外部RAM(DDR)中來執行。

    • 所以由此來看,SPL應該是一個非常小的loader程序,可以運行于SOC的內部SRAM中,它的主要功能就是加載真正的uboot并運行之。

    2.2.1. 進入_start函數:

    _start:#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG.word CONFIG_SYS_DV_NOR_BOOT_CFG #endifb resetldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irqldr pc, _fiq

    有一條跳轉指令b reset跳轉到reset函數處去執行
    注意,spl的流程在reset中就應該被結束,也就是說在reset中,就應該轉到到BL2,也就是uboot中了。

    2.2.2. 進入reset函數

    reset:/* Allow the board to save important registers */b save_boot_params @進入reset第一步跳轉到save_boot_params save_boot_params_ret: @ save_boot_params 內部通過cpsr 設置cpu為SVC模式,關閉FIQ和IRQ中斷/** disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,* except if in HYP mode already*/mrs r0, cpsrand r1, r0, #0x1f @ mask mode bitsteq r1, #0x1a @ test for HYP modebicne r0, r0, #0x1f @ clear all mode bitsorrne r0, r0, #0x13 @ set SVC modeorr r0, r0, #0xc0 @ disable FIQ and IRQmsr cpsr,r0/* the mask ROM code should have PLL and others stable */ #ifndef CONFIG_SKIP_LOWLEVEL_INITbl cpu_init_cp15 @ 跳轉到cpu_init_cp15 ,初始化協處理器CP15,從而禁用MMU和TLB。bl cpu_init_crit @ 跳轉到cpu_init_crit ,進行一些關鍵的初始化動作,也就是平臺級和板級的初始化 #endifbl _main @ 跳轉到_main ,加載BL2以及跳轉到BL2的主體部分

    進入reset函數,首先設置cpu為SVC模式關閉中斷。然后跳轉到cpu_init_cp15初始化協處理器CP15,從而禁用MMU和TLB。跳轉到cpu_init_crit ,進行一些關鍵的初始化動作,也就是平臺級和板級的初始化。最后跳轉到**_main**,加載BL2以及跳轉到BL2的主體部分

    • 關閉中斷。
      uboot引導linux起到的過程中本身就是一個完成的過程,不需要中斷機制。

    2.2.3 cpu_init_cp15函數

    ENTRY(cpu_init_cp15)/** Invalidate L1 I/D*/mov r0, #0 @ set up for MCRmcr p15, 0, r0, c8, c7, 0 @ invalidate TLBsmcr p15, 0, r0, c7, c5, 0 @ invalidate icachemcr p15, 0, r0, c7, c5, 6 @ invalidate BP arraymcr p15, 0, r0, c7, c10, 4 @ DSBmcr p15, 0, r0, c7, c5, 4 @ ISB @@ 這里只需要知道是對CP15處理器的部分寄存器清零即可。 @@ 將協處理器的c7\c8清零等等,各個寄存器的含義請參考《ARM的CP15協處理器的寄存器》/** disable MMU stuff and caches*/mrc p15, 0, r0, c1, c0, 0bic r0, r0, #0x00002000 @ clear bits 13 (--V-)bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)orr r0, r0, #0x00000002 @ set bit 1 (--A-) Alignorr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB #ifdef CONFIG_SYS_ICACHE_OFFbic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache #elseorr r0, r0, #0x00001000 @ set bit 12 (I) I-cache #endifmcr p15, 0, r0, c1, c0, 0 @@ 通過上述的文章的介紹,我們可以知道cp15的c1寄存器就是MMU控制器 @@ 上述對MMU的一些位進行清零和置位,達到關閉MMU和cache的目的,具體的話去看一下上述文章吧。ENDPROC(cpu_init_cp15)

    cpu_init_cp15 用來設置 CP15 相關的內容,完成啟動ICACHE,關閉DCACHE,關閉MMU和TLB

    • 關閉MMU
      ,MMU是用于虛擬地址向物理地址進行映射的一個結構。在 uboot階段操作的就直接是 物理地址,所以不需要轉換。
    • 啟動ICACHE(指令),關閉DCACHE(數據)
      啟動指令CACHE課可以加快指令讀取的速度,但是數據CACHE 必須 要關閉,因為它本身是一個CPU的二級緩存,在運行程序的時候可能會往里面去取數據,但是此時ram里面的數據可能并沒有存入到里面,這就可能導致讀取到錯誤的數據。

    2.2.4 cpu_init_crit函數(包含lowlevel_init函數)

    ENTRY(cpu_init_crit)/** Jump to board specific initialization...* The Mask ROM will have already initialized* basic memory. Go here to bump up clock rate and handle* wake up conditions.*/b lowlevel_init @ go setup pll,mux,memory ENDPROC(cpu_init_crit)

    cpu_init_crit函數的內容是跳轉到lowlevel_init函數。

    2.2.5. lowlevel_init 函數(平臺級和板級的初始化)

    lowlevel_init主要完成平臺級和板級的初始化
    在lowlevel_init中,我們要實現如下:

    • 檢查一些復位狀態
    • 關閉看門狗
    • 系統時鐘的初始化
    • 內存、DDR的初始化
    • 串口初始化(可選)
    • Nand flash的初始化

    在im6ull中

    此時初始化SP指向 內存空間為IRAM(內部ram ,OCRAM 128K ,0x00900000),(初始化內存空間,為第二階段準備ram)

    2.2.6. _main函數

    ** _main函數的主要工作是 **

    • 設置c語言的運行環境
    • 設置sp和gd的中間環境
    • 重定義代碼
    • 設置最終的環境
    ENTRY(_main)/** Set up initial C runtime environment and call board_init_f(0). */ @ 為c語言環境準備 @ uboot-spl和uboot代碼共用,CONFIG_SPL_BUILD來區分是誰調用 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)ldr sp, =(CONFIG_SPL_STACK) @ 在spl中為 c語言環境設置棧 #elseldr sp, =(CONFIG_SYS_INIT_SP_ADDR) #endif #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */mov r3, spbic r3, r3, #7mov sp, r3 #elsebic sp, sp, #7 /* 8-byte alignment for ABI compliance */ #endifmov r0, spbl board_init_f_alloc_reserve @ 把棧前面的空間分配給GDmov sp, r0 @重新設置指針SP/* set up gd here, outside any C code */mov r9, r0 @ 保存GD地址到r9寄存器bl board_init_f_init_reserve @ 初始化GD空間mov r0, #0bl board_init_f @ 跳轉到板級前期初始化函數,#if ! defined(CONFIG_SPL_BUILD)/** Set up intermediate environment (new sp and gd) and call* relocate_code(addr_moni). Trick here is that we'll return* 'here' but relocated.*/@ 設置sp和gd的中間環境ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */ #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC destination */mov r3, spbic r3, r3, #7mov sp, r3 #elsebic sp, sp, #7 /* 8-byte alignment for ABI compliance */ #endifldr r9, [r9, #GD_BD] /* r9 = gd->bd */sub r9, r9, #GD_SIZE /* new GD is below bd */adr lr, hereldr r0, [r9, #GD_RELOC_OFF] /* r0 = gd->reloc_off */add lr, lr, r0 #if defined(CONFIG_CPU_V7M)orr lr, #1 /* As required by Thumb-only */ #endifldr r0, [r9, #GD_RELOCADDR] /* r0 = gd->relocaddr */b relocate_code @ 重定位代碼 here: /** now relocate vectors*/bl relocate_vectors @重定位向量表/* Set up final (full) environment */@設置最終的環境bl c_runtime_cpu_setup /* we still call old routine here */ #endif #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK) # ifdef CONFIG_SPL_BUILD/* Use a DRAM stack for the rest of SPL, if requested */bl spl_relocate_stack_gdcmp r0, #0movne sp, r0movne r9, r0 # endifldr r0, =__bss_start /* this is auto-relocated! */#ifdef CONFIG_USE_ARCH_MEMSETldr r3, =__bss_end /* this is auto-relocated! */mov r1, #0x00000000 /* prepare zero to clear BSS */subs r2, r3, r0 /* r2 = memset len */bl memset #elseldr r1, =__bss_end /* this is auto-relocated! */mov r2, #0x00000000 /* prepare zero to clear BSS */clbss_l:cmp r0, r1 /* while not at end of BSS */ #if defined(CONFIG_CPU_V7M)itt lo #endifstrlo r2, [r0] /* clear 32-bit BSS word */addlo r0, r0, #4 /* move to next */blo clbss_l #endif#if ! defined(CONFIG_SPL_BUILD)bl coloured_LED_initbl red_led_on #endif/* call board_init_r(gd_t *id, ulong dest_addr) */mov r0, r9 /* gd_t */ldr r1, [r9, #GD_RELOCADDR] /* dest_addr *//* call board_init_r */@ 跳轉board_init_r 設置最終環境 #if defined(CONFIG_SYS_THUMB_BUILD) ldr lr, =board_init_r /* this is auto-relocated! */bx lr #elseldr pc, =board_init_r /* this is auto-relocated! */ #endif/* we should not return here. */ #endifENDPROC(_main)
    • 因為后面是C語言環境,首先是設置堆棧

    • 初始化gd(下圖中global date,內部ram) , 進行清零(同上內部ram)

    • 調用 board_init_f 函數(將SP指針從內部IRAM,轉移到外部DDR),主要用來初始化 DDR,定時器,完成代碼拷貝等等

    • 調用函數 relocate_code,也就是代碼重定位函數,此函數負責將 uboot 拷貝到新的地方去

    • 調用函數 relocate_vectors,對中斷向量表做重定位

    • 清除 BSS 段 , 。
      bss段不占用空間,都是未初始化的全局變量或者已經初始化為零的變量,本來就是零,直接清零就好。不清零的話未初始化的變量可能會存在未知的數值。

    • 設置函數 board_init_r 的兩個參數調用 board_init_r 函數

    • board_init_r 函數打印一些列的信息到串口,然后會進入main_loop() 。main_loop會進行倒計時,如果此時按下回車就會進入uboot的shell交互界面,否則就會自動引導啟動OS系統。

    2.2.7. board_init_f 函數

  • 初始化一系列外設,比如串口、定時器,或者打印一些消息等。
  • 重新設置環境(sp 和 gd) , 新的 sp 和 gd 將會存放到 DDR 中(外部),而不是內部的 RAM 了
    • uboot 會將自己重定位到 DRAM(DDR) 最后面的地址區域,也就是將自己拷貝到 DRAM 最后面的內存區域中。這么做的目的是給 Linux 騰出空間,防止 Linuxkernel 覆蓋掉 uboot,將 DRAM 前面的區域完整的空出來。
    • 在拷貝之前肯定要給 uboot 各部分分配好內存位置和大小,比這些信息都保存在 gd 的成員變量中(從板子配置文件里讀取),因此要對 gd 的這些成員變量做初始化。最終形成一個完整的內存“分配圖”,在后面重定位 uboot 的時候就會用到這個內存“分配圖”(外部)。
    • 注:上電后芯片內部Boot ROM把uboot搬移到DRAM頭部(0x87800000),重定位則再搬移到DDR后部
  • 2.2.8. relocate_code 函數

    • relocate_code 函數是用于代碼拷貝

    重定位就是 uboot 將自身拷貝到 DRAM 的另一個地放去繼續運行(DRAM 的高地址處)。我們知道,一個可執行的 bin 文件,其鏈接地址和運行地址要相等,也就是鏈接到哪個地址,在運行之前就要拷貝到哪個地址去。現在我們重定位以后,運行地址就和鏈接地址不同了,這樣尋址的時候不會出問題嗎?

    代碼動態重定位原理

  • 分析問題產生原因

    r0 = gd->relocaddr = 0x9ff47000 , uboot重定位后的首地址
    r1 = 0x87800000 源地址的首地址
    r2 = 0x8785dc6c 源地址的結束地址
    r4 = 0x9ff46000 - 0x87800000 = 0x18747000 偏移量
    拷貝是從r1復制往r0粘貼 , 一次兩個32位
    當r1等于r2,拷貝完成

    當簡單粗暴的將uboot從0x87800000拷貝到0x9ff47000 ,程序運行時地址和連接地址不同,發生錯誤。uboot解決方法是使用位置無關碼,借用 .rel.dyn 段

  • 使用位置無關碼解重定位后和連接地址不同問題的原理

    舉例: board_init 函數會調用 rel_test,rel_test 會調用全局變量 rel_a
    源代碼

    static int rel_a = 0;void rel_test(void){rel_a = 100;printf("rel_test\r\n");} int board_init(void) {...rel_test();... }

    反匯編代碼

    8785dcf8 <rel_a>: 8785dcf8: 00000000 andeq r0, r0, r0878042b4 <rel_test>: 878042b4: e59f300c ldr r3, [pc, #12] ; 878042c8 <rel_test+0x14> 878042b8: e3a02064 mov r2, #100 ; 0x64 878042bc: e59f0008 ldr r0, [pc, #8] ; 878042cc <rel_test+0x18> 878042c0: e5832000 str r2, [r3] 878042c4: ea00d64c b 87839bfc <printf> 878042c8: 8785dcf8 ; <UNDEFINED> instruction: 0x8785dcf8 878042cc: 87842aaf strhi r2, [r4, pc, lsr #21]

    從反匯編代碼中分析:

    • 想要找到 rel_a 的地址,首先 r3 = pc + 12 = 0x878042b4 + 8 + 12 = 0x878042c8 。(由ARM 流水線決定 pc = 當前地址 + 8)
    • 之后 r3 在0x878042c8 中存儲數據為0x8785dcf8,即為rel_a地址
    • 這里沒直接讀取rel_a , 而是借助0x878042c8 。 0x878042c8 就是Label

    重定位后,地址變化

    9ffa4cf8 <rel_a>: 9ffa4cf8: 00000000 andeq r0, r0, r09ff4b2b4<rel_test>: 9ff4b2b4: e59f300c ldr r3, [pc, #12] ; 878042c8 <rel_test+0x14> 9ff4b2b8: e3a02064 mov r2, #100 ; 0x64 9ff4b2bc: e59f0008 ldr r0, [pc, #8] ; 878042cc <rel_test+0x18> 9ff4b2c0: e5832000 str r2, [r3] 9ff4b2c4: ea00d64c b 87839bfc <printf> 9ff4b2c8: 8785dcf8 ; <UNDEFINED> instruction: 0x8785dcf8 9ff4b2cc: 87842aaf strhi r2, [r4, pc, lsr #21]
    • 這時 Label中的值還是重定位之前的,必須要將8785dcf8換為重定位后的rel_a地址
    • 重定位后的Label中的數據 = 0x878042c8(老的Label) + 0x18747000(uboot整體的偏移量) = 0x9ffa4cf8
    • 讀取 rel_a 地址為 ,r3 = 0x9ff4b2b4 + 8 + 12 = 0x9ff4b2c8 ,即為Label地址,然后從Label中讀取到 0x9ffa4cf8,為rel_a重定義后真是地址
  • uboot 中使用 .rel.dyn 段具體實現位置無關碼的原理

    完成這個功能在連接的時候需要加上”-pie”

    .rel.dyn 段代碼段

    8785dcec: 87800020 strhi r0, [r0, r0, lsr #32] 8785dcf0: 00000017 andeq r0, r0, r7, lsl r0 …… 8785e2fc: 878042c8 strhi r4, [r0, r8, asr #5] 8785e300: 00000017 andeq r0, r0, r7, lsl r0
    • .rel.dyn 段的格式,也就是兩個 4 字節數據為一組。
      高 4 字節是 Label 地址標識 0X17,低 4 字節就是 Label 的地址,
    • 第三行是878042c8,第四行是00000017 。說明878042c8是一個Label。正是上述分析中 存放 rel_a 地址的Label
    • 在重定位后,rel_a 真是地址 = Label內數據 + offset(0x18747000)
  • 2.2.9 relocate_vectors函數

    • 中斷向量表重定位后的地址,就是重定位后uboot的首地址

    2.2.10. board_init_r 函數(板級初始化,進入第二階段)

    board_init_f 并沒有初始化所有的外設,還需要做一些后續工作,這些后續工作就是由函數 board_init_r 來完成的
    uboot relocate后的板級初始化 ,最后執行run_main_loop

    第二階段

    2.2.11 run_main_loop函數

    • run_main_loop-> main_loop->
      • -> bootdelay_process 獲取bootdelay的值,然后保存到stored_bootdelay
        全局變量里面,獲取bootcmd環境變量值,并且將其
        返回
      • -> autoboot_command 參數是bootcmd的值。檢查倒計時內有無打斷
        • -> abortboot 參數為boot delay,此函數會處理倒計時
          • -> abortboot_normal 參數為boot delay,此函數會處理倒計時
        • ->run_command_list函數,參數為s(bootcmd的命令)倒計時結束時hush shell沒輸入執行,啟動內核
      • -> cli_loop 是uboot命令模式處理函數。
        • -> parse_file_outer
          • -> parse_stream_outer
            • -> parse_stream 解析輸入的字符,得到命令
            • -> run_list 運行命令
              • -> run_list_real
                • -> run_pipe_real
                  • -> cmd_process 處理命令,也就是執行命令
    static int run_main_loop(void) {/* main_loop() can return to retry autoboot, if so just run it again */for (;;)main_loop(); // 這里進入了主循環,而autoboot也是在主循環里面實現return 0; }

    進入了main_loop()函數。

    2.2.11 main_loop()函數

    void main_loop(void) {const char *s;bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); // 這里用于標記uboot的進度,對于tiny210來說起始什么都沒做cli_init(); // cli的初始化,主要是hush模式下的初始化run_preboot_environment_command(); // preboot相關的東西,后續有用到再說明s = bootdelay_process();if (cli_process_fdt(&s))cli_secure_boot_cmd(s);autoboot_command(s); // autoboot的東西,后續使用autoboot的時候再專門說明cli_loop(); // 進入cli的循環模式,也就是命令行模式panic("No CLI available"); }
    • 調用 bootstage_mark_name 函數,打印出啟動進度。
    • 調用 cli_init 函數,跟命令初始化有關,初始化 hush shell 相關的變量。( hush shell 為uboot倒計時結束的輸入shell)
    • run_preboot_environment_command 函數,獲取環境變量 perboot 的內容,perboot
      是一些預啟動命令
    • bootdelay_process 函數,此函數會讀取環境變量 bootdelay (延遲時間)和 bootcmd(啟動內核命令) 的內容,
      然后將 bootdelay 的值賦值給全局變量 stored_bootdelay,返回值為環境變量 bootcmd 的值。
    • autoboot_command(s)函數,此函數就是檢查倒計時是否結束?倒計時結束之前有
      沒有被打斷?輸入參數s為bootcmd的命令
      • 倒計時自然結束執行函數run_command_list,此函數會執行參數 s 指定的一系列命令,也就是環境變量 bootcmd 的命令,bootcmd 里面保存著默認的啟動命令,因此 linux 內核啟動
      • 倒計時結束之前按下了鍵盤上的按鍵,那么 run_command_list函數就不會執行,執行后面的cli_loop函數
    • cli_loop函數,是 uboot 的命令行處理函數

    2.2.12 cli_loop函數

    cli_loop 函數是 uboot 的命令行處理函數,我們在 uboot 中輸入各種命令,進行各種操作就是有 cli_loop 來處理的

    void cli_loop(void) {#ifdef CONFIG_SYS_HUSH_PARSERparse_file_outer();/* This point is never reached */for (;;);#elsecli_simple_loop(); //永遠不會執行#endif /*CONFIG_SYS_HUSH_PARSER*/ }
    • 調用 parse_file_outer函數

    2.2.13 parse_file_outer函數

    int parse_file_outer(void) {int rcode;struct in_str input;setup_file_in_str(&input);rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);return rcode;}
    • 調用函數 setup_file_in_str 初始化變量 input 的成員變量
    • 調用函數 parse_stream_outer,這個函數就是 hush shell 的命令解釋器,負責接收命令行輸入,然后解析并執行相應的命令

    2.3.14 函數 parse_stream_outer

    static int parse_stream_outer(struct in_str *inp, int flag){struct p_context ctx;o_string temp=NULL_O_STRING;int rcode;int code = 1;do {......rcode = parse_stream(&temp, &ctx, inp,flag & FLAG_CONT_ON_NEWLINE ? -1 : '\n');......if (rcode != 1 && ctx.old_flag == 0) {......run_list(ctx.list_head);......} else {......}b_free(&temp);/* loop on syntax errors, return on EOF */} while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP) &&(inp->peek != static_peek || b_peek(inp)));return 0; }
    • do-while 循環就是處理輸入命令的
    • 函數 parse_stream 進行命令解析
    • 調用 run_list 函數來執行解析出來的命令,run_list 調用 run_list_real 函數,run_list_real 函數調用 run_pipe_real 函數,run_pipe_real 函數調用 cmd_process 函數。最終通過函數 cmd_process 來處理命令

    2.3.15 補充:uboot的命令

    uboot把所有命令的數據結構都放在一個表格中,我們后續稱之為命令表。表中的每一項代表著一個命令,其項的類型是cmd_tbl_t。

    struct cmd_tbl_s {char *name; /* Command Name */int maxargs; /* maximum number of arguments */int repeatable; /* autorepeat allowed? *//* Implementation function */int (*cmd)(struct cmd_tbl_s *, int, int, char * const []);char *usage; /* Usage message (short) */ #ifdef CONFIG_SYS_LONGHELPchar *help; /* Help message (long) */ #endif }; typedef struct cmd_tbl_s cmd_tbl_t;

    參數說明如下:

    name:定義一個命令的名字。 其實就是執行的命令的字符串。這個要注意。
    maxargs:這個命令支持的最大參數
    repeatable:是否需要重復
    cmd:命令處理函數的地址
    usage:字符串,使用說明
    help:字符串,幫助

    Uboot使用U_BOOT_CMD來定義一個命令。CONFIG_CMD_XXX來使能uboot中的某個命令。

    //uboot命令定義代碼 #define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)

    U_BOOT_CMD最終是定義了一個cmd_tbl_t類型的結構體變量,所有的命令最終都是存放在.u_boot_list段里面。cmd_tbl_t結構體中的cmd成員變量就是具體的命令執行函數,命令執行函數都是do_xxx。

    // bootm就是我們的命令字符串 // 在tiny210.h中定義了最大參數數量是64 // #define CONFIG_SYS_MAXARGS 64 /* max number of command args */ // 1表示重復一次 // 對應命令處理函數是do_bootm // usage字符串是"boot application image from memory" // help字符串是bootm_help_text定義的字符串。 U_BOOT_CMD(bootm, CONFIG_SYS_MAXARGS, 1, do_bootm,"boot application image from memory", bootm_help_text );//并且命令處理函數的格式如下: //當命令處理函數執行成功時,需要返回0.返回非0值 int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])

    2.3.16 函數 cmd_process

    函數 cmd_process 來處理命令并執行

    • cmd_process
      • ->find_cmd 從.u_boot_list段里面查找命令,當找到對應的命令以后以返回值的
        形式給出,為cmd_tbl_t類型
      • ->cmd_call
        ->cmdtp->cmd 直接引用cmd成員變量,執行do_xxx函數

    函數 cmd_process代碼

    enum command_ret_t cmd_process(int flag, int argc, char * const argv[],int *repeatable, ulong *ticks) {enum command_ret_t rc = CMD_RET_SUCCESS;cmd_tbl_t *cmdtp;/* Look up command in command table */cmdtp = find_cmd(argv[0]);// 第一個參數argv[0]表示命令,調用find_cmd獲取命令對應的表項cmd_tbl_t。if (cmdtp == NULL) {printf("Unknown command '%s' - try 'help'\n", argv[0]);return 1;}/* found - check max args */if (argc > cmdtp->maxargs)rc = CMD_RET_USAGE;// 檢測參數是否正常/* If OK so far, then do the command */if (!rc) {if (ticks)*ticks = get_timer(0);rc = cmd_call(cmdtp, flag, argc, argv);// 調用cmd_call執行命令表項中的命令,成功的話需要返回0值if (ticks)*ticks = get_timer(*ticks);// 判斷命令執行的時間*repeatable &= cmdtp->repeatable;// 這個命令執行的重復次數存放在repeatable中的}if (rc == CMD_RET_USAGE)rc = cmd_usage(cmdtp);// 命令格式有問題,打印幫助信息return rc; }
    • find_cmd函數, 從.u_boot_list段獲取命令對應的命令表項cmd_tbl_t 。
    • cmd_call函數,執行命令表項cmd_tbl_t 中的命令,執行do_xxx函數

    2.3.17 uboot啟動linux內核(bootz命令)

    在run_main_loop函數倒計時結束時沒有輸入,uboot執行bootcmd命令,啟動內核

    • bootcmd 保存著 uboot 默認命令,這些命令一般都是用來啟動 Linux 內核的,讀取Linux鏡像文件和設備樹文件(從MMC、SD卡、網絡讀取等)到DARM(DDR)中,然后啟動內核(bootz、bootm)。

    • bootm和bootz的不同地方

      • bootm用于加載uImage和ramdisk
        bootm ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
      • bootz用于加載zImage和ext4文件系統
        bootz ${kernel_load_address} ${ramdisk_load_address} ${devicetree_load_address}
    • bootz的使用(tftp從網絡讀取)

      tftp 80800000 zImage tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb bootz 80800000 - 83000000

    bootz流程

    2.3.18 do_bootz函數

    do_bootz是bootz的執行函數
    do_bootz

    • -> bootz_start
      • -> do_bootm_states 階段為BOOTM_STATE_START
        • -> bootm_start 對images全局變量清零
      • -> images->ep = 0X80800000
      • ->bootz_setup 判斷zImage是否正確
      • -> bootm_find_images 查找鏡像文件
        • -> boot_get_fdt 找到設備樹,然后將設備樹起始地址和長度,寫入到images的ft_addr和ft_len成員變量中。
      • -> bootm_disable_interrupts 關閉中斷相關
      • -> images.os.os = IH_OS_LINUX; 表示要啟動Linux系統
      • -> do_bootm_states 狀態BOOTM_STATE_OS_PREP 、BOOTM_STATE_OS_FAKE_GO 、
        BOOTM_STATE_OS_GO,
        • -> bootm_os_get_boot_func 查找Linux內核啟動函數。找到Linux內核啟動函數
          do_bootm_linux,賦值給boot_fn。
        • -> boot_fn(BOOTM_STATE_OS_PREP, argc, argv, images); 就是do_bootm_linux。
          • -> boot_prep_linux 啟動之前的一些工作,對于使用設備樹來說,他會將Bootargs傳遞給Linux內核,通過設備樹完成。也就是向Linux內核傳參。
          • -> boot_jump_linux
            • -> machid= gd->bd->bi_arch_number;
            • -> kernel_entry = (void (*)(int, int, uint))images->ep; 0X80800000。
            • -> announce_and_cleanup 輸出Starting kernel……
            • -> kernel_entry(0, machid, r2); 啟動Linux內核。Uboot的最終使命,啟動Linux內核。

    2.3.19 kernel_entry函數

    kernel_entry函數是內核的入口函數。內核鏡像第一行代碼

    kernel_entry(0, machid, r2);

    此函數有三個參數:zero,arch,params,

    • 第一個參數 zero 同樣為 0;
    • 第二個參數為機器 ID;
    • 第三個參數啟動參數標記列表(ATAGS)或者設備樹(DTB)首地址,ATAGS 是傳統的方法,用于傳遞一些命令行信息啥的,如果使用設備樹的話就要傳遞設備樹(DTB)。
    • 是匯編函數,因為內核開始是匯編代碼。
    • images->ep 保存著 Linux內核鏡像的起始地址,也就是kernel_entry的地址

    kernel_entry函數的傳參

    • 向匯編函數傳遞參數要使用 r0、r1 和 r2寄存器
      • r0 = 0
      • r1 = 機器類型ID(machid)
        • Linux 內核會在自己的機器 ID 列表里面查找是否存在與 uboot 傳遞進來的 machid 匹配的項目,如果存在就說明 Linux 內核支持這個機器,那么 Linux 就會啟動!
        • 如果使用設備樹的話這個 machid 就無效了,設備樹存有一個“兼容性”這個屬性,Linux 內核會比較“兼容性”屬性的值(字符串)來查看是否支持這個機器。
      • r2 =
        • 如果使用設備樹的話,r2 應該是設備樹的起始地址
        • 如果不使用設備樹的話,r2 應該是 uboot 傳遞給 Linux 的參數起始地址,也就是環境變量 bootargs 的值

    如何從uboot跳轉到內核
    直接修改PC寄存器的值為Linux內核所在的地址,CPU從內核所在的地址去取指令,從而執行內核代碼
    為什么要傳參數給內核
    在此之前, uboot已經完成了硬件的初始化,可以說已經噎適應了“這塊開發板。然而,內核并不是對于所有的開發板都能完美適配的(如果適配了,可想而知這個內核有多龐大,又或者有新技術發明了,可以完美的適配各種開發板),此時,對于開發板的環境一無所知。所以,要想啟動 Linux內核, uboot必須要給內核傳遞一些必要的信息來告訴內核當前所處的環境。

    總結

    以上是生活随笔為你收集整理的uboot启动流程详细分析(基于i.m6ull)的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    国产美女在线观看 | 欧美性黄网官网 | 91视频 - 88av| 一区二区三区在线播放 | 精品xxx | 国产精品久久麻豆 | av网站手机在线观看 | 精品国产乱码久久久久 | 五月天伊人 | 青草视频在线免费 | 欧美一级黄大片 | 天天干天天操天天入 | 91污污视频在线观看 | 午夜电影一区 | 亚洲视频 视频在线 | 亚洲免费高清视频 | 国产精品九九热 | 亚洲精品自拍视频在线观看 | 九九精品在线观看 | 91手机视频 | 久久国产网站 | 91人人射| www操操 | 成人黄色在线观看视频 | 国产精品免费久久久久久 | 九九久 | 日韩av伦理片 | 婷婷激情av | 综合色综合| 中文字幕.av.在线 | 欧美a级在线免费观看 | 在线观看午夜 | 国产精品久久久久久999 | 久久久久久久久久福利 | 国产精品1区2区 | 国产手机免费视频 | 欧美激情综合五月色丁香 | 五月情婷婷| av免费看av | 日日插日日干 | www日 | 亚洲一二区精品 | 九色91在线视频 | 亚洲精品88欧美一区二区 | 中文字幕av在线免费 | 日韩一区二区三区免费视频 | 国产精品久久久久久久久久直播 | 日韩精品免费一区二区 | a黄色片在线观看 | 中文字幕国产一区二区 | 欧美日韩精品在线视频 | 日韩免费一级a毛片在线播放一级 | 五月婷婷丁香综合 | 91久久国产自产拍夜夜嗨 | 色偷偷中文字幕 | 黄色毛片视频免费观看中文 | 天天干 天天摸 天天操 | 久久欧洲视频 | 欧美 日韩 国产 中文字幕 | av品善网| 手机成人免费视频 | 久久99精品久久久久久 | 成人啊 v| 国产高清永久免费 | 久久黄色影院 | 综合久久久久久久久 | 日日干天天射 | 五月开心激情网 | 欧美精品一区二区在线播放 | 又黄又爽又无遮挡的视频 | 欧美日韩亚洲在线 | 男女视频国产 | 国产精品一二三 | 男女激情麻豆 | 日韩美精品视频 | 国产高清第一页 | 久久久久久久久爱 | 欧美日韩xxx| 亚洲精品国产精品久久99 | 欧美性色综合网 | 精品久久免费看 | 成人在线超碰 | 国产精品乱码高清在线看 | 色94色欧美| 丝袜美腿在线播放 | 国产欧美综合在线观看 | 婷婷av网 | 欧美日本不卡高清 | 亚洲日本激情 | 国产一级高清 | 麻豆传媒视频在线播放 | 国产尤物在线观看 | 99一级片 | 在线观看亚洲精品 | 久久久免费高清视频 | 人人爽人人爽人人爽人人爽 | 美女黄频在线观看 | 欧美电影在线观看 | 99亚洲天堂| 亚洲国产视频a | 日韩一区二区免费视频 | 精品一区二区电影 | 欧美在线视频精品 | 久久观看| 在线视频免费观看 | 波多野结衣在线播放视频 | 亚洲精品乱码久久久久久蜜桃欧美 | 日韩欧美视频在线观看免费 | 一区二区影视 | 日本精品一区二区在线观看 | www最近高清中文国语在线观看 | 五月婷视频 | 久久se视频 | 中国一区二区视频 | 五月激情站| 久久爽久久爽久久av东京爽 | 最近高清中文字幕在线国语5 | 特级黄色一级 | 在线视频精品 | 国产亚洲亚洲 | 久久久久久高潮国产精品视 | 久久久久久久久久久影院 | 国产黄在线播放 | 黄色软件网站在线观看 | 91av免费观看 | 国产精品99久久免费黑人 | 国产欧美最新羞羞视频在线观看 | 中文字幕在线观看不卡 | 欧美-第1页-屁屁影院 | 欧美专区日韩专区 | 免费日韩一区二区三区 | 日韩在线不卡视频 | 亚洲成人黄| 欧美激情视频一区 | 在线观看免费视频你懂的 | 在线观看mv的中文字幕网站 | 免费日韩一级片 | h视频在线看 | 婷婷色 亚洲 | 国产91国语对白在线 | 国产98色在线 | 日韩 | 成人四虎 | 最近2019好看的中文字幕免费 | 国产主播99 | 91精品在线观看入口 | 日韩系列在线观看 | 色综合久久88色综合天天免费 | 日韩欧美国产成人 | 日韩丝袜视频 | a视频免费在线观看 | 日本最新一区二区三区 | 久久精品久久99 | 欧美热久久| 欧美日韩在线观看一区二区 | 精品国产一区二区三区免费 | www黄色大片 | 中文字幕在线第一页 | 国产啊v在线观看 | 91高清视频 | 成人av电影网址 | 日韩在线观看视频一区二区三区 | 丁香5月婷婷 | 五月天com| 色资源网免费观看视频 | 日韩三级久久 | 婷婷综合久久 | 国产成人精品一区二区三区福利 | 最近高清中文字幕 | 日本三级全黄少妇三2023 | 久久99精品国产麻豆宅宅 | 精品视频免费久久久看 | 免费观看成人av | 国产最新91| 99re久久资源最新地址 | 在线性视频日韩欧美 | 欧美一级视频免费 | 久久小视频 | 亚洲欧美日本一区二区三区 | 五月激情视频 | 韩国av永久免费 | 成人h电影| 国内精品免费久久影院 | 97人人超碰在线 | 欧美日韩中文在线观看 | 国产一区二区播放 | 黄色三几片 | 欧美 日韩 成人 | av天天草| 人人爽影院 | 51久久夜色精品国产麻豆 | 成人av片免费看 | 免费碰碰 | 欧美伦理一区 | 91九色在线观看 | 亚洲www天堂com | 成人午夜黄色影院 | 久久精品久久99精品久久 | 在线观看 国产 | 国产精品久久嫩一区二区免费 | 成人精品99| www.五月天激情 | 精品久久久久久久久久久久久久久久久久 | 色99之美女主播在线视频 | 激情六月婷婷久久 | www.69xx| 91成人久久| 久免费 | 99九九免费视频 | 亚洲精品影院在线观看 | 国产精品成人a免费观看 | www.97视频| 国产成人三级在线播放 | 国产99久久久欧美黑人 | 在线小视频你懂的 | 日韩一区视频在线 | 久射网 | 国产精品一区二区久久 | 免费看成人av | av在线免费观看黄 | 久久久久亚洲精品男人的天堂 | 久久久久久久久久久久电影 | 91香蕉亚洲精品 | 日日夜夜中文字幕 | 成人久久久久久久久久 | 不卡av在线播放 | 亚洲蜜桃在线 | 91黄色在线看 | 久草免费在线观看视频 | 最近日本字幕mv免费观看在线 | 日日操操 | 91视频免费观看 | 久久成人一区 | 日韩免费视频在线观看 | 97在线播放视频 | 国产午夜三级一区二区三桃花影视 | 麻豆国产网站入口 | 狠狠色丁香婷婷综合久小说久 | 国产精品va在线播放 | 国产成人精品999在线观看 | 久久亚洲美女 | 在线观看成年人 | 免费在线日韩 | 免费欧美 | 992tv又爽又黄的免费视频 | 免费污片 | 超碰在97 | 日韩在线| wwwwww色 | 欧美专区国产专区 | 91成人免费在线视频 | 黄色aaa级片 | 欧美大片aaa | 日本女人b| 婷婷丁香导航 | 高清国产午夜精品久久久久久 | 成人a在线观看 | 一区在线电影 | 久草视频中文 | 波多野结衣视频一区二区 | 特级黄色一级 | 91精品少妇偷拍99 | 日韩色高清 | 久久久亚洲国产精品麻豆综合天堂 | 亚洲精品综合一二三区在线观看 | 久久久久久久久久久影院 | 在线免费中文字幕 | 狠狠插狠狠干 | 99精品免费在线 | 成人免费网站在线观看 | 国产精品久久久久久久久岛 | 久久久久一区二区三区 | 国产精品毛片一区二区三区 | 91麻豆精品国产91久久久更新时间 | 国产乱对白刺激视频在线观看女王 | 五月天色站| 免费在线色 | 在线成人免费 | 韩国在线一区 | 国产亚洲片 | 99久久激情 | 国产精品18videosex性欧美 | 日韩一区二区免费视频 | 9久久精品 | 岛国一区在线 | 色网免费观看 | 中文字幕在线免费 | 日日夜夜免费精品视频 | 国产精品高 | 人人揉人人揉人人揉人人揉97 | 麻豆视频大全 | 成片免费观看视频999 | 丰满少妇麻豆av | 干干夜夜 | 中文字幕中文字幕在线中文字幕三区 | av福利资源 | 国产精品欧美一区二区三区不卡 | 欧美激情视频在线免费观看 | 国产精品视频在线看 | 一区二区三区在线视频111 | 91福利在线观看 | 欧美美女激情18p | www.香蕉视频 | 久久色视频 | 久久久久久久精 | 国产资源站| 91精品一区二区三区蜜臀 | 黄色a三级 | 国内丰满少妇猛烈精品播放 | 久久精品久久精品久久精品 | 国产精品免费大片视频 | 狠狠色丁香久久婷婷综 | 久久久免费精品国产一区二区 | av成人在线电影 | 人人干在线 | 五月婷婷一区 | 最新国产在线观看 | 久久久久日本精品一区二区三区 | 色多多在线观看 | 在线99 | 欧美日韩在线看 | 成人免费观看视频大全 | 免费看国产黄色 | 国产永久免费高清在线观看视频 | 国产最新网站 | 在线成人一区 | 在线观看免费视频 | 久久美女免费视频 | 91在线永久 | www好男人| 日韩高清无线码2023 | 在线观看片| 热久久视久久精品18亚洲精品 | 免费看在线看www777 | 婷婷在线不卡 | 国产成人av电影 | 91一区啪爱嗯打偷拍欧美 | 久久精品美女视频 | 五月在线 | 久草在线在线视频 | 成人久久18免费网站 | 日韩亚洲在线 | av福利在线免费观看 | 成人免费观看视频网站 | 日本久久久久 | 亚洲国产三级 | 日韩高清网站 | 免费观看的黄色片 | 亚洲黄色成人 | 精品视频在线观看 | 国产日本亚洲 | 国产精品视频 | 国产精品精品久久久久久 | 中文字幕精品一区二区三区电影 | 一级欧美日韩 | av在线收看| 91精品国产麻豆国产自产影视 | 欧亚久久 | 亚洲资源在线 | 九九九九九九精品任你躁 | 日本精品一区二区 | 国产在线观看你懂的 | 久久午夜网 | 亚洲天堂网在线视频观看 | 在线观看亚洲精品视频 | www.com.日本一级 | 国产在线观看一区 | 午夜丁香网 | 99视频偷窥在线精品国自产拍 | 国产免费视频在线 | 久久久久一区二区三区四区 | 欧美在线资源 | 色综合久久中文字幕综合网 | 欧美极品久久 | 91成人在线视频 | 日本精品久久久久 | 99r在线精品 | 亚洲日韩中文字幕 | 国内精品美女在线观看 | 免费av在 | 国产精品久久艹 | 成人毛片一区二区三区 | 国产成人免费在线 | 九九免费视频 | 五月天婷亚洲天综合网鲁鲁鲁 | ,久久福利影视 | 欧美片一区二区三区 | 免费精品在线视频 | 伊人资源站 | 国色天香在线 | 成人蜜桃 | 操操碰| 中文在线字幕免费观 | 国产黄色在线网站 | 国产中文 | 国产精品123 | 亚洲国产剧情av | 狠狠躁日日躁狂躁夜夜躁 | 中文字幕视频在线播放 | 精品你懂的 | 亚洲狠狠操 | 亚洲成人av一区二区 | 成人永久视频 | 欧美午夜性生活 | 92国产精品久久久久首页 | 日韩精品中文字幕在线播放 | www.狠狠 | 成人在线播放免费观看 | 韩国av永久免费 | 日韩精品一区二区三区免费观看视频 | 国产自制av| 黄色av网站在线观看免费 | 西西44人体做爰大胆视频 | 97国产在线播放 | 99激情网 | 中文在线亚洲 | 久久性生活片 | 国产成人精品午夜在线播放 | 欧美精品久久久久久久久老牛影院 | 国产精品自产拍在线观看网站 | 99热这里只有精品久久 | 久久久蜜桃 | 久久不见久久见免费影院 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 手机在线看片日韩 | 91麻豆视频| 91av视频在线播放 | 亚洲美女视频网 | 久久丝袜视频 | 成人久久精品 | 一区二区男女 | 黄a在线| 国产精品video爽爽爽爽 | 日韩一区二区在线免费观看 | 日韩美在线观看 | 狠狠狠色狠狠色综合 | 四月婷婷在线观看 | 欧美在线aa | 国产a视频免费观看 | 国产成人一区二区三区在线观看 | 一级黄色片在线免费看 | 久久精品久久精品久久 | 91看片在线播放 | 日韩精品一区电影 | www激情久久 | 国产精品视频在线看 | 色资源二区在线视频 | 久久高清免费视频 | 中文字幕一区二区三区乱码不卡 | 免费又黄又爽的视频 | 99精品视频免费在线观看 | 日韩高清在线观看 | 91视频在线免费看 | 在线影院中文字幕 | 国产精品大全 | 婷婷六月丁 | 国产系列 在线观看 | www.夜夜草| 成年人精品 | 久久精品视频国产 | 91精品国产亚洲 | 免费在线视频一区二区 | 国产流白浆高潮在线观看 | 99热官网 | 久久国产精品一区二区三区 | 国产999精品久久久久久麻豆 | 中文在线字幕免费观看 | 美女视频黄频大全免费 | 久久精品韩国 | 成人小视频在线免费观看 | 国产黄色精品视频 | 日韩最新在线视频 | 日韩高清不卡一区二区三区 | 免费福利在线视频 | 亚洲激情p | www.久久99 | 在线看中文字幕 | 黄色免费网战 | 一区在线观看 | 亚洲精选99 | 国产精品第三页 | 精品国内自产拍在线观看视频 | 国产中文字幕第一页 | 国产生活一级片 | 丰满少妇在线 | 午夜av不卡 | 国产热re99久久6国产精品 | 免费观看www7722午夜电影 | 欧美日韩一二三四区 | 欧亚久久| 91丨九色丨高潮丰满 | 波多野结衣视频一区 | 日韩二区在线观看 | 欧美日韩在线观看一区二区 | 美国人与动物xxxx | 天天操夜夜操夜夜操 | 中文字幕一区二区三区精华液 | 欧美激情另类文学 | av视屏在线| 国产在线不卡视频 | 又黄又刺激 | 91人人爽久久涩噜噜噜 | 2019精品手机国产品在线 | 日日麻批40分钟视频免费观看 | 亚洲国产电影在线观看 | 久久久综合九色合综国产精品 | 午夜影院一级片 | 99麻豆视频 | 精品一二三四五区 | 精品产品国产在线不卡 | 亚洲www天堂com | 人人揉人人揉人人揉人人揉97 | 免费激情网 | 右手影院亚洲欧美 | 嫩草av在线 | 91精品国产乱码在线观看 | 婷婷伊人综合亚洲综合网 | 一级免费片 | 国产99久久久久久免费看 | 高清不卡一区二区在线 | 性日韩欧美在线视频 | 欧美aaa级片| 91精品国产91久久久久 | 激情综合亚洲 | 在线免费试看 | 91精品成人 | 国产一区二区精品91 | 精品国产91亚洲一区二区三区www | 五月综合激情网 | 99se视频在线观看 | 国产美女网| 日韩电影中文,亚洲精品乱码 | 欧美久久九九 | 国产中文字幕在线播放 | 成人免费xxx在线观看 | 久操视频在线播放 | 免费在线观看日韩视频 | 国产 视频 高清 免费 | 国产美女永久免费 | 青青啪| 韩国av在线播放 | 国产精品久久久网站 | 操操综合 | 成人av资源站| 青青草国产成人99久久 | 国产高清不卡av | 欧美大片mv免费 | 欧美91av| 色综合夜色一区 | 久久高清国产 | 免费成人黄色片 | 免费日韩在线 | 久久久久久久久久免费 | 婷婷六月综合亚洲 | 99高清视频有精品视频 | 日韩三级中文字幕 | av中文字幕网址 | 久久久国产一区二区三区 | 久久久久久欧美二区电影网 | 精品国产一区二区三区日日嗨 | 久久婷婷丁香 | 六月色婷 | 国内一区二区视频 | 国产成人一区二区三区久久精品 | 欧美日韩国产欧美 | 91一区在线观看 | 欧美一级免费黄色片 | 国产99久久久国产精品免费看 | 欧美日韩p片 | 久久精品国产精品亚洲精品 | 在线小视频你懂的 | 亚洲成 人精品 | 2017狠狠干 | 特级西西444www高清大视频 | 最近更新好看的中文字幕 | 国产高清无线码2021 | 久久影视中文字幕 | 精品视频99| 日本乱视频| 日韩免费不卡av | 免费成人av电影 | 久久久久久久免费看 | 亚洲国产小视频在线观看 | 国产午夜亚洲精品 | www日韩在线 | 99免费看片 | 国产a高清| 午夜久久电影网 | 日韩a级黄色 | 在线视频日韩 | 这里有精品在线视频 | 国产精品久久久久久高潮 | av电影不卡在线 | 天天干天天操 | 久久超级碰视频 | 久久久久久久久影院 | 久久97超碰 | 国产在线观看你懂得 | 久久夜夜爽 | 婷婷午夜 | 99热这里只有精品免费 | 亚洲区精品视频 | 亚色视频在线观看 | 激情综合色综合久久综合 | 天天超碰 | 亚洲一区黄色 | 99精品视频99| 色香蕉在线 | 在线播放国产一区二区三区 | 91精品久久久久久久久 | 91在线视频精品 | 欧美日韩精品在线播放 | 国产成人综合在线观看 | 丁香婷婷综合激情五月色 | 婷婷视频在线 | 中文字幕在线视频一区二区三区 | 色综合久久88色综合天天 | 久久久国产网站 | 精品国产中文字幕 | 在线免费观看欧美日韩 | 麻豆成人在线观看 | 免费看黄的 | 中文字幕亚洲五码 | 国内偷拍精品视频 | 国产亚洲精品久久久网站好莱 | 最新中文字幕在线资源 | 精品久久一二三区 | 97在线免费 | 麻豆视频在线免费观看 | 欧美综合干| 国产精品久久久久久久久久了 | 久久看免费视频 | 射九九 | 久久黄色免费 | 国产高清在线观看av | 亚洲精品毛片一级91精品 | 天天干天天拍天天操天天拍 | 青青网视频| 麻豆你懂的 | av线上免费观看 | 久久久久久久久久免费 | 亚洲一区二区精品3399 | 五月天综合激情 | 久久久免费精品国产一区二区 | 久久久久电影网站 | 丝袜美腿在线 | 久久香蕉国产精品麻豆粉嫩av | 久久er99热精品一区二区 | 久av电影 | 国产一级片一区二区三区 | 日韩免费电影网站 | 国产一区免费在线观看 | 久久只有精品 | 夜夜爽88888免费视频4848 | 麻豆网站免费观看 | 97超碰中文字幕 | 午夜精品一区二区三区可下载 | 成人久久18免费网站 | 日韩影片在线观看 | 久久国产一区二区 | 一级片黄色片网站 | 视频91 | 亚洲日本va在线观看 | 碰超在线观看 | 91福利视频免费观看 | 天天激情天天干 | 五月情婷婷 | 日韩综合一区二区三区 | 麻豆国产精品一区二区三区 | 色网站在线看 | 成人xxxx| 国产v在线 | 久一久久 | 美女视频黄是免费的 | 菠萝菠萝在线精品视频 | www.夜夜爱| 国产视频一区二区三区在线 | 九九热精品视频在线播放 | 免费成人看片 | 色资源二区在线视频 | 91精品国产三级a在线观看 | 在线成人小视频 | 国产一区二区免费 | 国产精品igao视频网网址 | 最近中文字幕视频网 | 久久久精品在线观看 | 免费观看视频的网站 | 欧美成人a在线 | 色吊丝在线永久观看最新版本 | 精品国产综合区久久久久久 | 999电影免费在线观看 | 99精品免费视频 | 久久久久久久久久久国产精品 | 99国产精品久久久久久久久久 | 亚洲精品字幕在线观看 | 夜夜夜影院 | 成人午夜电影网站 | 99在线视频精品 | 二区三区中文字幕 | 免费精品在线观看 | 精品国产一区二区三区在线观看 | 免费a v网站| 日韩欧美电影 | 国产一区在线视频播放 | 精品在线一区二区三区 | 色偷偷88888欧美精品久久 | 在线视频 成人 | 久久久久黄| 亚洲精品国产综合99久久夜夜嗨 | 麻豆精品传媒视频 | 久久香蕉国产精品麻豆粉嫩av | 国产在线不卡一区 | 国产成人精品亚洲精品 | 91在线最新 | 五月婷婷丁香网 | 国产精品综合久久久久久 | 日韩av福利在线 | 91热| 9999毛片| 最新国产一区二区三区 | 操夜夜操| 色综合久久久久久中文网 | 在线电影av | 在线视频 日韩 | 日韩一区精品 | www一起操 | 欧美一二三专区 | 99爱这里只有精品 | 91爱看片 | 日本精品视频在线观看 | 色橹橹欧美在线观看视频高清 | 麻豆免费视频网站 | 中文字幕资源网在线观看 | 97在线播放| 精品99999| 五月婷婷色丁香 | 日日添夜夜添 | 不卡精品视频 | 最新av中文字幕 | 韩国三级av在线 | 国产黄色在线观看 | 国产精品一区免费在线观看 | 国产特黄色片 | 波多野结衣电影久久 | 成人在线观看日韩 | 五月天亚洲综合 | 92国产精品久久久久首页 | 99久久9 | 日韩啪啪小视频 | 狠狠做深爱婷婷综合一区 | 激情婷婷综合 | 日韩在线观看三区 | 黄色中文字幕在线 | 日韩视频一区二区在线 | av大片免费在线观看 | 国产精品久久久久一区二区三区 | 亚洲资源一区 | 欧美一区在线观看视频 | 国产无套视频 | 国产精品一区二区免费 | 免费看久久久 | 午夜精品剧场 | 在线91播放 | 99爱视频在线观看 | 免费色视频网站 | 亚洲激情中文 | 国产主播大尺度精品福利免费 | 激情网站| 国产精品女教师 | 天天操天天操天天 | 一区二区不卡 | 最新国产在线观看 | 国产免费嫩草影院 | 97在线观看视频 | 免费黄a| 国产精品久久久久aaaa | 免费91麻豆精品国产自产在线观看 | 中文字幕在线观 | 一区二区三区日韩精品 | 日韩免费电影网 | 二区三区在线 | 99精品国产高清在线观看 | 久草在线费播放视频 | 国产麻豆精品久久一二三 | 免费能看的黄色片 | 亚洲 成人 欧美 | 日女人电影 | 精品在线99 | 欧美成人中文字幕 | 999成人精品| 久久少妇| 中文字幕成人一区 | 在线视频观看91 | av电影中文字幕在线观看 | 国产精品色婷婷视频 | 亚洲aⅴ免费在线观看 | 国产中的精品av小宝探花 | 最近日本中文字幕 | 国内精品在线一区 | 973理论片235影院9 | 黄色大片日本免费大片 | 国产一区二区三区四区在线 | 亚洲免费小视频 | 91在线精品播放 | 中文字幕在线看人 | 亚洲三级影院 | 婷婷国产精品 | 中文字幕丝袜一区二区 | 久草在线在线精品观看 | 视频一区二区三区视频 | 亚洲国产成人精品久久 | 黄色成品视频 | 91资源在线播放 | 中文字幕资源网 国产 | 国模精品在线 | 成人av免费 | 久久精品影视 | 免费人人干 | 亚洲国产精品人久久电影 | 一区二区欧美在线观看 | 欧美日韩精品在线播放 | 久久少妇av | 99久久精品免费看国产四区 | 91香蕉视频污在线 | 久久久久久国产精品免费 | 欧美精选一区二区三区 | 黄色小网站免费看 | 久久国产免 | 久久国产精品免费一区二区三区 | 国产精品9999 | 国产在线97| 91高清完整版在线观看 | 国产精品一区二区吃奶在线观看 | 国产成人一二片 | 99久久精品国产一区 | 91天堂影院 | 人人干在线观看 | 99久久日韩精品免费热麻豆美女 | 久久久久久久18 | 免费观看9x视频网站在线观看 | 手机色在线 | 久久久免费观看完整版 | 成人动漫精品一区二区 | 国产精品美女久久久免费 | 操夜夜操 | 99免费在线观看 | 免费午夜视频在线观看 | 正在播放一区二区 | 超碰人人干人人 | 亚洲综合情 | 久久成熟| 欧美在线一级片 | 99视频久久 | 久久天天躁夜夜躁狠狠85麻豆 | 黄色小说免费在线观看 | 国产精品免费观看国产网曝瓜 | 久久久久久久久久网站 | 亚洲 综合 国产 精品 | 日韩 在线 | 有码中文字幕 | 丰满少妇麻豆av | 精品夜夜嗨av一区二区三区 | 欧美精品久久久久久久久老牛影院 | 亚洲五月婷婷 | 亚洲人视频在线 | 天天操天天操天天爽 | 天堂在线一区二区 | 在线午夜av| 国产一区二区三区免费观看视频 | 中文字幕第一页av | 国产 日韩 欧美 在线 | 欧美日韩另类视频 | 五月天视频网 | 超碰精品在线观看 | 五月婷婷狠狠 | 国产中文a | 欧美激情精品久久久久 | 综合网久久 | 中文字幕日韩av | 小草av在线播放 | 91网在线看| 欧美韩国日本在线观看 | 97干com| 久久久国产一区 | 欧美精品午夜 | 欧美另类一二三四区 | 国产午夜一区二区 | 国产精品视频 | 91av播放 | 高清在线一区二区 | 中文字幕一区二区三区乱码不卡 | 国产精品美女久久久久久久 | 天天色天天搞 | 日本成址在线观看 | 国内成人精品2018免费看 | 天天操夜夜看 | 国产中文字幕第一页 | 日韩网站在线播放 | 免费午夜视频在线观看 | 国产精品一区二区白浆 | 国产又粗又猛又爽又黄的视频免费 | 国产h在线播放 | 超级碰99 | www.com.黄 | 制服丝袜成人在线 | av大片网站| 免费精品在线 | 亚洲高清视频在线观看免费 | 女人魂免费观看 | 精品国产亚洲日本 | 视频91| 激情视频91| 蜜臀av性久久久久蜜臀aⅴ流畅 | 高清av免费看| 草久久影院 | 免费久久久久久 | 国产精品九九久久久久久久 | 黄色一级免费 | 在线观看成人一级片 | 中文国产成人精品久久一 | 在线一级片 | 9999在线观看 | 免费观看国产成人 | 国产欧美最新羞羞视频在线观看 | 人人添人人 | 91视频下载 | zzijzzij日本成熟少妇 | 欧美日韩视频精品 | 免费黄色网址大全 | 色黄久久久久久 | 黄网站色成年免费观看 | 五月天婷婷在线观看视频 | 激情视频二区 | www.五月婷 | 四虎成人网 | 成人免费在线播放 | 中文字幕超清在线免费 | 国产99久久久欧美黑人 | 国产成人一区二区三区免费看 | 日韩精品在线视频免费观看 | 免费精品视频在线观看 | 午夜婷婷综合 | 美女黄频在线观看 | 在线看污网站 | 亚洲精品在线视频播放 | 人人澡人人添人人爽一区二区 | 亚洲在线网址 | 五月婷婷视频在线 | 中文字幕av免费在线观看 | 国产高清在线 | 樱空桃av | 久久免费视屏 | 99在线播放 | 国产欧美精品在线观看 | 国产亚洲人 | 999国产在线 | 激情视频久久 | 亚洲精品动漫久久久久 | 国产第一二区 | 久久久免费观看视频 | 国产精品理论视频 | 国产91电影在线观看 | 亚洲无吗av | 亚洲天天在线 | 色婷婷av国产精品 | 国产91精品一区二区绿帽 | 97超碰香蕉 | 亚洲综合日韩在线 | 亚洲日本激情 | 日韩久久久久久久久久 | 日韩videos高潮hd| 久久玖| 国产专区在线 | 夜夜骑日日操 | 天天做日日做天天爽视频免费 | 在线视频app | 国产成人a v电影 | 日本精品中文字幕 | 久久国产综合视频 | 国产流白浆高潮在线观看 | 国产精品毛片久久蜜 | 国产精品精品久久久久久 | 一级a性色生活片久久毛片波多野 | 久久久久激情电影 | 免费黄色看片 | 亚洲人成免费网站 | 99精品一区二区 | av色综合 | 中文字幕欧美日韩va免费视频 | 国产高清视频在线观看 | 久久久99久久 | 麻豆极品| 国产99久久久国产精品 | 九九精品视频在线 | 国产护士hd高朝护士1 | 亚洲欧洲日韩 | 在线视频国产区 | 日韩午夜av | 久久久久亚洲精品成人网小说 |