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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Bootloader】探究bootloader,分析u-boot源码

發(fā)布時(shí)間:2025/4/14 编程问答 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Bootloader】探究bootloader,分析u-boot源码 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Preface

? ?之前也發(fā)表過關(guān)于《Bootloader啟動過程分析》的文章,但是內(nèi)容表達(dá)得比較抽象,大多是文字?jǐn)⑹?#xff0c;所以這里從系統(tǒng)和代碼的角度來深入分析bootloader的啟動過程。

? ?工具:Source Insight

? ?目標(biāo):U-Boot-1.1.6

? ?僅留此分析過程,日后再作補(bǔ)充(純手打也不容易啊,嘿嘿)。

?


U-Boot工程結(jié)構(gòu)

? ?學(xué)習(xí)一個(gè)軟件,尤其是開源軟件,首先應(yīng)該從分析軟件的工程結(jié)構(gòu)開始。一個(gè)好的軟件有良好的工程結(jié)構(gòu),對于讀者學(xué)習(xí)和理解軟件的架構(gòu)以及工作流程都有很好的幫助。

? ?U-Boot的源代碼布局和Linux類似,使用了按照模塊劃分的結(jié)構(gòu),并且充分考慮了體系結(jié)構(gòu)和跨平臺問題。

U-Boot源代碼目錄結(jié)構(gòu)

子目錄名

作用

board開發(fā)板相關(guān)的定義和結(jié)構(gòu)
common包含U-Boot用到的各種處理函數(shù)
cpu各種不同類型的處理器相關(guān)代碼
docU-Boot文檔
drivers常用外部設(shè)備驅(qū)動程序
examples

存放U-Boot開發(fā)代碼樣例

fs

文件系統(tǒng)有關(guān)的代碼,包括cramfs、ext2、fat等常見文件系統(tǒng)

include

U-Boot用到的頭文件

lib_arm

ARM體系結(jié)構(gòu)有關(guān)的數(shù)據(jù)定義和操作

lib_generic

U-Boot通用的操作函數(shù)

net

常用的網(wǎng)絡(luò)協(xié)議,包括bootp、rarp、arp、tftp等

post

上電自檢相關(guān)代碼

rtc

實(shí)時(shí)鐘有關(guān)操作

tools

U-Boot有關(guān)的數(shù)據(jù)代碼

?


U-Boot總體工作流程

? ?與大多數(shù)Bootloader類似,U-Boot的啟動分成stage1和stage2兩個(gè)階段。

? ?stage1使用匯編語言編寫,通常與CPU體系緊密相關(guān),如處理器初始化和設(shè)備初始化代碼等,該階段在start.S文件中實(shí)現(xiàn)。

? ?上圖是U-Boot中Stage1工作流程。Stage1的代碼都是與平臺相關(guān)的,使用匯編語言編寫占用空間小而且執(zhí)行速度快。

? ?Stage1負(fù)責(zé)建立Stage1階段使用堆棧和代碼段,然后復(fù)制Stage2階段的代碼到內(nèi)存。

? ?Stage2階段一般包括:初始化Flash器件、swim 系統(tǒng)內(nèi)存映射、初始化網(wǎng)絡(luò)設(shè)備、進(jìn)入命令循環(huán),接收用戶從串口發(fā)送的命令然后進(jìn)行相應(yīng)的處理。

? ?Stage2使用C語言編寫,用于加載操作系統(tǒng)內(nèi)核,該階段主要是board.c中是start_armboot()函數(shù)實(shí)現(xiàn)。下圖為U-Boot的Stage1和Stage2在Flash和RAM中的分配。

? ?從上圖中可以看出,U-Boot在加載到內(nèi)存后,使用了操作系統(tǒng)空余的內(nèi)存空間。

?


U-Boot啟動流程分析

?

?

? ?從圖中可以看出U-Boot的啟動代碼分布在start.S、low_level_init.S、board.c和main.c文件中

? ?Start.S是U-Boot整個(gè)程序的入口,該文件使用匯編語言編寫,不同體系結(jié)構(gòu)的啟動代碼不同

? ?low_level_init.S是特定開發(fā)板的設(shè)置代碼;

? ?board.c包含開發(fā)板底層設(shè)備驅(qū)動;

? ?main.c是一個(gè)與平臺無關(guān)的代碼,U-Boot應(yīng)用程序的入口在此文件中。

?


①_start標(biāo)號

? ?在U-Boot工程中,每種處理器目錄下都有一個(gè)start.S文件,該文件中有一個(gè)_start標(biāo)號,是整個(gè)U-Boot代碼的入口點(diǎn)。

/**************************************************************************** Jump vector table as in table 3.1 in [1]***************************************************************************/ .globl _start _start: b reset //復(fù)位向量:無條件跳轉(zhuǎn)到reset標(biāo)號ldr pc, _undefined_instruction //未定義指令向量ldr pc, _software_interrupt //軟件中斷向量ldr pc, _prefetch_abort //預(yù)取指令異常向量ldr pc, _data_abort //數(shù)據(jù)操作異常向量ldr pc, _not_used //未使用ldr pc, _irq //慢速中斷向量ldr pc, _fiq //快速中斷向量 _undefined_instruction: .word undefined_instruction //定義中斷向量表入口地址 _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq.balignl 16,0xdeadbeef /**************************************************************************** Startup Code (reset vector)** do important init only if we don't start from memory!* relocate armboot to ram* setup stack* jump to second stage***************************************************************************/ _TEXT_BASE:.word TEXT_BASE //定義整個(gè)錟-Boot鏡像文件在內(nèi)存加載的地址 .globl _armboot_start _armboot_start:.word _start /** These are defined in the board-specific linker script.*/ .globl _bss_start _bss_start:.word __bss_start //定義代碼段起始 .globl _bss_end _bss_end:.word _end //定義代碼段結(jié)束地址 #ifdef CONFIG_USE_IRQ /* IRQ stack memory (calculated at run-time) */ .globl IRQ_STACK_START //定義IRQ的堆棧地址 IRQ_STACK_START:.word 0x0badc0de /* IRQ stack memory (calculated at run-time) */ .globl FIQ_STACK_START //定義FIQ的堆棧地址 FIQ_STACK_START:.word 0x0badc0de #endif

?

? ?_start標(biāo)號下面的代碼主要是一些偽指令,設(shè)置全局變量,供啟動程序把U-Boot映像從Flash存儲器復(fù)制到內(nèi)存中。

? ?其中比較重要的變量是TEXT_BASE,該變量是通過連接腳本得到的。TEXT_BASE變量需要根據(jù)開發(fā)板的情況自己修改,具體地址需要根據(jù)硬件設(shè)計(jì)確定。

? ?_start標(biāo)號一開始定義了ARM處理器7個(gè)中斷向量的向量表,對應(yīng)ARM處理器的7種模式。

由于上電一開始處理器會從0地址執(zhí)行指令,因此第一個(gè)指令直接跳轉(zhuǎn)到reset標(biāo)號。

? ?reset執(zhí)行機(jī)器初始化的一些操作,此處的跳轉(zhuǎn)指令,無論是冷啟動還是熱啟動開發(fā)板都會執(zhí)行reset標(biāo)號的代碼。

? ?reset也屬于一種異常模式,并且該模式的代碼不需要返回。

?


②reset標(biāo)號

? ?reset標(biāo)號的代碼在處理器啟動的時(shí)候最先被執(zhí)行。

/** the actual reset code*/ reset:/** set the cpu to SVC32 mode*/mrs r0,cpsr //保存CPSR寄存器的值到r0寄存器bic r0,r0,#0x1f //清除中斷orr r0,r0,#0xd3msr cpsr,r0 //設(shè)置CPSR為超級保護(hù)模式 /* turn off the watchdog */ //關(guān)閉看門狗 #if defined(CONFIG_S3C2400) # define pWTCON 0x15300000 //看門狗地址 # define INTMSK 0x14400008 /* Interupt-Controller base addresses */ //中斷控制器基址 # define CLKDIVN 0x14800014 /* clock divisor register */ #elif defined(CONFIG_S3C2410) # define pWTCON 0x53000000 # define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ # define INTSUBMSK 0x4A00001C # define CLKDIVN 0x4C000014 /* clock divisor register */ #endif #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)ldr r0, =pWTCON //取出當(dāng)前看門狗控制寄存器的地址到r0mov r1, #0x0 //設(shè)置r1寄存器的值為0str r1, [r0] //寫入看門狗控制寄存器/** mask all IRQs by setting all bits in the INTMR - default*/mov r1, #0xffffffff //設(shè)置r1ldr r0, =INTMSK //取出中斷屏蔽寄存器地址到r0str r1, [r0] //r1的值寫入中斷屏蔽寄存器 # if defined(CONFIG_S3C2410)ldr r1, =0x3ffldr r0, =INTSUBMSKstr r1, [r0] # endif/* FCLK:HCLK:PCLK = 1:2:4 *//* default FCLK is 120 MHz ! */ldr r0, =CLKDIVN //取出時(shí)鐘寄存器地址到r0mov r1, #3 //設(shè)置r1的值str r1, [r0] //寫入時(shí)鐘配置 #endif /* CONFIG_S3C2400 || CONFIG_S3C2410 *//** we do sys-critical inits only at reboot,* not when booting from ram!*/ #ifndef CONFIG_SKIP_LOWLEVEL_INITbl cpu_init_crit //跳轉(zhuǎn)到開發(fā)板相關(guān)初始化代碼 #endif

?

? ?注意,最后根據(jù)CONFIG_SKIP_LOWLEVEL_INIT宏的值是否跳到cpu_init_crit標(biāo)號執(zhí)行。

? ?請注意這里使用的是bl指令,在執(zhí)行完cpu_init_crit標(biāo)號的代碼后會返回。

?

?


③cpu_init_crit標(biāo)號

? ?cpu_init_crit標(biāo)號處的代碼初始化ARM處理器關(guān)鍵的寄存器。

/**************************************************************************** CPU_init_critical registers** setup important registers* setup memory timing***************************************************************************/ #ifndef CONFIG_SKIP_LOWLEVEL_INIT cpu_init_crit:/** flush v4 I/D caches*/mov r0, #0mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ //刷新cachemcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ //刷新TLB/** disable MMU stuff and caches //關(guān)閉MMU*/mrc p15, 0, r0, c1, c0, 0bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)orr r0, r0, #0x00000002 @ set bit 2 (A) Alignorr r0, r0, #0x00001000 @ set bit 12 (I) I-Cachemcr p15, 0, r0, c1, c0, 0/** before relocating, we have to setup RAM timing* because memory timing is board-dependend, you will* find a lowlevel_init.S in your board directory.*/mov ip, lrbl lowlevel_init //跳轉(zhuǎn)到lowlevel_initmov lr, ipmov pc, lr #endif /* CONFIG_SKIP_LOWLEVEL_INIT */

?

? ?注意刷新cache和TLB。

? ?cache是一種高速緩存存儲器,用于保存CPU頻繁使用的數(shù)據(jù),在使用Cache技術(shù)的處理器上,當(dāng)一條指令要訪問內(nèi)存的數(shù)據(jù)時(shí),首先查詢cache緩存中是否有數(shù)據(jù)以及數(shù)據(jù)是否過期,如果數(shù)據(jù)未過期則從cache讀出數(shù)據(jù),處理器會定期回寫cache中的數(shù)據(jù)到內(nèi)存。根據(jù)程序的局部性原理,使用cache后可以大大加快處理器訪問內(nèi)存數(shù)據(jù)的速度。

? ?TLB的作秀是在處理器訪問內(nèi)存數(shù)據(jù)的時(shí)候做地址轉(zhuǎn)換。TLB的全稱是Translation Lookaside Buffer,可以翻譯做旁路緩沖TLB中存放了一些頁表文件,文件中記錄了虛擬地址和物理地址的映射關(guān)系。當(dāng)應(yīng)用程序訪問一個(gè)虛擬地址的時(shí)候,會從TLB中查詢出對就的物理地址,然后訪問物理地址。TLB通常是一個(gè)分層結(jié)構(gòu),使用與cache類似的原理。處理器使用一定的算法把最常用的頁表放在最先訪問的層次。

? ?MMU是內(nèi)存管理單元(Memory Management Unit)的縮寫,在現(xiàn)代計(jì)算機(jī)體系結(jié)構(gòu)上,MMU被廣泛應(yīng)用。使用MMU技術(shù)可以向應(yīng)用程序提供一個(gè)巨大的虛擬地址空間。在U-Boot初始化的時(shí)候,程序看到的地址都是物理地址,無須使用MMU。

?


④lowlevel_init標(biāo)號

? ?lowlevel_init標(biāo)號,執(zhí)行與開發(fā)板相關(guān)的初始化配置。

.globl lowlevel_init lowlevel_init:/* memory control configuration *//* make r0 relative the current location so that it *//* reads SMRDATA out of FLASH rather than memory ! */ldr r0, =SMRDATA //讀取SMRDATA變量地址ldr r1, _TEXT_BASE //讀取_TEXT_BASE變量地址sub r0, r0, r1ldr r1, =BWSCON /* Bus Width Status Controller */ //讀取總線寬度寄存器add r2, r0, #13*4 //得到SMRDATA占用的大小 0:ldr r3, [r0], #4 //加載SMRDATA到內(nèi)存str r3, [r1], #4cmp r2, r0bne 0b/* everything is fine now */mov pc, lr.ltorg /* the literal pools origin */ SMRDATA: //定義SMRDATA的值.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)).word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)).word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)).word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)).word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)).word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)).word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)).word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)).word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)).word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT).word 0x32.word 0x30.word 0x30

?

? ?程序中需要計(jì)算SMRDATA需要加載的內(nèi)存地址和大小。

? ?首先讀取SMRDATA的變量地址,之后計(jì)算存放的內(nèi)存地址并且記錄在r0寄存器,然后根據(jù)總線寬度計(jì)算需要加載的SMRDATA大小,并且把加載結(jié)束的地址存放在r2寄存器。

? ?最后復(fù)制SMRDATA到內(nèi)存。SMRDATA是開發(fā)板上內(nèi)存映射的配置。

?


⑤relocate標(biāo)號

? ?relocate部分的代碼負(fù)責(zé)把U-Boot Stage2的代碼從Flash存儲器加載到內(nèi)存。

#ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate: /* relocate U-Boot to RAM */adr r0, _start /* r0 <- current position of code *///獲取當(dāng)前代碼存放地址ldr r1, _TEXT_BASE /* test if we run from flash or RAM *///獲取內(nèi)存存放代碼地址cmp r0, r1 /* don't reloc during debug *///檢查是否需要加載beq stack_setupldr r2, _armboot_start //獲取stage2代碼存放地址ldr r3, _bss_start //獲取內(nèi)存代碼段起始地址sub r2, r3, r2 /* r2 <- size of armboot */ //計(jì)算stage2代碼長度add r2, r0, r2 /* r2 <- source end address */ //計(jì)算stage2代碼結(jié)束地址 copy_loop:ldmia r0!, {r3-r10} /* copy from source address [r0] *///從Flash復(fù)制代碼到內(nèi)存stmia r1!, {r3-r10} /* copy to target address [r1] */cmp r0, r2 /* until source end addreee [r2] */ble copy_loop #endif /* CONFIG_SKIP_RELOCATE_UBOOT *//* Set up the stack */ stack_setup: //在內(nèi)存中建立堆棧ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ //分配內(nèi)存區(qū)域sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ #ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endifsub sp, r0, #12 /* leave 3 words for abort-stack */ clear_bss: //初始化內(nèi)存bss段內(nèi)容為0ldr r0, _bss_start /* find start of bss segment *///查找bss段起始地址ldr r1, _bss_end /* stop here *///查找bss段結(jié)束地址mov r2, #0x00000000 /* clear */ clbss_l:str r2, [r0] /* clear loop... */add r0, r0, #4cmp r0, r1ble clbss_l #if 0/* try doing this stuff after the relocation */ldr r0, =pWTCONmov r1, #0x0str r1, [r0]/** mask all IRQs by setting all bits in the INTMR - default*/mov r1, #0xffffffffldr r0, =INTMRstr r1, [r0]/* FCLK:HCLK:PCLK = 1:2:4 *//* default FCLK is 120 MHz ! */ldr r0, =CLKDIVNmov r1, #3str r1, [r0]/* END stuff after relocation */ #endifldr pc, _start_armboot //設(shè)置程序指針為start_armboot()函數(shù)地址 _start_armboot: .word start_armboot

?

? ?程序首先檢查當(dāng)前是否在內(nèi)存中執(zhí)行代碼,根據(jù)結(jié)果決定是否需要從Flash存儲器加載代碼。

程序通過獲取_start和_TEXT_BASE所在的地址比較,如果地址相同說明程序已經(jīng)在內(nèi)存中,無須加載。

? ?然后計(jì)算要加載的stage2代碼起始地址和長度,然后在循環(huán)復(fù)制Flash的數(shù)據(jù)到內(nèi)存,每次可以復(fù)制8個(gè)字長的數(shù)據(jù)。stage2程序復(fù)制完成后,程序設(shè)置系統(tǒng)堆棧,最后清空內(nèi)存bss段內(nèi)容。

? ?relocate程序最后在設(shè)置程序指針寄存器為start_armboot()函數(shù)地址,程序跳轉(zhuǎn)到stage2部分執(zhí)行,注意最后的定義,_start_armboot全局變量的值是C語言函數(shù)start_armboot()函數(shù)的地址,使用這種方式可以在匯編中調(diào)用C語言編寫的函數(shù)。

? ?另外,有一種NOR類型Flash存儲器,可以像使用內(nèi)存一樣直接執(zhí)行程序,NOR Flash被映射到地址0開始的內(nèi)存空間。

? ?注意,程序中第12行的_armboot_start即標(biāo)號⑥_armboot_start

?


⑦start_armboot()函數(shù)

? ?start_armboot()函數(shù)主要初始化ARM系統(tǒng)的硬件和環(huán)境變量,包括Flash存儲器、FrameBuffer、網(wǎng)卡等,最后進(jìn)入U(xiǎn)-Boot應(yīng)用程序主循環(huán)。

void start_armboot (void) {init_fnc_t **init_fnc_ptr;char *s; #ifndef CFG_NO_FLASHulong size; #endif #if defined(CONFIG_VFD) || defined(CONFIG_LCD)unsigned long addr; #endif/* Pointer is writable since we allocated a register for it */gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));/* compiler optimization barrier needed for GCC >= 3.4 */__asm__ __volatile__("": : :"memory");memset ((void*)gd, 0, sizeof (gd_t));gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));memset (gd->bd, 0, sizeof (bd_t));monitor_flash_len = _bss_start - _armboot_start;for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {if ((*init_fnc_ptr)() != 0) {hang ();}} #ifndef CFG_NO_FLASH/* configure available FLASH banks */size = flash_init (); //初始化Flash存儲器配置display_flash_config (size); //顯示Flash存儲器配置 #endif /* CFG_NO_FLASH */ #ifdef CONFIG_VFD # ifndef PAGE_SIZE # define PAGE_SIZE 4096 # endif/** reserve memory for VFD display (always full pages)*//* bss_end is defined in the board-specific linker script */addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); //計(jì)算FrameBuffer內(nèi)存地址size = vfd_setmem (addr); //計(jì)算FrameBuffer占用內(nèi)存大小gd->fb_base = addr; //設(shè)置FrameBuffer內(nèi)存起始地址 #endif /* CONFIG_VFD */ #ifdef CONFIG_LCD # ifndef PAGE_SIZE # define PAGE_SIZE 4096 # endif/** reserve memory for LCD display (always full pages)*//* bss_end is defined in the board-specific linker script */addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); //計(jì)算rameBuffer內(nèi)存地址size = lcd_setmem (addr); //計(jì)算FrameBuffer占用內(nèi)存大小gd->fb_base = addr; //設(shè)置FrameBuffer內(nèi)存起始地址 #endif /* CONFIG_LCD *//* armboot_start is defined in the board-specific linker script */mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); #if (CONFIG_COMMANDS & CFG_CMD_NAND)puts ("NAND: ");nand_init(); /* go init the NAND */ //初始化NAND Flash存儲器 #endif #ifdef CONFIG_HAS_DATAFLASHAT91F_DataflashInit(); //初始化Hash表dataflash_print_info(); #endif/* initialize environment */env_relocate (); //重新設(shè)置環(huán)境變量 #ifdef CONFIG_VFD/* must do this after the framebuffer is allocated */drv_vfd_init(); //初始化虛擬顯示設(shè)置 #endif /* CONFIG_VFD *//* IP Address */gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr"); //設(shè)置網(wǎng)卡的IP地址/* MAC Address */{int i;ulong reg;char *s, *e;char tmp[64];i = getenv_r ("ethaddr", tmp, sizeof (tmp)); //從網(wǎng)卡寄存器讀取MAC地址s = (i > 0) ? tmp : NULL;for (reg = 0; reg < 6; ++reg) {gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;if (s)s = (*e) ? e + 1 : e;} #ifdef CONFIG_HAS_ETH1i = getenv_r ("eth1addr", tmp, sizeof (tmp)); //讀取Hash值s = (i > 0) ? tmp : NULL;for (reg = 0; reg < 6; ++reg) {gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;if (s)s = (*e) ? e + 1 : e;} #endif}devices_init (); /* get the devices list going. */ //初始化開發(fā)板上的設(shè)備 #ifdef CONFIG_CMC_PU2load_sernum_ethaddr (); #endif /* CONFIG_CMC_PU2 */jumptable_init (); //初始化跳轉(zhuǎn)表console_init_r (); /* fully init console as a device */ //初始化控制臺 #if defined(CONFIG_MISC_INIT_R)/* miscellaneous platform dependent initialisations */misc_init_r (); //初始化其他設(shè)備 #endif/* enable exceptions */enable_interrupts (); //打開中斷/* Perform network card initialisation if necessary */ #ifdef CONFIG_DRIVER_CS8900cs8900_get_enetaddr (gd->bd->bi_enetaddr); //獲取CS8900網(wǎng)卡MAC地址 #endif #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)if (getenv ("ethaddr")) {smc_set_mac_addr(gd->bd->bi_enetaddr); //設(shè)置SMC網(wǎng)卡MAC地址} #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 *//* Initialize from environment */if ((s = getenv ("loadaddr")) != NULL) {load_addr = simple_strtoul (s, NULL, 16);} #if (CONFIG_COMMANDS & CFG_CMD_NET)if ((s = getenv ("bootfile")) != NULL) {copy_filename (BootFile, s, sizeof (BootFile)); //保存FrameBuffer} #endif /* CFG_CMD_NET */ #ifdef BOARD_LATE_INITboard_late_init (); //開發(fā)板相關(guān)設(shè)備初始化 #endif #if (CONFIG_COMMANDS & CFG_CMD_NET) #if defined(CONFIG_NET_MULTI)puts ("Net: "); #endifeth_initialize(gd->bd); #endif/* main_loop() can return to retry autoboot, if so just run it again. */for (;;) {main_loop (); //進(jìn)入主循環(huán)}/* NOTREACHED - no way out of command loop except booting */ } void hang (void) {puts ("### ERROR ### Please RESET the board ###\n");for (;;); }

?

? ?start_armboot()函數(shù)代碼里有許多的宏相關(guān),這個(gè)根據(jù)開發(fā)板的情況進(jìn)行配置。函數(shù)里面的board_late_init()函數(shù),該函數(shù)是開發(fā)板提供的,供不同的開發(fā)板做一些特有的初始化工作。

? ?在start_armboot()函數(shù)中,使用宏開關(guān)括起來的代碼是在各種開發(fā)板是最常用的功能,如CS8900網(wǎng)卡配置。整個(gè)函數(shù)配置完畢后,進(jìn)入一個(gè)for死循環(huán),調(diào)用main_loop()函數(shù)。這里需要注意,在main_loop()函數(shù)中也有一個(gè)for死循環(huán)。

? ?start_armboot()函數(shù)使用死循環(huán)調(diào)用main_loop()函數(shù),作用是防止main_loop()函數(shù)開始的初始化代碼如果調(diào)用失敗后重新執(zhí)行初始化操作,保證程序能進(jìn)入到U-Boot的命令行。

?

?


⑧main_loop()函數(shù)

? ?main_loop()函數(shù)做的都是與具體平臺無關(guān)的工作,主要包括初始化啟動次數(shù)限制機(jī)制、設(shè)置軟件版本號、打印啟動信息、解析命令等。

? ??設(shè)置啟動次數(shù)有關(guān)參數(shù)。在進(jìn)入main_loop()函數(shù)后,首先是根據(jù)配置加載已經(jīng)保留的啟動次數(shù),并且根據(jù)配置判斷是否超過啟動次數(shù)。

void main_loop (void) { #ifndef CFG_HUSH_PARSERstatic char lastcommand[CFG_CBSIZE] = { 0, };int len;int rc = 1;int flag; #endif #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)char *s;int bootdelay; #endif #ifdef CONFIG_PREBOOTchar *p; #endif #ifdef CONFIG_BOOTCOUNT_LIMITunsigned long bootcount = 0;unsigned long bootlimit = 0;char *bcs;char bcs_set[16]; #endif /* CONFIG_BOOTCOUNT_LIMIT */ #if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO)ulong bmp = 0; /* default bitmap */extern int trab_vfd (ulong bitmap); #ifdef CONFIG_MODEM_SUPPORTif (do_mdm_init)bmp = 1; /* alternate bitmap */ #endiftrab_vfd (bmp); #endif /* CONFIG_VFD && VFD_TEST_LOGO */ #ifdef CONFIG_BOOTCOUNT_LIMITbootcount = bootcount_load(); //加載保存的啟動次數(shù)bootcount++; //啟動次數(shù)加1bootcount_store (bootcount); //更新啟動次數(shù)sprintf (bcs_set, "%lu", bootcount); //打印啟動次數(shù)setenv ("bootcount", bcs_set);bcs = getenv ("bootlimit");bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0; //轉(zhuǎn)換啟動次數(shù)字符串為UINT類型 #endif /* CONFIG_BOOTCOUNT_LIMIT */

?

? ?函數(shù)啟動次數(shù)限制功能,啟動次數(shù)限制可以被用戶設(shè)置一個(gè)啟動次數(shù),然后保存在Flash存儲器的特定位置,當(dāng)?shù)竭_(dá)啟動次數(shù)后,U-Boot無法啟動,該功能適合一些商業(yè)產(chǎn)品,通過配置不同的License限制用戶重新啟動系統(tǒng)。

? ??接下來是Modem功能。如果系統(tǒng)中有Modem,打開該功能可以接受其他用戶通過電話網(wǎng)絡(luò)的撥號請求。Modem功能通常供一些遠(yuǎn)程控制的系統(tǒng)使用

#ifdef CONFIG_MODEM_SUPPORTdebug ("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init);if (do_mdm_init) { //判斷是否需要初始化Modemchar *str = strdup(getenv("mdm_cmd")); //獲取Modem參數(shù)setenv ("preboot", str); /* set or delete definition */if (str != NULL)free (str);mdm_init(); /* wait for modem connection */ //初始化Modem} #endif /* CONFIG_MODEM_SUPPORT */

?

? ??然后設(shè)置U-Boot版本號,初始化命令自動完成功能等。

#ifdef CONFIG_VERSION_VARIABLE{extern char version_string[];setenv ("ver", version_string); /* set version variable */ //設(shè)置版本號} #endif /* CONFIG_VERSION_VARIABLE */ #ifdef CFG_HUSH_PARSERu_boot_hush_start (); //初始化Hash功能 #endif #ifdef CONFIG_AUTO_COMPLETEinstall_auto_complete(); //初始化命令自動完成功能 #endif #ifdef CONFIG_PREBOOTif ((p = getenv ("preboot")) != NULL) { # ifdef CONFIG_AUTOBOOT_KEYEDint prev = disable_ctrlc(1); /* disable Control C checking *///關(guān)閉Crtl+C組合鍵 # endif # ifndef CFG_HUSH_PARSERrun_command (p, 0); //運(yùn)行Boot參數(shù) # elseparse_string_outer(p, FLAG_PARSE_SEMICOLON |FLAG_EXIT_FROM_LOOP); # endif # ifdef CONFIG_AUTOBOOT_KEYEDdisable_ctrlc(prev); /* restore Control C checking *///恢復(fù)Ctrl+C組合鍵 # endif} #endif /* CONFIG_PREBOOT */

?

? ?程序開始是動態(tài)版本號功能支持代碼,version_string變量是在其他文件定義的一個(gè)字符串變量,當(dāng)用戶改變U-Boot版本的時(shí)候會更新該變量。打開動態(tài)版本支持功能后,U-Boot在啟動的時(shí)候會顯示最新的版本號。

? ?install_auto_comlpete()函數(shù)設(shè)置命令行自動完成功能,該功能與linux的shell類似,當(dāng)用戶輸入一個(gè)部分命令后,可以通過按下鍵盤上的Tab鍵補(bǔ)全命令的剩余部分,main_loop()函數(shù)不同的功能使用宏開關(guān)控制不僅能提高代碼模塊化,理主要的是針對嵌入式系統(tǒng)Flash存儲器大小設(shè)計(jì)的。在嵌入式系統(tǒng)上,不同的系統(tǒng)Flash存儲空間不同。對于一些Flash空間比較緊張的設(shè)備來說,通過宏開關(guān)關(guān)閉一些不是特別必要的功能如命令行自動完成,可以減小U-Boot編譯后的文件大小。

? ??在進(jìn)入主循環(huán)之前,如果配置了啟動延遲功能,需要等待用戶從串口或者網(wǎng)絡(luò)接口輸入。如果用戶按下任意鍵打斷,啟動流程,會向終端打印出一個(gè)啟動菜單。

#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)s = getenv ("bootdelay");bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; //啟動延遲debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay); # ifdef CONFIG_BOOT_RETRY_TIMEinit_cmd_timeout (); //初始化命令行超時(shí)機(jī)制 # endif /* CONFIG_BOOT_RETRY_TIME */ #ifdef CONFIG_BOOTCOUNT_LIMITif (bootlimit && (bootcount > bootlimit)) { //檢查是否超出啟動次數(shù)限制printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",(unsigned)bootlimit);s = getenv ("altbootcmd");}else #endif /* CONFIG_BOOTCOUNT_LIMIT */s = getenv ("bootcmd"); //獲取啟動命令參數(shù)debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");if (bootdelay >= 0 && s && !abortboot (bootdelay)) { //檢查是否支持啟動延遲功能 # ifdef CONFIG_AUTOBOOT_KEYEDint prev = disable_ctrlc(1); /* disable Control C checking *///關(guān)閉Ctrl+C組合鍵 # endif # ifndef CFG_HUSH_PARSERrun_command (s, 0); //運(yùn)行啟動命令行 # elseparse_string_outer(s, FLAG_PARSE_SEMICOLON |FLAG_EXIT_FROM_LOOP); # endif # ifdef CONFIG_AUTOBOOT_KEYEDdisable_ctrlc(prev); /* restore Control C checking *///打開Ctrl+C組合鍵 # endif} # ifdef CONFIG_MENUKEYif (menukey == CONFIG_MENUKEY) { //檢查是否支持菜單鍵s = getenv("menucmd");if (s) { # ifndef CFG_HUSH_PARSERrun_command (s, 0); # elseparse_string_outer(s, FLAG_PARSE_SEMICOLON |FLAG_EXIT_FROM_LOOP); # endif}} #endif /* CONFIG_MENUKEY */ #endif /* CONFIG_BOOTDELAY */ #ifdef CONFIG_AMIGAONEG3SE{extern void video_banner(void);video_banner(); //打印啟動圖標(biāo)} #endif

?

? ??在各功能設(shè)置完畢后,程序進(jìn)入一個(gè)for死循環(huán),該循環(huán)不斷使用readline()函數(shù)從控制臺(一般是串口)讀取用戶的輸入,然后解析,有關(guān)如何解析命令則可以參考U-Boot代碼中run_command()函數(shù)的定義。

/** Main Loop for Monitor Command Processing*/ #ifdef CFG_HUSH_PARSERparse_file_outer();/* This point is never reached */for (;;); #elsefor (;;) { //進(jìn)入命令行超時(shí) #ifdef CONFIG_BOOT_RETRY_TIMEif (rc >= 0) {/* Saw enough of a valid command to* restart the timeout.*/reset_cmd_timeout(); //設(shè)置命令行超時(shí)} #endiflen = readline (CFG_PROMPT); //讀取命令flag = 0; /* assume no special flags for now */if (len > 0)strcpy (lastcommand, console_buffer);else if (len == 0)flag |= CMD_FLAG_REPEAT; #ifdef CONFIG_BOOT_RETRY_TIMEelse if (len == -2) {/* -2 means timed out, retry autoboot*/puts ("\nTimed out waiting for command\n"); # ifdef CONFIG_RESET_TO_RETRY/* Reinit board to run initialization code again */do_reset (NULL, 0, 0, NULL); # elsereturn; /* retry autoboot */ # endif} #endifif (len == -1)puts ("<INTERRUPT>\n");elserc = run_command (lastcommand, flag); //運(yùn)行命令if (rc <= 0) {/* invalid command or not repeatable, forget it */lastcommand[0] = 0;}} #endif /*CFG_HUSH_PARSER*/ }

?


結(jié)束語

? ?整個(gè)U-Boot的啟動流程代碼,最關(guān)鍵的就是這些了,其中主要語句都作了相應(yīng)注釋,另外我把自己注釋后的四個(gè)源文件上傳到附件,以備查看。

? ?如果有人覺得哪里注釋沒對,歡迎留言探討。

?

?

本文出自 “成鵬致遠(yuǎn)” 博客,請務(wù)必保留此出處http://infohacker.blog.51cto.com/6751239/1202976

轉(zhuǎn)載于:https://www.cnblogs.com/lcw/p/3159399.html

總結(jié)

以上是生活随笔為你收集整理的【Bootloader】探究bootloader,分析u-boot源码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

夜夜爽88888免费视频4848 | 亚洲国产精品va在线 | 久久久久久国产精品免费 | 国产黄大片 | 五月天.com| 久久综合色8888 | 国产高h视频| 精品国产一区二区三区久久久 | 亚洲国产美女久久久久 | 99久久精品网| 色狠狠综合天天综合综合 | 免费下载高清毛片 | 99这里都是精品 | 婷婷午夜激情 | 精品欧美一区二区在线观看 | 欧美精品久久久久性色 | 欧美一级电影片 | 婷婷综合亚洲 | 久久夜av| 国产精品一区二区果冻传媒 | 在线成人观看 | 成人禁用看黄a在线 | 亚洲精品在线观看中文字幕 | 精品国自产在线观看 | 三级黄色大片在线观看 | 久久永久免费 | 女人18精品一区二区三区 | 91最新国产| 区一区二区三在线观看 | 精品国产区 | 国产流白浆高潮在线观看 | 国产精品福利无圣光在线一区 | 81国产精品久久久久久久久久 | 亚洲综合成人专区片 | 成人国产精品免费观看 | 欧美 亚洲 另类 激情 另类 | 人人艹视频 | 欧美另类tv| 丰满少妇久久久 | 日韩超碰 | 国产精品美女久久久久久网站 | 欧美日韩国产三级 | 国产精品丝袜在线 | zzijzzij日本成熟少妇 | 国产黄色片网站 | 中文字幕人成一区 | 综合在线观看 | 免费久草视频 | 亚洲国产精品久久久久 | 亚洲狠狠婷婷综合久久久 | 中文乱幕日产无线码1区 | 欧美a级成人淫片免费看 | 91亚洲精品久久久 | 免费看一级特黄a大片 | 99视频在线观看视频 | 亚洲精品视频免费在线 | 欧美一级片在线播放 | 国产精品正在播放 | 国产精品一区二区你懂的 | 果冻av在线 | 九九精品久久久 | 国产一区视频在线播放 | 久草在线观看视频免费 | 91伊人久久大香线蕉蜜芽人口 | 欧美一级黄色视屏 | 国产午夜免费视频 | 亚洲免费专区 | 一区二区视频在线免费观看 | 国产69精品久久app免费版 | 人人射人人 | 午夜999 | 最新av在线播放 | 免费在线观看污 | 色av男人的天堂免费在线 | 午夜视频在线观看一区二区三区 | 操夜夜操 | 国产免费一区二区三区最新 | 中文字幕亚洲综合久久五月天色无吗'' | 亚洲美女免费精品视频在线观看 | 美女久久一区 | 黄色国产区 | av中文字幕在线看 | 欧美天堂影院 | 丁香视频| 在线观看国产永久免费视频 | 免费av黄色 | 在线免费视频你懂的 | 免费在线一区二区 | 四虎永久网站 | 国产区免费在线 | 在线免费观看的av网站 | 久久国产热视频 | 国产视频精品久久 | 丝袜美腿一区 | 成人一级片在线观看 | 一区二区欧美在线观看 | 国产成人精品在线播放 | 成人精品电影 | 免费视频成人 | 国产字幕在线看 | 国产精品高清免费在线观看 | 91九色视频导航 | 欧美一二三区在线播放 | 天天操天天摸天天爽 | 亚洲全部视频 | 久久免费影院 | 日韩欧美高清视频在线观看 | 正在播放日韩 | 国产精品四虎 | 日韩美女av在线 | 欧美男同网站 | 色在线中文字幕 | 亚洲涩涩涩涩涩涩 | 日韩美女黄色片 | 久久涩涩网站 | 成人a级黄色片 | 成人在线免费看视频 | 日本黄色大片免费看 | 日本久久久久久 | 黄色91免费观看 | 热久久视久久精品18亚洲精品 | 久久久久成人精品 | 国产精品久久久久影院 | 欧美大片在线观看一区 | 四虎精品成人免费网站 | 97精产国品一二三产区在线 | 亚洲第一久久久 | 国产一线二线三线在线观看 | 久久久午夜精品福利内容 | 91久久久久久久一区二区 | 国产精品久久久久影院 | 中文在线字幕免费观看 | 国产精品亚洲成人 | 国产一区精品在线观看 | 美女久久一区 | 超碰97国产在线 | 成人av影视 | 探花视频在线观看免费 | 亚洲成a人片综合在线 | 99久久精品免费看国产一区二区三区 | 久久人人爽人人人人片 | 激情五月五月婷婷 | 99热999| 国产久草在线观看 | 在线视频欧美亚洲 | www.av在线.com | 人人干天天射 | 国产精品久久久久aaaa九色 | 日韩三级久久 | 97理论片 | 啪啪激情网 | 亚洲天堂网站视频 | 国产一区二区在线影院 | 久久99欧美| 天堂入口网站 | 91免费高清视频 | 色婷婷国产精品一区在线观看 | 欧美一区二区三区在线视频观看 | 国产精品久久久久久久久婷婷 | 91麻豆精品91久久久久同性 | 久久久久久久久久久成人 | 国产中文伊人 | 91视频免费| 久久99精品国产麻豆宅宅 | 天天射成人 | 欧美午夜久久 | 精品国产一区二区三区蜜臀 | 一区二区在线电影 | 少妇按摩av| 中文字幕在线观看日本 | 人人玩人人添人人澡超碰 | 久草网视频在线观看 | 久久久免费av | 亚洲精选视频免费看 | 中文字幕色婷婷在线视频 | 免费看一级特黄a大片 | 99九九99九九九视频精品 | 激情五月六月婷婷 | 国产精品国产精品 | 天天射天天舔天天干 | 国产成人av一区二区三区在线观看 | 日韩av在线免费播放 | 九九九九热精品免费视频点播观看 | 国产中的精品av小宝探花 | 久久人人爽人人爽人人片av免费 | 欧美日韩视频在线观看一区二区 | 国产成人三级在线播放 | 日韩欧美国产精品 | 日本中文字幕网址 | 蜜臀av夜夜澡人人爽人人 | 欧美激情奇米色 | 久久视频二区 | 婷婷色六月天 | 九九热免费在线观看 | av丁香花 | 天天综合网 天天综合色 | 中国一级特黄毛片大片久久 | 亚洲精品免费播放 | 激情在线网站 | 天天干,天天射,天天操,天天摸 | 777久久久 | 成人免费视频网站在线观看 | 97综合视频 | 一本一道久久a久久精品 | 一级大片在线观看 | 丁香 久久 综合 | 精品视频久久久 | 九九视频热 | 免费a v在线| 亚洲第一中文字幕 | 99视频国产在线 | 人人插人人 | 五月天久久精品 | 91成熟丰满女人少妇 | 日韩精品免费在线观看视频 | 国产一区二区免费看 | 伊人五月天 | 9i看片成人免费看片 | a国产精品| 特级西西444www大精品视频免费看 | 99久久久久免费精品国产 | 在线a视频免费观看 | 日本中文字幕网 | 欧美一级高清片 | 超碰在线91| 婷婷在线免费 | 九九热1 | 波多野结衣在线观看视频 | 色综合 久久精品 | 亚洲精品网页 | 久久精品艹 | 456免费视频| 成人黄色免费观看 | av网站大全免费 | 2018好看的中文在线观看 | 久久久久久久久久久福利 | 成人av网站在线观看 | 亚洲国产丝袜在线观看 | 伊人天天综合 | 久久试看| 国产精品视频地址 | 色九九在线 | 麻豆精品在线 | 欧美日韩成人一区 | 久久91网| 在线国产一区二区三区 | 国产一区二区高清不卡 | 日日夜夜人人精品 | 国产精品视频不卡 | 久久欧美视频 | 亚洲欧洲精品久久 | 麻豆视频国产在线观看 | 成人久久久电影 | 国产精品久久久久av福利动漫 | 五月天亚洲激情 | 丁香在线视频 | 国产在线a | 正在播放亚洲精品 | 天天操天天干天天插 | av大全免费在线观看 | 三级av网| 国产精品一区二区三区观看 | 69国产在线观看 | 国产福利在线免费 | 国产一区播放 | 在线小视频| 国产色一区 | 国产99色| 日批视频在线观看免费 | 国产一区二区三区网站 | 91久久精品一区二区三区 | 五月婷婷一区 | 成人国产精品 | 亚州国产精品视频 | 欧美国产日韩一区 | 国产高清久久久久 | 嫩草av影院| 久爱综合| 日日夜夜91 | 色综合五月天 | 伊人久久五月天 | 狠狠干天天色 | 亚洲在线视频观看 | 国产精品亚洲成人 | 亚洲永久精品国产 | 美女视频永久黄网站免费观看国产 | 在线免费高清一区二区三区 | 中文字幕资源网 | 免费三级黄色片 | 色综合久久五月天 | 成人中文字幕av | 在线观看国产成人av片 | 国产成人精品亚洲日本在线观看 | 亚洲另类视频在线 | 91九色自拍 | free,性欧美 九九交易行官网 | 国产理论一区二区三区 | 天天骚夜夜操 | 久久亚洲专区 | 日韩在线中文字幕 | 日韩欧美视频在线 | 国产精品igao视频网入口 | 天天干天天操天天入 | 欧美精品在线免费 | av高清一区二区三区 | 日韩欧美在线综合网 | 亚洲精品美女免费 | 成人综合婷婷国产精品久久免费 | 麻豆成人精品视频 | 国产亚洲精品免费 | 99精品国产一区二区三区麻豆 | 在线有码中文 | 日韩精品免费一区二区 | 丝袜网站在线观看 | 99999精品 | 97av视频| 国产综合精品久久 | 亚洲一区二区视频 | 香蕉视频免费看 | 久久综合日 | 日韩精品视 | 日本一区二区不卡高清 | 国产夫妻性生活自拍 | 国产一区二区三区高清播放 | 中文字幕在线免费观看 | 久久乐九色婷婷综合色狠狠182 | www成人av| 91精品高清| 黄色成人在线 | 西西44人体做爰大胆视频 | 91丨九色丨高潮 | 精品视频国产一区 | 国产v视频 | 精品色综合 | 亚洲国产69 | 亚洲国产精品成人av | www亚洲国产 | 伊人狠狠色| 天天在线视频色 | 亚洲日本一区二区在线 | 在线播放 日韩专区 | 成人99免费视频 | 午夜色影院 | 久久99国产综合精品免费 | 久久精品欧美一区二区三区麻豆 | 九九免费精品视频在线观看 | 黄色大片入口 | 国产精品久久99精品毛片三a | 亚洲黄色在线播放 | 久久九九国产精品 | 最新成人av | 国产91免费在线观看 | 国产精品麻豆视频 | 国产小视频91 | 久久精品这里热有精品 | 国产91粉嫩白浆在线观看 | 婷婷六月色 | 国产一区在线免费观看视频 | 国产亚洲人成网站在线观看 | 欧美日韩高清在线 | 欧美激情视频免费看 | 色综合天天综合在线视频 | 午夜精品久久久久久久99水蜜桃 | 992tv成人免费看片 | 欧美一级片免费观看 | 在线国产视频 | 亚洲综合在线观看视频 | 99re热精品视频 | 国产在线播放一区二区三区 | 天天狠狠操 | 久久99在线观看 | 香蕉影视app | 欧美激情视频久久 | 成年人在线观看视频免费 | 又黄又爽免费视频 | 日韩在线视频观看 | 久久精彩 | 国产亚洲精品成人av久久ww | 一区三区在线欧 | 看污网站| 成人97人人超碰人人99 | 国产精品人成电影在线观看 | 亚洲无人区小视频 | 久久久久久久久精 | 91亚洲精品久久久久图片蜜桃 | 国产麻豆精品在线观看 | 亚洲特级毛片 | 免费看毛片网站 | aaa毛片视频 | 黄色免费高清视频 | 91理论片午午伦夜理片久久 | 亚洲女欲精品久久久久久久18 | 四虎影视4hu4虎成人 | 五月婷婷综合在线视频 | 久久精品这里都是精品 | 香蕉在线观看 | 日本三级不卡视频 | 99色网站 | 国产九色视频在线观看 | 久久久免费播放 | 日韩三级视频在线看 | 午夜精品久久久久久久久久 | 韩国三级av在线 | 久操久| 国内精品久久天天躁人人爽 | 91成人免费观看视频 | 91桃色在线免费观看 | 最近中文字幕高清字幕在线视频 | 涩五月婷婷 | 亚洲aⅴ乱码精品成人区 | 91精品第一页 | 午夜三级在线 | 欧美精品成人在线 | 免费黄色在线播放 | 精品一区二区三区香蕉蜜桃 | 国产精品久久久久久久久久久久久久 | 最新av网站在线观看 | 九草视频在线 | 久久久国产网站 | 日韩精品一区二区三区中文字幕 | 在线成人性视频 | 国产在线精品一区二区三区 | 免费国产黄线在线观看视频 | 欧美成a人片在线观看久 | 亚洲 欧美 日韩 综合 | www.91成人 | 久久午夜电影院 | 99视频一区 | 欧美午夜精品久久久久 | 婷婷免费视频 | 国内精品免费久久影院 | 99精品国产99久久久久久97 | 久久激情影院 | 欧美黄色软件 | 国产精品 视频 | 亚洲午夜精品久久久久久久久 | 综合色中色 | 国产色久| 人人插人人玩 | 国产成人av免费在线观看 | 麻豆视频在线看 | 摸bbb搡bbb搡bbbb | 国产手机视频在线观看 | 亚洲最大的av网站 | 久久久午夜影院 | 日韩av一区二区在线播放 | 日韩在线观看你懂的 | 亚洲国产福利视频 | 欧美另类sm图片 | 久久精国产 | 亚洲国产操| 免费色av| 精品国产亚洲日本 | 精品久久99 | 国产精品久久99精品毛片三a | 欧美最猛性xxxxx(亚洲精品) | 高清国产在线一区 | 在线观看免费 | 久久久国产精品麻豆 | av 一区二区三区四区 | 伊人激情网 | 91av久久| 久久精品视频网 | 婷婷激情小说网 | 日韩在线观看第一页 | 久久国产精品一区二区 | 国产视频一区在线播放 | 国产福利不卡视频 | 国产高清在线视频 | 亚洲国产精品一区二区尤物区 | 在线免费精品视频 | 日韩欧美国产精品 | 免费色av| 亚a在线 | 亚洲最新av在线网址 | 不卡精品视频 | 国产高清在线视频 | 黄色福利网站 | 西西444www| 亚洲国产精久久久久久久 | 四虎成人网| 精品一二三区视频 | 狠狠躁夜夜a产精品视频 | 亚洲精品综合在线观看 | 97成人在线视频 | 久久人人97超碰国产公开结果 | 麻花豆传媒mv在线观看 | 亚洲小视频在线观看 | 国产中文字幕视频在线 | 中文字幕大全 | 美女国内精品自产拍在线播放 | 国产亚洲精品久久久网站好莱 | 久草视频观看 | 一本大道久久精品懂色aⅴ 五月婷社区 | 亚洲精品大片www | 日本护士三级少妇三级999 | av在线播放快速免费阴 | 91亚洲精品久久久蜜桃借种 | 日韩av影视| 精品国产一二三四区 | 午夜性色 | 最新国产精品视频 | 婷婷色婷婷 | 亚洲黄色大片 | 免费观看一级一片 | 亚洲91视频 | 91系列在线 | 国产黄色免费电影 | 婷五月天激情 | 久久avav| 九九三级毛片 | 在线色吧 | 成 人 黄 色 视频播放1 | 精品国产免费av | 天天操天天操天天操天天 | 波多野结衣小视频 | 久草在线免费资源 | 麻花传媒mv免费观看 | 免费成人黄色片 | 日韩一区二区三 | 国产成人精品一区二三区 | 中文字幕在线观看资源 | 2021国产在线 | 亚洲 中文 欧美 日韩vr 在线 | 欧美久久久久久久久 | 日韩视频一区二区三区 | 精品一区二区三区久久久 | 国产一二区在线观看 | 综合黄色网 | 国产资源在线观看 | 六月丁香色婷婷 | 丁香花在线观看视频在线 | 久久一本综合 | 国产精品欧美日韩 | 国产一二三在线视频 | 欧美精品在线观看免费 | 成人资源在线观看 | 91福利区一区二区三区 | 中文字幕亚洲欧美日韩 | 久99久精品视频免费观看 | 欧美日韩精 | 日韩剧情 | 香蕉免费在线 | 在线99热 | 精品视频在线免费观看 | 黄网在线免费观看 | 免费a v观看 | 三级a毛片 | 久久五月精品 | 亚洲一区二区三区精品在线观看 | 久久久黄视频 | 国产精品美女视频 | 国产剧情一区二区在线观看 | 亚洲国产精品一区二区久久,亚洲午夜 | 成人av电影网址 | 五月婷婷综合在线 | 天天综合网在线观看 | 精品在线免费视频 | 精品视频在线视频 | 97人人模人人爽人人喊网 | 亚洲国产中文字幕在线视频综合 | 国产精品第54页 | 亚洲女人av | 99精品福利视频 | 成人久久精品视频 | 在线观看网站黄 | 国产玖玖视频 | 亚洲,国产成人av | 久久久久久久久久电影 | 91精品视频免费看 | 精品一区电影国产 | 在线电影av | 免费韩国av | 九九久久久久久久久激情 | 国产精品99久久免费黑人 | 国产中的精品av小宝探花 | 国产91影院 | 久精品在线观看 | av高清一区二区三区 | 97视频在线 | 免费一级特黄录像 | 99久久影视 | av中文字幕在线看 | 不卡日韩av | 91网址在线观看 | 6080yy午夜一二三区久久 | 婷婷激情五月 | 99夜色| 亚洲黄色成人av | 超碰在线中文字幕 | 日本精品一区二区三区在线观看 | 伊人午夜| 日韩中文字幕在线不卡 | 人人干人人艹 | a级片久久久 | 亚洲综合网站在线观看 | 在线www色 | 六月久久婷婷 | www.成人精品 | 91在线日韩 | 狠狠五月婷婷 | 天天射网站| 在线电影日韩 | 一级黄色大片在线观看 | 福利电影久久 | 欧美日韩a视频 | 人人超碰97 | 国产精品中文字幕av | 国产免费美女 | 国产在线精品观看 | 免费av视屏 | 五月天综合激情 | 国产999精品久久久久久 | 久久免费黄色 | 国产韩国日本高清视频 | www.成人精品 | 亚洲欧美日韩精品一区二区 | 欧美日韩中文字幕综合视频 | 欧美伦理一区 | 精品久久久久久亚洲综合网站 | 中文字幕在线看 | 欧美日韩国语 | 久久综合狠狠综合久久激情 | 中文日韩在线视频 | 在线观看视频黄色 | 国产精品久久久久久久免费大片 | 国产片免费在线观看视频 | 日韩欧美精品在线视频 | 91爱看片| 国产日韩精品一区二区三区 | 麻豆成人在线观看 | 日韩精品一区二区免费视频 | 99精品国产福利在线观看免费 | 一区二区三区免费在线观看视频 | 婷婷丁香在线 | 在线小视频你懂的 | 国产免费一区二区三区网站免费 | 国产看片 色 | av成人动漫在线观看 | 久久精品8| 中文字幕91视频 | 欧美精品在线观看一区 | 人人爽人人澡人人添人人人人 | 蜜臀久久99精品久久久无需会员 | 国产精品日韩欧美一区二区 | 99久热在线精品 | 精品国内 | 99热最新| 午夜久久福利影院 | 在线观看小视频 | 超碰国产在线播放 | 99视频偷窥在线精品国自产拍 | 国产亚洲在线 | 成人羞羞视频在线观看免费 | 婷婷精品国产一区二区三区日韩 | 免费av网站在线 | 黄色片免费在线 | 久久久免费播放 | 日韩区欧美久久久无人区 | 色的网站在线观看 | 搡bbbb搡bbb视频 | 亚洲综合网站在线观看 | 色噜噜在线观看 | 午夜成人免费影院 | 香蕉免费| 国产男女爽爽爽免费视频 | 中文字幕亚洲欧美日韩 | 久久人人97超碰com | 四虎影视成人永久免费观看亚洲欧美 | 久久伦理| 欧美a级在线免费观看 | 亚洲第一区在线观看 | 国产亚洲精品久久久久久移动网络 | 久久久久久激情 | 久久无码av一区二区三区电影网 | 欧美在线你懂的 | 四虎影视成人精品 | 999国内精品永久免费视频 | 免费看国产曰批40分钟 | 日韩久久久久久久久久久久 | 色天天中文 | 精品国产一区二区三区av性色 | 中文字幕精品久久 | 日本黄色大片免费看 | 99在线观看免费视频精品观看 | 精品91视频 | 国产r级在线观看 | 在线成人短视频 | 亚洲精品黄色 | 久久免费片 | 天天操操操操操 | 黄污网站在线观看 | 人人爽人人片 | 精品国产美女在线 | 91精品免费在线观看 | 婷婷中文字幕 | 国内精品视频免费 | www日韩| 青青色影院 | 玖操 | 欧美亚洲久久 | 午夜色大片在线观看 | 操操操夜夜操 | 黄色软件视频网站 | 日b视频在线观看网址 | 99久久毛片 | 色中文字幕在线观看 | 夜夜高潮夜夜爽国产伦精品 | 婷婷六月天综合 | 亚洲激情在线 | 亚洲 欧美 综合 在线 精品 | 亚洲黄色在线观看 | 国产免费视频在线 | www.五月激情.com | 久久观看最新视频 | 狠狠躁夜夜a产精品视频 | 福利精品在线 | 91爱爱中文字幕 | 亚洲成人一二三 | 天天色天天操综合 | 日韩大片在线看 | 人人插人人插 | 国产精品av在线免费观看 | 欧美黑吊大战白妞欧美 | 成人在线观看影院 | 国产精品一区二区久久精品爱涩 | 久久麻豆视频 | 97国产在线 | 国产裸体视频网站 | 欧美韩国日本在线 | 在线看国产视频 | 天天操天天操天天操天天操天天操天天操 | 人人澡人 | 久久99深爱久久99精品 | 国产最顶级的黄色片在线免费观看 | 国产成人久久精品77777综合 | 四虎国产精品永久在线国在线 | 97成人在线观看视频 | 国产在线精品一区二区 | 亚洲国产成人高清精品 | 高清不卡毛片 | 久久精品伊人 | 欧美日韩另类在线观看 | 亚洲va欧洲va国产va不卡 | 狠狠网亚洲精品 | 中文字幕乱码电影 | 91九色蝌蚪视频 | 久草线| 中文字幕黄色av | 麻豆影视网站 | 日本在线视频一区二区三区 | 国产91精品久久久久久 | 欧美精品午夜 | 久青草视频在线观看 | 久久99精品国产99久久 | 韩日在线一区 | 91久久精品日日躁夜夜躁国产 | 亚洲精品视频在 | 国产五十路毛片 | 久久草草影视免费网 | 国产青草视频在线观看 | 国产专区在线播放 | 国产黄在线 | 国产1区在线| 在线视频观看你懂的 | 亚洲精品在线视频 | 特级西西人体444是什么意思 | 人人插人人| 成人毛片网 | 在线一二区| 精品久久久久久久久亚洲 | 精品久久久影院 | 狠狠色狠狠色合久久伊人 | 久久久久一区二区三区四区 | 欧美日韩二区三区 | 久久视频在线免费观看 | 夜色成人av | 97视频在线免费 | 久久久一本精品99久久精品66 | 久久艹中文字幕 | 国产精品国产三级国产aⅴ无密码 | freejavvideo日本免费 | 久久综合亚洲鲁鲁五月久久 | 中文字幕在线观看免费 | 久久久久久久久久久影视 | 亚洲电影一级黄 | 久久99最新地址 | 91色综合| 五月花丁香婷婷 | 国产 日韩 欧美 自拍 | 中文字幕视频网 | 成人一区二区三区中文字幕 | 色91av | 99爱精品视频 | 欧美日韩高清国产 | 国产 日韩 欧美 在线 | 美女网站在线免费观看 | 国产精品一区二区中文字幕 | 在线中文字幕观看 | 欧美激情片在线观看 | 精品国产自在精品国产精野外直播 | 国内精品在线看 | 三级黄色大片在线观看 | 久久国产精品久久w女人spa | 免费男女羞羞的视频网站中文字幕 | 欧美一级视频一区 | 91九色丨porny丨丰满6 | 亚洲精品乱码久久久久v最新版 | 久久久久久久久久久久久久免费看 | 91视频a| 成人毛片在线观看视频 | 四虎影视成人永久免费观看亚洲欧美 | 91免费的视频在线播放 | 在线观看片 | 日韩免费小视频 | 国产网站色 | 免费观看全黄做爰大片国产 | 久久久久久久久久影院 | 亚洲人成网站精品片在线观看 | 欧洲在线免费视频 | 国产91aaa| 天天干,天天干 | av在线a | 国产乱码精品一区二区蜜臀 | 欧美在线视频免费 | 国产剧情在线一区 | 色综合久久中文综合久久牛 | 粉嫩aⅴ一区二区三区 | 久久福利国产 | 成人国产一区 | 久久国产精品小视频 | 国内亚洲精品 | 中文字幕日韩免费视频 | 日本精品免费看 | 97超碰免费在线观看 | 免费看精品久久片 | 免费福利片2019潦草影视午夜 | 亚洲成色777777在线观看影院 | 一 级 黄 色 片免费看的 | 人人澡人人爽 | www黄在线| 久久久精品一区二区 | 天天爽夜夜操 | 久久精品国产亚洲精品2020 | 日韩亚洲国产精品 | 成人资源站 | 91麻豆精品国产自产在线 | 精品一区二区在线看 | 韩国av一区二区三区在线观看 | 91色综合| 中文字幕色播 | 欧美一区二区三区在线视频观看 | 婷婷丁香在线 | 91视频三区| 久久久久久久久久亚洲精品 | 人人澡人人添人人爽一区二区 | 欧美一区二区免费在线观看 | 国产精品成人免费精品自在线观看 | 国产成人精品一区二区在线 | 久久男人视频 | 精品国产一区二区三区久久久久久 | 女人18片| 人人爽人人片 | 国产精品va最新国产精品视频 | 国产一级不卡毛片 | 国产色秀视频 | 久久线视频 | 91豆麻精品91久久久久久 | 在线观看你懂的网址 | 国产二区视频在线 | 婷婷久久综合九色综合 | 亚洲精品系列 | 黄色小网站在线 | 激情五月五月婷婷 | 成人午夜网| 亚洲综合色网站 | 91成人精品观看 | 在线香蕉视频 | 国产成人精品一区二区三区在线观看 | 午夜久久久久久久 | www欧美色| 日韩高清一 | 久久在线精品视频 | www欧美色| 婷婷久操 | 亚洲伦理电影在线 | 肉色欧美久久久久久久免费看 | 久久亚洲二区 | 精品国产视频在线观看 | 国产一区国产二区在线观看 | 欧美精品乱码久久久久 | 日韩精品高清视频 | 在线观看中文 | 久久美女免费视频 | 亚洲一区二区精品视频 | 99久久99久久精品国产片果冰 | 亚洲人成人天堂h久久 | 久久人91精品久久久久久不卡 | 欧美一区二区三区在线看 | 亚洲资源网 | 韩国三级在线一区 | 欧美日韩在线视频一区二区 | a黄色一级| 高清美女视频 | 亚洲三级网站 | 久草在线这里只有精品 | 有码一区二区三区 | 国产护士在线 | 日韩在线视频免费看 | 7777精品伊人久久久大香线蕉 | 国产午夜在线观看视频 | 在线观看av国产 | 久久66热这里只有精品 | 久草在线手机视频 | 精品国产aⅴ一区二区三区 在线直播av | 亚洲国产人午在线一二区 | 免费久久视频 | 欧美日韩高清一区二区 国产亚洲免费看 | 日本中文字幕在线电影 | 97视频在线播放 | 成人精品国产 | 亚欧洲精品视频在线观看 | 极品中文字幕 | 九九热国产视频 | 中文字幕网站视频在线 | 99热这里是精品 | 免费在线观看毛片网站 | 免费在线黄色av | 国产99色| 欧美性粗大hdvideo | 日韩精品不卡在线观看 | 成人免费91| 在线免费中文字幕 | 国产欧美综合在线观看 | 成人97人人超碰人人99 | 黄色大片入口 | 亚洲精品xx | 综合国产在线观看 | 中文永久免费观看 | 免费观看日韩av | 国产在线精品区 | 天天干,天天射,天天操,天天摸 | 国产日产精品一区二区三区四区的观看方式 | 国产精品一区二区无线 | 国产精品99蜜臀久久不卡二区 | 色操插 | 成人资源在线播放 | 久久精品这里都是精品 | 欧美成人999| 亚洲精品在线视频 | 久久人人爽人人人人片 | 男女视频91| 国产成人精品久 | 91av电影在线 | av片中文 | 91福利免费| 日韩精品2区| 国产一级片网站 | 国产精品毛片久久久 | 婷婷中文字幕 | 国产成人亚洲在线观看 | 国产一区二区免费在线观看 | 欧美乱淫视频 | 久久久久久黄 | 国产九九热视频 | 欧美性久久久 | 国产精品久久久毛片 | 久久久www免费电影网 | 久久黄网站 | 久久er99热精品一区二区 | 伊人手机在线 | 日本中文字幕观看 | 亚洲粉嫩av | 精品国产成人在线影院 | 一级国产视频 | 亚洲亚洲精品在线观看 | www..com毛片 | 97在线公开视频 | 亚洲女同ⅹxx女同tv | 欧美日韩在线网站 | 免费a级黄色毛片 | 久久精品2 | 亚洲精品欧美成人 | 成人久久18免费网站麻豆 | 国产成人精品一区二区三区福利 | 欧美午夜久久久 | 亚洲午夜精品久久久久久久久久久久 | 草莓视频在线观看免费观看 | 亚洲精品一区二区网址 | 丁香婷婷基地 | .国产精品成人自产拍在线观看6 | 美女视频a美女大全免费下载蜜臀 | 日本久久99| 午夜骚影 | 色综合久久中文字幕综合网 | 97在线精品视频 | 欧美日韩高清在线观看 | 91最新视频在线观看 |