久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

【ARM-Linux开发】U-Boot启动过程--详细版的完全分析

發布時間:2024/7/19 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【ARM-Linux开发】U-Boot启动过程--详细版的完全分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

-------------------------------------------------------------------------------------------------------------------------------------------

?我們知道,bootloader是系統上電后最初加載運行的代碼。它提供了處理器上電復位后最開始需要執行的初始化代碼。

??? 在PC機上引導程序一般由BIOS開始執行,然后讀取硬盤中位于MBR(Main Boot Record,主引導記錄)中的Bootloader(例如LILO或GRUB),并進一步引導操作系統的啟動。

??? 然而在嵌入式系統中通常沒有像BIOS那樣的固件程序,因此整個系統的加載啟動就完全由bootloader來完成。它主要的功能是加載與引導內核映像?

?

一個嵌入式的存儲設備通過通常包括四個分區:

第一分區:存放的當然是u-boot

第二個分區:存放著u-boot要傳給系統內核的參數

第三個分區:是系統內核(kernel)

第四個分區:則是根文件系統

如下圖所示:

-------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------

?

u-boot是一種普遍用于嵌入式系統中的Bootloader。

Bootloader介紹

Bootloader是進行嵌入式開發必然會接觸的一個概念,它是嵌入式學院<嵌入式工程師職業培訓班>二期課程中嵌入式linux系統開發方面的重要內容。本篇文章主要講解Bootloader的基本概念以及內部原理,這部分內容的掌握將對嵌入式linux系統開發的學習非常有幫助!

Bootloader的定義:Bootloader是在操作系統運行之前執行的一小段程序,通過這一小段程序,我們可以初始化硬件設備、建立內存空間的映射表,從而建立適當的系統軟硬件環境,為最終調用操作系統內核做好準備。意思就是說如果我們要想讓一個操作系統在我們的板子上運轉起來,我們就必須首先對我們的板子進行一些基本配置和初始化,然后才可以將操作系統引導進來運行。具體在Bootloader中完成了哪些操作我們會在后面分析到,這里我們先來回憶一下PC的體系結構:PC機中的引導加載程序是由BIOS和位于硬盤MBR中的OS Boot Loader(比如LILO和GRUB等)一起組成的,BIOS在完成硬件檢測和資源分配后,將硬盤MBR中的Boot Loader讀到系統的RAM中,然后將控制權交給OS Boot Loader。Boot Loader的主要運行任務就是將內核映象從硬盤上讀到RAM中,然后跳轉到內核的入口點去運行,即開始啟動操作系統。在嵌入式系統中,通常并沒有像BIOS那樣的固件程序(注:有的嵌入式cpu也會內嵌一段短小的啟動程序),因此整個系統的加載啟動任務就完全由Boot Loader來完成。比如在一個基于ARM7TDMI core的嵌入式系統中,系統在上電或復位時通常都從地址0x00000000處開始執行,而在這個地址處安排的通常就是系統的Boot Loader程序。(先想一下,通用PC和嵌入式系統為何會在此處存在如此的差異呢?)

Bootloader是基于特定硬件平臺來實現的,因此幾乎不可能為所有的嵌入式系統建立一個通用的Bootloader,不同的處理器架構都有不同的Bootloader,Bootloader不但依賴于cpu的體系結構,還依賴于嵌入式系統板級設備的配置。對于2塊不同的板子而言,即使他們使用的是相同的處理器,要想讓運行在一塊板子上的Bootloader程序也能運行在另一塊板子上,一般也需要修改Bootloader的源程序。

Bootloader的啟動方式

Bootloader的啟動方式主要有網絡啟動方式、磁盤啟動方式和Flash啟動方式。

1、網絡啟動方式

?
圖1??Bootloader網絡啟動方式示意圖

如圖1所示,里面主機和目標板,他們中間通過網絡來連接,首先目標板的DHCP/BIOS通過BOOTP服務來為Bootloader分配IP地址,配置網絡參數,這樣才能支持網絡傳輸功能。我們使用的u-boot可以直接設置網絡參數,因此這里就不用使用DHCP的方式動態分配IP了。接下來目標板的Bootloader通過TFTP服務將內核映像下載到目標板上,然后通過網絡文件系統來建立主機與目標板之間的文件通信過程,之后的系統更新通常也是使用Boot Loader的這種工作模式。工作于這種模式下的Boot Loader通常都會向它的終端用戶提供一個簡單的命令行接口。

2、磁盤啟動方式

這種方式主要是用在臺式機和服務器上的,這些計算機都使用BIOS引導,并且使用磁盤作為存儲介質,這里面兩個重要的用來啟動linux的有LILO和GRUB,這里就不再具體說明了。

3、Flash啟動方式

這是我們最常用的方式。Flash有NOR Flash和NAND Flash兩種。NOR Flash可以支持隨機訪問,所以代碼可以直接在Flash上執行,Bootloader一般是存儲在Flash芯片上的。另外Flash上還存儲著參數、內核映像和文件系統。這種啟動方式與網絡啟動方式之間的不同之處就在于,在網絡啟動方式中,內核映像和文件系統首先是放在主機上的,然后經過網絡傳輸下載進目標板的,而這種啟動方式中內核映像和文件系統則直接是放在Flash中的,這兩點在我們u-boot的使用過程中都用到了。

U-boot的定義

U-boot,全稱Universal Boot Loader,是由DENX小組的開發的遵循GPL條款的開放源碼項目,它的主要功能是完成硬件設備初始化、操作系統代碼搬運,并提供一個控制臺及一個指令集在操作系統運行前操控硬件設備。U-boot之所以這么通用,原因是他具有很多特點:開放源代碼、支持多種嵌入式操作系統內核、支持多種處理器系列、較高的穩定性、高度靈活的功能設置、豐富的設備驅動源碼以及較為豐富的開發調試文檔與強大的網絡技術支持。另外u-boot對操作系統和產品研發提供了靈活豐富的支持,主要表現在:可以引導壓縮或非壓縮系統內核,可以靈活設置/傳遞多個關鍵參數給操作系統,適合系統在不同開發階段的調試要求與產品發布,支持多種文件系統,支持多種目標板環境參數存儲介質,采用CRC32校驗,可校驗內核及鏡像文件是否完好,提供多種控制臺接口,使用戶可以在不需要ICE的情況下通過串口/以太網/USB等接口下載數據并燒錄到存儲設備中去(這個功能在實際的產品中是很實用的,尤其是在軟件現場升級的時候),以及提供豐富的設備驅動等。

u-boot源代碼的目錄結構

1、board中存放于開發板相關的配置文件,每一個開發板都以子文件夾的形式出現。

2、Commom文件夾實現u-boot行下支持的命令,每一個命令對應一個文件。

3、cpu中存放特定cpu架構相關的目錄,每一款cpu架構都對應了一個子目錄。

4、Doc是文檔目錄,有u-boot非常完善的文檔。

5、Drivers中是u-boot支持的各種設備的驅動程序。

6、Fs是支持的文件系統,其中最常用的是JFFS2文件系統。

7、Include文件夾是u-boot使用的頭文件,還有各種硬件平臺支持的匯編文件,系統配置文件和文件系統支持的文件。

8、Net是與網絡協議相關的代碼,bootp協議、TFTP協議、NFS文件系統得實現。

9、Tooles是生成U-boot的工具。

對u-boot的目錄有了一些了解后,分析啟動代碼的過程就方便多了,其中比較重要的目錄就是/board、/cpu、/drivers和/include目錄,如果想實現u-boot在一個平臺上的移植,就要對這些目錄進行深入的分析。

-------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------

???????????????????????????????????????????????????????????????????????????????????????什么是《編譯地址》?什么是《運行地址》?

(一)編譯地址:?32位的處理器,它的每一條指令是4個字節,以4個字節存儲順序,進行順序執行,CPU是順序執行的,只要沒發生什么跳轉,它會順序進行執行行, 編譯器會對每一條指令分配一個編譯地址,這是編譯器分配的,在編譯過程中分配的地址,我們稱之為編譯地址。
(二)運行地址:是指程序指令真正運行的地址,是由用戶指定的,用戶將運行地址燒錄到哪里哪里就是運行的地址

???? ?比如有一個指令的編譯地址是0x5,實際運行的地址是0x200,如果用戶將指令燒到0x200上,那么這條指令的運行地址就是0x200,

??????當編譯地址和運行地址不同的時候會出現什么結果?結果是不能跳轉,編譯后會產生跳轉地址,如果實際地址和編譯后產生的地址不相等,那么就不能跳轉。

???? C語言編譯地址:都希望把編譯地址和實際運行地址放在一起的,但是匯編代碼因為不需要做C語言到匯編的轉換,可以認為的去寫地址,所以直接寫的就是他的運行地址這就是為什么任何bootloader剛開始會有一段匯編代碼,因為起始代碼編譯地址和實際地址不相等,這段代碼和匯編無關,跳轉用的運行地址。????????????????????????????????????????????????????

????????????????????????????????????????????????????????????編譯地址和運行地址如何來算呢?

???1.??? 假如有兩個編譯地址a=0x10,b=0x7,b的運行地址是0x300,那么a的運行地址就是b的運行地址加上兩者編譯地址的差值,a-b=0x10-0x7=0x3,

?????? a的運行地址就是0x300+0x3=0x303。
?? ?2.?? 假設uboot上兩條指令的編譯地址為a=0x33000007和b=0x33000001,這兩條指令都落在bank6上,現在要計算出他們對應的運行地址,要找出運行地址的始地址,這個是由用戶燒錄進去的,假設運行地址的首地址是0x0,則a的運行地址為0x7,b為0x1,就是這樣算出來的。

???????????????????????????????????????????? 為什么要分配編譯地址?這樣做有什么好處,有什么作用?
??????? 比如在函數a中定義了函數b,當執行到函數b時要進行指令跳轉,要跳轉到b函數所對應的起始地址上去,編譯時,編譯器給每條指令都分配了編譯地址,如果編譯器已經給分配了地址就可以直接進行跳轉,查找b函數跳轉指令所對應的表,進行直接跳轉,因為有個編譯地址和指令對應的一個表,如果沒有分配,編譯器就查找不到這個跳轉地址,要進行計算,非常麻煩。

?????????????????????????????????????????????????????????????????????? 什么是《相對地址》?
??????? 以NOR Flash為例,NOR Falsh是映射到bank0上面,SDRAM是映射到bank6上面,uboot和內核最終是在SDRAM上面運行,最開始我們是從Nor Flash的零地址開始往后燒錄,uboot中至少有一段代碼編譯地址和運行地址是不一樣的,編譯uboot或內核時,都會將譯地址放入到SDRAM中,他們最終都會在SDRAM中執行,剛開始uboot在Nor Flash中運行,運行地址是一個低端地址,是bank0中的一個地址,但編譯地址是bank6中的地址,這樣就會導致絕對跳轉指令執行的失敗所以就引出了相對地址的概念

????????????????????????????????????????????????????????????????????? 那么什么是相對地址呢?

???? 至少在bank0中uboot這段代碼要知道不能用b+編譯地址這樣的方法去跳轉指令,因為這段代碼的編譯地址和運行地址不一樣,那如何去做呢?

??? 要去計算這個指令運行的真實地址,計算出來后再做跳轉,應該是b+運行地址,不能出現b+編譯地址,而是b+運行地址,而運行地址是算出來的。

?? _TEXT_BASE:
? .word TEXT_BASE //0x33F80000,在board/config.mk中
這段話表示,用戶告訴編譯器編譯地址的起始地址
-------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------?

?????? U-Boot工作過程

???

???? ?大多數 Boot Loader 都包含兩種不同的操作模式:"啟動加載"模式和"下載"模式,這種區別僅對于開發人員才有意義。

???? 但從最終用戶的角度看,Boot Loader 的作用就是:用來加載操作系統,而并不存在所謂的啟動加載模式與下載工作模式的區別。
???? (一)啟動加載(Boot loading)模式:這種模式也稱為"自主"(Autonomous)模式。

???? 也即 Boot Loader 從目標機上的某個固態存儲設備上將操作系統加載到 RAM 中運行,整個過程并沒有用戶的介入。

???? 這種模式是 Boot Loader 的正常工作模式,因此在嵌入式產品發布的時侯,Boot Loader 顯然必須工作在這種模式下。


(二)下載(Downloading)模式:在這種模式下,目標機上的 Boot Loader 將通過串口連接或網絡連接等通信手段從主機(Host)下載文件,比如:下載內核映像和根文件系統映像等。從主機下載的文件通常首先被 Boot Loader保存到目標機的RAM?中,然后再被 BootLoader到目標機上的FLASH類固態存儲設備中。Boot Loader 的這種模式通常在第一次安裝內核與根文件系統時被使用;此外,以后的系統更新也會使用 Boot Loader 的這種工作模式。工作于這種模式下的 Boot Loader 通常都會向它的終端用戶提供一個簡單的命令行接口。這種工作模式通常在第一次安裝內核與跟文件系統時使用。或者在系統更新時使用。進行嵌入式系統調試時一般也讓bootloader工作在這一模式下。
????????? U-Boot 這樣功能強大的 Boot Loader 同時支持這兩種工作模式,而且允許用戶在這兩種工作模式之間進行切換。

???????? 大多數 bootloader 都分為階段 1(stage1)和階段 2(stage2)兩大部分,u-boot 也不例外。依賴于 CPU 體系結構的代碼(如 CPU 初始化代碼等)通常都放在階段 1 中且通常用匯編語言實現,而階段 2 則通常用 C 語言來實現,這樣可以實現復雜的功能,而且有更好的可讀性和移植性。
-------------------------------------------------------------------------------------------------------------------------------------------

第一、大概總結性得的分析

?????? 系統啟動的入口點。既然我們現在要分析u-boot的啟動過程,就必須先找到u-boot最先實現的是哪些代碼,最先完成的是哪些任務。

?????? 另一方面一個可執行的image必須有一個入口點,并且只能有一個全局入口點,所以要通知編譯器這個入口在哪里。由此我們可以找到程序的入口點是在/board/lpc2210/u-boot.lds中指定的,其中ENTRY(_start)說明程序從_start開始運行,而他指向的是cpu/arm7tdmi/start.o文件。

因為我們用的是ARM7TDMI的cpu架構,在復位后從地址0x00000000取它的第一條指令,所以我們將Flash映射到這個地址上,

這樣在系統加電后,cpu將首先執行u-boot程序。u-boot的啟動過程是多階段實現的,分了兩個階段。

依賴于cpu體系結構的代碼(如設備初始化代碼等)通常都放在stage1中,而且通常都是用匯編語言來實現,以達到短小精悍的目的。

而stage2則通常是用C語言來實現的,這樣可以實現復雜的功能,而且代碼具有更好的可讀性和可移植性。

下面我們先詳細分析下stage1中的代碼,如圖2所示:

?
圖2??Start.s程序流程

??????????代碼真正開始是在_start,設置異常向量表,這樣在cpu發生異常時跳轉到/cpu/arm7tdmi/interrupts中去執行相應中斷代碼

?????????在interrupts文件中大部分的異常代碼都沒有實現具體的功能,只是打印一些異常消息,其中關鍵的是reset中斷代碼,跳到reset入口地址

????????? reset復位入口之前有一些段的聲明

??????????1.在reset中,首先是將cpu設置為svc32模式下,并屏蔽所有irq和fiq。

??????????2.在u-boot中除了定時器使用了中斷外其他的基本上都不需要使用中斷,比如串口通信和網絡等通信等,在u-boot中只要完成一些簡單的通信就可以了,所以在這里屏蔽掉了所有的中斷響應。

?????????3.初始化外部總線。這部分首先設置了I/O口功能,包括串口、網絡接口等的設置,其他I/O口都設置為GPIO。然后設置BCFG0~BCFG3,即外部總線控制器。這里bank0對應Flash,設置為16位寬度,總線速度設為最慢,以實現穩定的操作;Bank1對應DRAM,設置和Flash相同;Bank2對應RTL8019。

???????? 4.接下來是cpu關鍵設置,包括系統重映射(告訴處理器在系統發生中斷的時候到外部存儲器中去讀取中斷向量表)和系統頻率。

???????? 5.lowlevel_init,設定RAM的時序,并將中斷控制器清零。這些部分和特定的平臺有關,但大致的流程都是一樣的。

????????下面就是代碼的搬移階段了。為了獲得更快的執行速度

??????? 通常把stage2加載到RAM空間中來執行,因此必須為加載Boot Loader的stage2準備好一段可用的RAM空間范圍。空間大小最好是memory page大小(通常是4KB)的倍數

??????? 一般而言,1M的RAM空間已經足夠了。

????????flash中存儲的u-boot可執行文件中,代碼段、數據段以及BSS段都是首尾相連存儲的,

??????? 所以在計算搬移大小的時候就是利用了用BSS段的首地址減去代碼的首地址,這樣算出來的就是實際使用的空間。

?????? ?程序用一個循環將代碼搬移到0x81180000,即RAM底端1M空間用來存儲代碼。

?????? ?然后程序繼續將中斷向量表搬到RAM的頂端。由于stage2通常是C語言執行代碼,所以還要建立堆棧去。

?????? 在堆棧區之前還要將malloc分配的空間以及全局數據所需的空間空下來,他們的大小是由宏定義給出的,可以在相應位置修改。

基本內存分布圖:


圖3??搬移后內存分布情況圖

???? 下來是u-boot啟動的第二個階段,是用c代碼寫的,

???? 這部分是一些相對變化不大的部分,我們針對不同的板子改變它調用的一些初始化函數,并且通過設置一些宏定義來改變初始化的流程

???? 所以這些代碼在移植的過程中并不需要修改,也是錯誤相對較少出現的文件。

???? 在文件的開始先是定義了一個函數指針數組,通過這個數組,程序通過一個循環來按順序進行常規的初始化,并在其后通過一些宏定義來初始化一些特定的設備。

???? 在最后程序進入一個循環,main_loop這個循環接收用戶輸入的命令,以設置參數或者進行啟動引導

本篇文章將分析重點放在了前面的start.s上,是因為這部分無論在移植還是在調試過程中都是最容易出問題的地方,要解決問題就需要程序員對代碼進行修改,所以在這里簡單介紹了一下start.s的基本流程,希望能對大家有所幫助

-------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------------------------------------

第二、代碼分析

?

2.2 階段 1 介紹
u-boot 的 stage1 代碼通常放在 start.s 文件中,它用匯編語言寫成,其主要代碼部分如下:
2.2.1 定義入口
由于一個可執行的 Image 必須有一個入口點,并且只能有一個全局入口,通常這個入口放在 ROM(Flash)的 0x0
地址,因此,必須通知編譯器以使其知道這個入口,該工作可通過修改連接器腳本來完成。
1. board/crane2410/u-boot.lds:? ENTRY(_start)?? ==> cpu/arm920t/start.S: .globl _start
2. uboot 代碼區(TEXT_BASE = 0x33F80000)定義在 board/crane2410/config.mk

U-Boot啟動內核的過程可以分為兩個階段,兩個階段的功能如下:

?????? (1)第一階段的功能

?? 硬件設備初始化

?? 加載U-Boot第二階段代碼到RAM空間

?? 設置好棧

?? 跳轉到第二階段代碼入口

?????? (2)第二階段的功能

?? 初始化本階段使用的硬件設備

?? 檢測系統內存映射

?? 將內核從Flash讀取到RAM中

?? 為內核設置啟動參數

?? 調用內核

1.1.1???????????? U-Boot啟動第一階段代碼分析

?????? 第一階段對應的文件是cpu/arm920t/start.S和board/samsung/mini2440/lowlevel_init.S。

?????? U-Boot啟動第一階段流程如下:

?

詳細分析

圖 2.1 U-Boot啟動第一階段流程

?

?????根據cpu/arm920t/u-boot.lds中指定的連接方式

???? 看一下uboot.lds文件,在board/smdk2410目錄下面,uboot.lds是告訴編譯器這些段改怎么劃分,GUN編譯過的段,最基本的三個段是RO,RW,ZI,RO表示只讀,對應于具體的指代碼段,RW是數據段,ZI是歸零段,就是全局變量的那段。Uboot代碼這么多,如何保證start.s會第一個執行,編譯在最開始呢?就是通過uboot.lds鏈接文件進行

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000; //起始地址

. = ALIGN(4); //4字節對齊
.text : //test指代碼段,上面3行標識是不占用任何空間的
{
cpu/arm920t/start.o (.text) //這里把start.o放在第一位就表示把start.s編
譯時放到最開始,這就是為什么把uboot燒到起始地址上它肯定運行的是start.s
*(.text)
}

. = ALIGN(4); //前面的 “.” 代表當前值,是計算一個當前的值,是計算上
面占用的整個空間,再加一個單元就表示它現在的位置
.rodata : { *(.rodata) }

. = ALIGN(4);
.data : { *(.data) }

. = ALIGN(4);
.got : { *(.got) }

. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;

. = ALIGN(4);
__bss_start = .; //bss表示歸零段
.bss : { *(.bss) }
_end = .;
}
?????? 第一個鏈接的是cpu/arm920t/start.o,因此u-boot.bin的入口代碼在cpu/arm920t/start.o中,其源代碼在cpu/arm920t/start.S中。下面我們來分析cpu/arm920t/start.S的執行。

1.????? 硬件設備初始化

(1)設置異常向量

????????? 下面代碼是系統啟動后U-boot上電后運行的第一段代碼,它是什么意思?

????????? u-boot對應的第一階段代碼放在cpu/arm920t/start.S文件中,入口代碼如下:.

globl _startglobal??????????????????????????????????? /*聲明一個符號可被其它文件引用,相當于聲明了一個全局變量,.globl與.global相同*/

_start:??? b???? start_code??????????????????? /* 復位 */b是不帶返回的跳轉(bl是帶返回的跳轉),意思是無條件直接跳轉到start_code標號出執行程序

?????? ldr?? pc, _undefined_instruction????? /*?未定義指令向量 l---dr相當于mov操作*/

?????? ldr?? pc, _software_interrupt??????????? /* ?軟件中斷向量 */

?????? ldr?? pc, _prefetch_abort????????????????? /*? 預取指令異常向量 */

?????? ldr?? pc, _data_abort??????????????????????? /* ?數據操作異常向量 */

?????? ldr?? pc, _not_used?????????????????????????? /*? 未使用?? */

?????? ldr?? pc, _irq???????????????????????????????????? /*? irq中斷向量? */

?????? ldr?? pc, _fiq???????????????????????????????????? /*? fiq中斷向量? */

/*? 中斷向量表入口地址 */

_undefined_instruction:??? .word undefined_instruction? /*就是在當前地址,即_undefined_instruction 處存放 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?

word偽操作用于分配一段字內存單元(分配的單元都是字對齊的),并用偽操作中的expr初始化

?????? .balignl 16,0xdeadbeef

?????? 他們是系統定義的異常,一上電程序跳轉到start_code異常處執行相應的匯編指令,下面定義出的都是不同的異常,比如軟件發生軟中斷時,CPU就會去執行軟中斷的指令,這些異常中斷在CUP中地址是從0開始,每個異常占4個字節

???????ldr pc, _undefined_instruction表示把_undefined_instruction存放的數值存放到pc指針上

????????????????? ?_undefined_instruction: .word undefined_instruction表示未定義的這個異常是由.word來定義的,它表示定義一個字,一個32位的數

.? word后面的數:表示把該標識的編譯地址寫入當前地址,標識是不占用任何指令的。把標識存放的數值copy到指針pc上面,那么標識上存放的值是什么?

是由.word undefined_instruction來指定的,pc就代表你運行代碼的地址,她就實現了CPU要做一次跳轉時的工作

???????以上代碼設置了ARM異常向量表,各個異常向量介紹如下:

表 2.1 ARM異常向量表

???????地址?

? 異常?

??? 進入模式

描述

0x00000000?

復位

?? 管理模式

??? 復位電平有效時,產生復位異常,程序跳轉到復位處理程序處執行

0x00000004?

未定義指令

???未定義模式

?? 遇到不能處理的指令時,產生未定義指令異常

0x00000008

軟件中斷

?? 管理模式

??? 執行SWI指令產生,用于用戶模式下的程序調用特權操作指令

0x0000000c

預存指令

?? 中止模式

?? 處理器預取指令的地址不存在,或該地址不允許當前指令訪問,產生指令預取中止異常

0x00000010

數據操作

?? 中止模式

?? 處理器數據訪問指令的地址不存在,或該地址不允許當前指令訪問時,產生數據中止異常

0x00000014

未使用

???未使用

?? 未使用

0x00000018

IRQ

?? IRQ

??? 外部中斷請求有效,且CPSR中的I位為0時,產生IRQ異常

0x0000001c

FIQ

?? FIQ

??? 快速中斷請求引腳有效,且CPSR中的F位為0時,產生FIQ異常

??????

????? 在cpu/arm920t/start.S中還有這些異常對應的異常處理程序。當一個異常產生時,CPU根據異常號在異常向量表中找到對應的異常向量,然后執行異常向量處的跳轉指令,CPU就跳轉到對應的異常處理程序執行。

?????? 其中復位異常向量的指令“b start_code”決定了U-Boot啟動后將自動跳轉到標號“start_code”處執行。

(2)CPU進入SVC模式

start_code:

?????? /*

?????? ?* set the cpu to SVC32 mode

?????? ?*/

?????? mrs r0, cpsr

?????? bic? r0, r0, #0x1f??????? /*工作模式位清零 */

?????? orr?? r0, r0, #0xd3????????????? /*工作模式位設置為“10011”(管理模式),并將中斷禁止位和快中斷禁止位置1 */

?????? msr cpsr, r0

?????? 以上代碼將CPU的工作模式位設置為管理模式,即設置相應的CPSR程序狀態字,并將中斷禁止位和快中斷禁止位置一,從而屏蔽了IRQ和FIQ中斷。

?????? 操作系統先注冊一個總的中斷,然后去查是由哪個中斷源產生的中斷,再去查用戶注冊的中斷表,查出來后就去執行用戶定義的用戶中斷處理函數。

(3)設置控制寄存器地址

# if defined(CONFIG_S3C2400)??????? /*關閉看門狗*/

#? define pWTCON 0x15300000?????? /*;看門狗寄存器*/

#? define INTMSK? 0x14400008??????? /*;中斷屏蔽寄存器*/

#? define CLKDIVN????? 0x14800014 /*;時鐘分頻寄存器*/

#else????? /* s3c2410與s3c2440下面4個寄存器地址相同 */

#? define pWTCON 0x53000000?????????????? /* WATCHDOG控制寄存器地址 */

#? define INTMSK? 0x4A000008???????????????????? /* INTMSK寄存器地址? */

#? define INTSUBMSK 0x4A00001C????? /* INTSUBMSK寄存器地址 次級中斷屏蔽寄存器*/

#? define CLKDIVN????? 0x4C000014?????? ? ????????? /* CLKDIVN寄存器地址?;時鐘分頻寄存器*/

# endif

?????? 對與s3c2440開發板,以上代碼完成了WATCHDOG,INTMSK,INTSUBMSK,CLKDIVN四個寄存器的地址的設置。各個寄存器地址參見參考文獻[4] 。

(4)關閉看門狗

?????? ldr?? r0, =pWTCON?? /*將pwtcon寄存器地址賦給R0*/

?????? mov?????? r1, #0x0????? /*r1的內容為0*/

?????? str?? r1, [r0]?????????????? ?/* 看門狗控制器的最低位為0時,看門狗不輸出復位信號 */

?????? 以上代碼向看門狗控制寄存器寫入0,關閉看門狗。否則在U-Boot啟動過程中,CPU將不斷重啟

為什么要關看門狗?

??????? ?就是防止,不同得兩個以上得CPU,進行喂狗的時間間隔問題:說白了,就是你運行的代碼如果超出喂狗時間,而你不關狗,就會導致,你代碼還沒運行完又得去喂狗,就這樣反復得重啟CPU,那你代碼永遠也運行不完,所以,得先關看門狗得原因,就是這樣。

關狗---詳細的原因:

????? 關閉看門狗,關閉中斷,所謂的喂狗是每隔一段時間給某個寄存器置位而已,在實際中會專門啟動一個線程或進程會專門喂狗,當上層軟件出現故障時就會停止喂狗

????? 停止喂狗之后,cpu會自動復位,一般都在外部專門有一個看門狗,做一個外部的電路,不在cpu內部使用看門狗,cpu內部的看門狗是復位的cpu

?????? 當開發板很復雜時,有好幾個cpu時,就不能完全讓板子復位,但我們通常都讓整個板子復位。看門狗每隔短時間就會喂狗,問題是在兩次喂狗之間的時間間隔內,運行的代碼的時間是否夠用,兩次喂狗之間的代碼是否在兩次喂狗的時間延遲之內,如果在延遲之外的話,代碼還沒改完就又進行喂狗,代碼永遠也改不完

(5)屏蔽中斷

?????? /*

?????? ?* mask all IRQs by setting all bits in the INTMR - default

?????? ?*/

?????? mov?????? r1, #0xffffffff???? /*屏蔽所有中斷,?某位被置1則對應的中斷被屏蔽 */?/*寄存器中的值*/

?????? ldr?? r0, =INTMSK?????? /*將管理中斷的寄存器地址賦給ro*/

?????? str?? r1, [r0]??????????????????/*將全r1的值賦給ro地址中的內容*/

?????? INTMSK是主中斷屏蔽寄存器,每一位對應SRCPND(中斷源引腳寄存器)中的一位,表明SRCPND相應位代表的中斷請求是否被CPU所處理。

???????? 根據參考文獻4,INTMSK寄存器是一個32位的寄存器,每位對應一個中斷,向其中寫入0xffffffff就將INTMSK寄存器全部位置一,從而屏蔽對應的中斷。

# if defined(CONFIG_S3C2440)

??? ????? ldr? r1, =0x7fff??????????????????

? ?????? ldr? r0, =INTSUBMSK??

???????? str? r1, [r0]????????????

?# endif

?????? INTSUBMSK每一位對應SUBSRCPND中的一位,表明SUBSRCPND相應位代表的中斷請求是否被CPU所處理。

?????? 根據參考文獻4,INTSUBMSK寄存器是一個32位的寄存器,但是只使用了低15位。向其中寫入0x7fff就是將INTSUBMSK寄存器全部有效位(低15位)置一,從而屏蔽對應的中斷。

屏蔽所有中斷,為什么要關中斷?

中斷處理中ldr pc是將代碼的編譯地址放在了指針上,而這段時間還沒有搬移代碼,所以編譯地址上面沒有這個代碼,如果進行跳轉就會跳轉到空指針上面

(6)設置MPLLCON,UPLLCON, CLKDIVN

# if defined(CONFIG_S3C2440)?

#define MPLLCON?? 0x4C000004

#define UPLLCON?? 0x4C000008??

??? ????? ldr? r0, =CLKDIVN???;設置時鐘

??? ????? mov? r1, #5

??? ????? str? r1, [r0]

?

??? ????? ldr? r0, =MPLLCON

??? ????? ldr? r1, =0x7F021?

??? ????? str? r1, [r0]

?

?? ?ldr? r0, =UPLLCON?

??? ????? ldr? r1, =0x38022

??? ????? str? r1, [r0]

# else

?????? /* FCLK:HCLK:PCLK = 1:2:4 */

?????? /* default FCLK is 120 MHz ! */

?????? ldr?? r0, =CLKDIVN

?????? mov?????? r1, #3

?????? str?? r1, [r0]

#endif

?????? CPU上電幾毫秒后,晶振輸出穩定,FCLK=Fin(晶振頻率),CPU開始執行指令。但實際上,FCLK可以高于Fin,為了提高系統時鐘,需要用軟件來啟用PLL。這就需要設置CLKDIVN,MPLLCON,UPLLCON這3個寄存器。

???????CLKDIVN寄存器用于設置FCLK,HCLK,PCLK三者間的比例,可以根據表2.2來設置。

表 2.2 S3C2440 的CLKDIVN寄存器格式

??????????????????????? ?? CLKDIVN????????????? ??????????

?????????????? ? 位???????????????

? 說明

????????????????????????? ?初始值????????????????????

HDIVN

[2:1]

????? 00 : HCLK = FCLK/1.

??????01 : HCLK = FCLK/2.

????? 10 : HCLK = FCLK/4 (當 CAMDIVN[9] = 0 時)

????? HCLK= FCLK/8? (當 CAMDIVN[9] = 1 時)

????? 11 : HCLK = FCLK/3 (當 CAMDIVN[8] = 0 時)

????? HCLK = FCLK/6 (當 CAMDIVN[8] = 1時)

00

PDIVN

[0]

0: PCLK = HCLK/1?? 1: PCLK = HCLK/2

0

?

?????? 設置CLKDIVN為5,就將HDIVN設置為二進制的10,由于CAMDIVN[9]沒有被改變過,取默認值0,因此HCLK = FCLK/4。PDIVN被設置為1,因此PCLK= HCLK/2。因此分頻比FCLK:HCLK:PCLK = 1:4:8 。

?????? MPLLCON寄存器用于設置FCLK與Fin的倍數。MPLLCON的位[19:12]稱為MDIV,位[9:4]稱為PDIV,位[1:0]稱為SDIV。

?????? 對于S3C2440,FCLK與Fin的關系如下面公式:

?????? MPLL(FCLK) = (2×m×Fin)/(p× )

?????? 其中: m=MDIC+8,p=PDIV+2,s=SDIV

?????? MPLLCON與UPLLCON的值可以根據參考文獻4中“PLL VALUE SELECTION TABLE”設置。該表部分摘錄如下:

表 2.3 推薦PLL值

?????? 輸入頻率???????

??????????????????????? 輸出頻率?????????????????????????

?????????????????????? MDIV???????????????????

???????????????????????? PDIV?????????????????????

??????????????????????SDIV?????????????????????

12.0000MHz

48.00 MHz

56(0x38)

2

2

12.0000MHz

405.00 MHz

127(0x7f)

2

1

?????? 當mini2440系統主頻設置為405MHZ,USB時鐘頻率設置為48MHZ時,系統可以穩定運行,因此設置MPLLCON與UPLLCON為:

?????? MPLLCON=(0x7f<<12) | (0x02<<4) | (0x01) = 0x7f021

?????? UPLLCON=(0x38<<12) | (0x02<<4) | (0x02) = 0x38022

默認頻率為????? FCLK:HCLK:PCLK = 1:2:4,默認 FCLK 的值為 120 MHz,該值為 S3C2410 手冊的推薦值。

設置時鐘分頻,為什么要設置時鐘?

起始可以不設,系統能不能跑起來和頻率沒有任何關系,頻率的設置是要讓外圍的設備能承受所設置的頻率,如果頻率過高則會導致cpu操作外圍設備失敗

說白了:設置頻率,就為了CPU能去操作外圍設備

(7)關閉MMU,cache? ------(也就是做bank的設置)

?????? 接著往下看:

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

?????? bl??? cpu_init_crit??/*?;跳轉并把轉移后面緊接的一條指令地址保存到鏈接寄存器LR(R14)中,以此來完成子程序的調用*/

#endif

?????? cpu_init_crit這段代碼在U-Boot正常啟動時才需要執行,若將U-Boot從RAM中啟動則應該注釋掉這段代碼

?????? 下面分析一下cpu_init_crit到底做了什么:

320? #ifndef CONFIG_SKIP_LOWLEVEL_INIT

321? cpu_init_crit:

322? ??? /*

323? ??? ?* 使數據cache與指令cache無效 */

324? ??? ?*/?

325? ??? mov?????? r0, #0

326? ??? mcr p15, 0, r0, c7, c7, 0??? /* 向c7寫入0將使ICache與DCache無效*/

327? ??? mcr p15, 0, r0, c8, c7, 0??? /* 向c8寫入0將使TLB失效 ,協處理器*/??

328?

329? ??? /*

330? ??? ?* disable MMU stuff and caches

331? ??? ?*/

332? ??? mrc p15, 0, r0, c1, c0, 0??? /*? 讀出控制寄存器到r0中? */

333? ??? bic? r0, r0, #0x00002300?? @ clear bits 13, 9:8 (--V- --RS)

334? ??? bic? r0, r0, #0x00000087?? @ clear bits 7, 2:0 (B--- -CAM)

335? ??? orr?? r0, r0, #0x00000002?? @ set bit 2 (A) Align

336? ??? orr?? r0, r0, #0x00001000?? @ set bit 12 (I) I-Cache

337? ??? mcr p15, 0, r0, c1, c0, 0??? /*? 保存r0到控制寄存器? */

338?

339? ??? /*

340? ??? ?* before relocating, we have to setup RAM timing

341? ??? ?* because memory timing is board-dependend, you will

342? ??? ?* find a lowlevel_init.S in your board directory.

343? ??? ?*/

344? ??? mov?????? ip, lr

345?

346? ??? bl??? lowlevel_init

347?

348? ??? mov?????? lr, ip

349? ??? mov?????? pc, lr

350? #endif /* CONFIG_SKIP_LOWLEVEL_INIT */


?????????????? 代碼中的c0,c1,c7,c8都是ARM920T的協處理器CP15的寄存器。其中c7是cache控制寄存器,c8是TLB控制寄存器。325~327行代碼將0寫入c7、c8,使Cache,TLB內容無效。

?????? 第332~337行代碼關閉了MMU。這是通過修改CP15的c1寄存器來實現的,先看CP15的c1寄存器的格式(僅列出代碼中用到的位):

表 2.3 CP15的c1寄存器格式(部分)

????? 15???????

?????? 14??????

?? 13?????

?????? 12??????

???? 11??????

??? 10?????

?????? 9??????

??????? 8??????

?????? 7??????

???? 6???????

?????? 5??????

????? 4?????

?????? 3?????

???????? 2?????

???? 1????

??????? 0????????

.

.

V

I

.

.

R

S

B

.

.

.

.

C

A

M

?????? 各個位的意義如下:

V : ?表示異常向量表所在的位置,0:異常向量在0x00000000;1:異常向量在 0xFFFF0000
I : ?0 :關閉ICaches;1 :開啟ICaches
R、S : 用來與頁表中的描述符一起確定內存的訪問權限
B : ?0 :CPU為小字節序;1 : CPU為大字節序
C : ?0:關閉DCaches;1:開啟DCaches
A : ?0:數據訪問時不進行地址對齊檢查;1:數據訪問時進行地址對齊檢查
M : ?0:關閉MMU;1:開啟MMU

?????? 332~337行代碼將c1的 M位置零,關閉了MMU。

為什么要關閉catch和MMU呢?catch和MMU是做什么用的?

????MMU是Memory Management Unit的縮寫,中文名是內存管理單元,它是中央處理器(CPU)中用來管理虛擬存儲器、物理存儲器的控制線路

??? 同時也負責虛擬地址映射為物理地址,以及提供硬件機制的內存訪問授權??????

概述:

一,關catch

?????? catch和MMU是通過CP15管理的,剛上電的時候,CPU還不能管理他們

?????? 上電的時候MMU必須關閉,指令catch可關閉,可不關閉,但數據catch一定要關閉

?????? 否則可能導致剛開始的代碼里面,去取數據的時候,從catch里面取,而這時候RAM中數據還沒有catch過來,導致數據預取異常

二:關MMU

????? 因為MMU是;把虛擬地址轉化為物理地址得作用

????? 而目的是設置控制寄存器,而控制寄存器本來就是實地址(物理地址),再使能MMU,不就是多此一舉了嗎?

詳細分析---

????? Catch是cpu內部的一個2級緩存,它的作用是將常用的數據和指令放在cpu內部,MMU是用來把虛實地址轉換為物理地址用的

????? 我們的目的:是設置控制的寄存器,寄存器都是實地址(物理地址),如果既要開啟MMU又要做虛實地址轉換的話,中間還多一步,多此一舉了嘛?

??
????? 先要把實地址轉換成虛地址,然后再做設置,但對uboot而言就是起到一個簡單的初始化的作用和引導操作系統,如果開啟MMU的話,很麻煩,也沒必要,所以關閉MMU.
????

????? ?說到catch就必須提到一個關鍵字Volatile,以后在設置寄存器時會經常遇到,他的本質:是告訴編譯器不要對我的代碼進行優化,作用是讓編寫者感覺不倒變量的變化情況(也就是說,讓它執行速度加快吧)

???????優化的過程:是將常用的代碼取出來放到catch中,它沒有從實際的物理地址去取,它直接從cpu的緩存中去取,但常用的代碼就是為了感覺一些常用變量的變化

????????優化原因:如果正在取數據的時候發生跳變,那么就感覺不到變量的變化了,所以在這種情況下要用Volatile關鍵字告訴編譯器不要做優化,每次從實際的物理地址中去取指令,這就是為什么關閉catch關閉MMU

??????? ?但在C語言中是不會關閉catch和MMU的,會打開,如果編寫者要感覺外界變化,或變化太快,從catch中取數據會有誤差,就加一個關鍵字Volatile。

(8)初始化RAM控制寄存器

???????????????????? bl lowlevel_init下來初始化各個bank,把各個bank設置必須搞清楚,對以后移植復雜的uboot有很大幫助
???????????????????? 設置完畢后拷貝uboot代碼到4k空間,拷貝完畢后執行內存中的uboot代碼

????? 其中的lowlevel_init就完成了內存初始化的工作,由于內存初始化是依賴于開發板的,因此lowlevel_init的代碼一般放在board下面相應的目錄中。對于mini2440,lowlevel_init在board/samsung/mini2440/lowlevel_init.S中定義如下:

45? #define BWSCON?? 0x48000000??????? /* 13個存儲控制器的開始地址 */

? … …

129? _TEXT_BASE:

130? ??? .word???? TEXT_BASE???????0x33F80000, board/config.mk中這段話表示,用戶告訴編譯器編譯地址的起始地址

131?

132? .globl lowlevel_init

133? lowlevel_init:

134? ??? /* memory control configuration */

135? ??? /* make r0 relative the current location so that it */

136? ??? /* reads SMRDATA out of FLASH rather than memory ! */

137? ??? ldr???? r0, =SMRDATA

138? ??? ldr?? r1, _TEXT_BASE

139? ??? sub? r0, r0, r1????????????? /* SMRDATA減 _TEXT_BASE就是13個寄存器的偏移地址 */

140? ??? ldr?? r1, =BWSCON?? /* Bus Width Status Controller */

141? ??? add???? r2, r0, #13*4

142? 0:

143? ??? ldr???? r3, [r0], #4??? /*將13個寄存器的值逐一賦值給對應的寄存器*/

144? ??? str???? r3, [r1], #4

145? ??? cmp???? r2, r0

146? ??? bne? ???0b

147?

148? ??? /* everything is fine now */

149? ??? mov?????? pc, lr

150?

151? ??? .ltorg

152? /* the literal pools origin */

153?

154? SMRDATA:??????????? /*? 下面是13個寄存器的值? */

155? .word? … …

156 ? .word? … …

?… …

?????? lowlevel_init初始化了13個寄存器來實現RAM時鐘的初始化。lowlevel_init函數對于U-Boot從NAND Flash或NOR Flash啟動的情況都是有效的。

?????? U-Boot.lds鏈接腳本有如下代碼:

?????? .text :

?????? {

???????????????????? cpu/arm920t/start.o??? (.text)

???? ?????????? board/samsung/mini2440/lowlevel_init.o (.text)

??? ???????????? board/samsung/mini2440/nand_read.o (.text)

????????????? … …

?????? }

??

?????? board/samsung/mini2440/lowlevel_init.o將被鏈接到cpu/arm920t/start.o后面,因此board/samsung/mini2440/lowlevel_init.o也在U-Boot的前4KB的代碼中。

?????? U-Boot在NAND Flash啟動時,lowlevel_init.o將自動被讀取到CPU內部4KB的內部RAM中。因此第137~146行的代碼將從CPU內部RAM中復制寄存器的值到相應的寄存器中。

?????? 對于U-Boot在NOR Flash啟動的情況,由于U-Boot連接時確定的地址是U-Boot在內存中的地址,而此時U-Boot還在NOR Flash中,因此還需要在NOR Flash中讀取數據到RAM中。

?????? 由于NOR Flash的開始地址是0,而U-Boot的加載到內存的起始地址是TEXT_BASE,SMRDATA標號在Flash的地址就是SMRDATA-TEXT_BASE。

?????? 綜上所述,lowlevel_init的作用就是將SMRDATA開始的13個值復制給開始地址[BWSCON]的13個寄存器,從而完成了存儲控制器的設置。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

?問題一:如果換一塊開發板有可能改哪些東西?
????????????????? ?首先,cpu的運行模式,如果需要對cpu進行設置那就設置,管看門狗,關中斷不用改,時鐘有可能要改,如果能正常使用則不用改,關閉catch和MMU不用改,設置bank有可能要改。最后一步拷貝時看地址會不會變,如果變化也要改,執行內存中代碼,地址有可能要改。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
問題二:Nor Flash和Nand Flash本質區別:

????????????????? 就在于是否進行代碼拷貝,也就是下面代碼所表述:無論是Nor Flash還是Nand Flash,核心思想就是將uboot代碼搬運到內存中去運行,但是沒有拷貝bss后面這段代碼,只拷貝bss前面的代碼,bss代碼是放置全局變量的。Bss段代碼是為了清零,拷貝過去再清零重復操作

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

(9)復制U-Boot第二階段代碼到RAM

?????? cpu/arm920t/start.S原來的代碼是只支持從NOR Flash啟動的,經過修改現在U-Boot在NOR Flash和NAND Flash上都能啟動了,實現的思路是這樣的:

?????? bl??? bBootFrmNORFlash /*? 判斷U-Boot是在NAND Flash還是NOR Flash啟動? */

?????? cmp?????? r0, #0????????? /*? r0存放bBootFrmNORFlash函數返回值,若返回0表示NAND Flash啟動,否則表示在NOR Flash啟動? */

?????? beq nand_boot???????? /*? 跳轉到NAND Flash啟動代碼? */

?

/*? NOR Flash啟動的代碼? */

?????? b???? stack_setup???????? /* 跳過NAND Flash啟動的代碼 */

?

nand_boot:

/*? NAND Flash啟動的代碼? */

?

stack_setup:???????

?????? /* 其他代碼 */

?

?????? 其中bBootFrmNORFlash函數作用是判斷U-Boot是在NAND Flash啟動還是NOR Flash啟動,若在NOR Flash啟動則返回1,否則返回0。根據ATPCS規則,函數返回值會被存放在r0寄存器中,因此調用bBootFrmNORFlash函數后根據r0的值就可以判斷U-Boot在NAND Flash啟動還是NOR Flash啟動。bBootFrmNORFlash函數在board/samsung/mini2440/nand_read.c中定義如下:

int bBootFrmNORFlash(void)

{

??? volatile unsigned int *pdw = (volatile unsigned int *)0;

??? unsigned int dwVal;

??

??? dwVal = *pdw;?????? ??/* 先記錄下原來的數據 */

??? *pdw = 0x12345678;

??? if (*pdw != 0x12345678)?????? /* 寫入失敗,說明是在NOR Flash啟動 */

??? {

??????? return 1;?????

??? }

??? else?????? ??????????????????????????? /* 寫入成功,說明是在NAND Flash啟動 */

??? {

??????? *pdw = dwVal;??????? /* 恢復原來的數據 */

??????? return 0;

??? }

}

???? 無論是從NOR Flash還是從NAND Flash啟動,地址0處為U-Boot的第一條指令“ b??? start_code”。

?????? 對于從NAND Flash啟動的情況,其開始4KB的代碼會被自動復制到CPU內部4K內存中,因此可以通過直接賦值的方法來修改。

?????? 對于從NOR Flash啟動的情況,NOR Flash的開始地址即為0,必須通過一定的命令序列才能向NOR Flash中寫數據,所以可以根據這點差別來分辨是從NAND Flash還是NOR Flash啟動:向地址0寫入一個數據,然后讀出來,如果發現寫入失敗的就是NOR Flash,否則就是NAND Flash。

?????? 下面來分析NOR Flash啟動部分代碼:

208? ??? adr? r0, _start????????????? /* r0 <- current position of code?? */

209? ??? ldr?? r1, _TEXT_BASE??????????? /* test if we run from flash or RAM */

?

/* 判斷U-Boot是否是下載到RAM中運行,若是,則不用?再復制到RAM中了,這種情況通常在調試U-Boot時才發生 */

210? ??? cmp ???? r0, r1????? /*_start等于_TEXT_BASE說明是下載到RAM中運行 */

211? ??? beq stack_setup

212? /* 以下直到nand_boot標號前都是NOR Flash啟動的代碼 */

213? ??? ldr?? r2, _armboot_start?? /*flash中armboot_start的起始地址*/

214? ??? ldr?? r3, _bss_start???????? /*uboot_bss的起始地址*/

215? ??? sub? r2, r3, r2????????????? /* r2 <- size of armboot??uboot實際程序代碼的大小?? */

216? ??? add r2, r0, r2????????????? /* r2 <- source end address???????? */

217? /*?搬運U-Boot自身到RAM中*/

218? copy_loop:

219? ??? ldmia???? r0!, {r3-r10} /* 從地址為[r0]的NOR Flash中讀入8個字的數據 */

220? ??? stmia????? r1!, {r3-r10} /* 將r3至r10寄存器的數據復制給地址為[r1]的內存 */

221? ??? cmp?????? r0, r2??????????????????? /* until source end addreee [r2]??? */

222? ??? ble? copy_loop

223? ??? b???? stack_setup???????? /* 跳過NAND Flash啟動的代碼 */

?????? 下面再來分析NAND Flash啟動部分代碼:

nand_boot:

??? mov r1, #NAND_CTL_BASE?

??? ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )

??? str r2, [r1, #oNFCONF]?? /* 設置NFCONF寄存器 */

?

?????? /* 設置NFCONT,初始化ECC編/解碼器,禁止NAND Flash片選 */

??? ldr r2, =( (1<<4)|(0<<1)|(1<<0) )

??? str r2, [r1, #oNFCONT]?

?

??? ldr r2, =(0x6)?????????? /* 設置NFSTAT */

str r2, [r1, #oNFSTAT]

?

?????? /* 復位命令,第一次使用NAND Flash前復位 */

??? mov r2, #0xff???????????

??? strb r2, [r1, #oNFCMD]

??? mov r3, #0??????????????

?

??? /* 為調用C函數nand_read_ll準備堆棧 */

??? ldr sp, DW_STACK_START??

??? mov fp, #0??????????????

??? /* 下面先設置r0至r2,然后調用nand_read_ll函數將U-Boot讀入RAM */

??? ldr r0, =TEXT_BASE????? /* 目的地址:U-Boot在RAM的開始地址 */

??? mov r1, #0x0???? ????????? /* 源地址:U-Boot在NAND Flash中的開始地址 */

??? mov r2, #0x30000? ??????? /* 復制的大小,必須比u-boot.bin文件大,并且必須是NAND Flash塊大小的整數倍,這里設置為0x30000(192KB) */

??? bl? nand_read_ll?? ????????????? /* 跳轉到nand_read_ll函數,開始復制U-Boot到RAM */

tst? r0, #0x0???????????????????? /* 檢查返回值是否正確 */

beq stack_setup

bad_nand_read:

loop2: b loop2??? //infinite loop

?

.align 2

DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

?????? 其中NAND_CTL_BASE,oNFCONF等在include/configs/mini2440.h中定義如下:

#define NAND_CTL_BASE? 0x4E000000? // NAND Flash控制寄存器基址

?

#define STACK_BASE? 0x33F00000???? //base address of stack

#define STACK_SIZE? 0x8000???????? //size of stack

?

#define oNFCONF? 0x00????? /* NFCONF相對于NAND_CTL_BASE偏移地址 */

#define oNFCONT? 0x04????? /* NFCONT相對于NAND_CTL_BASE偏移地址*/

#define oNFADDR? 0x0c???? /* NFADDR相對于NAND_CTL_BASE偏移地址*/

#define oNFDATA? 0x10????? /* NFDATA相對于NAND_CTL_BASE偏移地址*/

#define oNFCMD?? 0x08???? /* NFCMD相對于NAND_CTL_BASE偏移地址*/

#define oNFSTAT? 0x20??????? /* NFSTAT相對于NAND_CTL_BASE偏移地址*/

#define oNFECC?? 0x2c????????????? /* NFECC相對于NAND_CTL_BASE偏移地址*/

?????? NAND Flash各個控制寄存器的設置在S3C2440的數據手冊有詳細說明,這里就不介紹了。

?????? 代碼中nand_read_ll函數的作用是在NAND Flash中搬運U-Boot到RAM,該函數在board/samsung/mini2440/nand_read.c中定義。

?????? NAND Flash根據page大小可分為2種: 512B/page和2048B/page的。這兩種NAND Flash的讀操作是不同的。因此就需要U-Boot識別到NAND Flash的類型,然后采用相應的讀操作,也就是說nand_read_ll函數要能自動適應兩種NAND Flash。

?????? 參考S3C2440的數據手冊可以知道:根據NFCONF寄存器的Bit3(AdvFlash (Read only))和Bit2 (PageSize (Read only))可以判斷NAND Flash的類型。Bit2、Bit3與NAND Flash的block類型的關系如下表所示:

表 2.4 NFCONF的Bit3、Bit2與NAND Flash的關系

????????????????????????????????? Bit2??? Bit3????????????????????????????????

??????????????????????? ? ?????? 0???????????????????? ????????????

??????????????????????????? ??? ??? 1????????????????????????? ?????? ??????

0

256 B/page

512 B/page

1

1024 B/page

2048 B/page

?

?????? 由于的NAND Flash只有512B/page和2048 B/page這兩種,因此根據NFCONF寄存器的Bit3即可區分這兩種NAND Flash了。

?????? 完整代碼見board/samsung/mini2440/nand_read.c中的nand_read_ll函數,這里給出偽代碼:

int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)

{

//根據NFCONF寄存器的Bit3來區分2種NAND Flash

?????? if( NFCONF & 0x8 ) ?????? /* Bit是1,表示是2KB/page的NAND Flash */

?????? {

?????????????

????????????? 讀取2K block 的NAND Flash

?????????????

?

?????? }

?????? else????????????????????? /* Bit是0,表示是512B/page的NAND Flash */

?????? {

????????????? /

????????????? 讀取512B block 的NAND Flash

????????????? /

?

?????? }

??? return 0;

}

(10)設置堆棧

?????? /* ?設置堆棧 */

stack_setup:

?????? ldr?? r0, _TEXT_BASE??????????? /* upper 128 KiB: relocated uboot?? */

?????? sub? r0, r0, #CONFIG_SYS_MALLOC_LEN?? /* malloc area????????????? */

?????? sub? r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /*? 跳過全局數據區?????????????? */

#ifdef CONFIG_USE_IRQ

?????? sub? r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

?????? sub? sp, r0, #12?????????? /* leave 3 words for abort-stack??? */

?????? 只要將sp指針指向一段沒有被使用的內存就完成棧的設置了。根據上面的代碼可以知道U-Boot內存使用情況了,如下圖所示:

?

?

圖2.2 U-Boot內存使用情況

?

(11)清除BSS段

clear_bss:

?????? ldr?? r0, _bss_start????????????? /* BSS段開始地址,在u-boot.lds中指定*/

?????? ldr?? r1, _bss_end?????????????? /* BSS段結束地址,在u-boot.lds中指定*/

?????? mov?????? r2, #0x00000000

clbss_l:str???? r2, [r0]????????? /* 將bss段清零*/

?????? add r0, r0, #4

?????? cmp ???? r0, r1

?????? ble? clbss_l

?????? 初始值為0,無初始值的全局變量,靜態變量將自動被放在BSS段。應該將這些變量的初始值賦為0,否則這些變量的初始值將是一個隨機的值,若有些程序直接使用這些沒有初始化的變量將引起未知的后果。

(12)跳轉到第二階段代碼入口

?????? ldr?? pc,?_start_armboot

?

_start_armboot:?? .word? start_armboot

?????? 跳轉到第二階段代碼入口start_armboot處。

1.1.2?????????????U-Boot啟動第二階段代碼分析

?????? start_armboot函數在lib_arm/board.c中定義,是U-Boot第二階段代碼的入口。U-Boot啟動第二階段流程如下:

?

圖 2.3 U-Boot第二階段執行流程

?????? 在分析start_armboot函數前先來看看一些重要的數據結構:

(1)gd_t結構體

?????? U-Boot使用了一個結構體gd_t來存儲全局數據區的數據,這個結構體在include/asm-arm/global_data.h中定義如下:

typedef? struct???? global_data {

?????? bd_t????????????? *bd;

?????? unsigned long????? flags;

?????? unsigned long????? baudrate;

?????? unsigned long????? have_console;????? /* serial_init() was called */

?????? unsigned long????? env_addr;???? /* Address? of Environment struct */

?????? unsigned long????? env_valid;??? /* Checksum of Environment valid? */

?????? unsigned long????? fb_base; /* base address of frame buffer */

?????? void????????????? **jt;????????????? /* jump table */

} gd_t;

?????? U-Boot使用了一個存儲在寄存器中的指針gd來記錄全局數據區的地址:

#define DECLARE_GLOBAL_DATA_PTR???? register volatile gd_t *gd asm ("r8")

?????? DECLARE_GLOBAL_DATA_PTR定義一個gd_t全局數據結構的指針,這個指針存放在指定的寄存器r8中。這個聲明也避免編譯器把r8分配給其它的變量。任何想要訪問全局數據區的代碼,只要代碼開頭加入“DECLARE_GLOBAL_DATA_PTR”一行代碼,然后就可以使用gd指針來訪問全局數據區了。

?????? 根據U-Boot內存使用圖中可以計算gd的值:

gd = TEXT_BASE -CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)

(2)bd_t結構體

?????? bd_t在include/asm-arm.u/u-boot.h中定義如下:

typedef struct bd_info {

??? int??????????????? bi_baudrate; ????????????? /* 串口通訊波特率 */

??? unsigned long???? bi_ip_addr;?? ?????? /* IP 地址*/

??? struct environment_s ?????? *bi_env;????????????? /* 環境變量開始地址 */

??? ulong??? ??????? bi_arch_number;????? /* 開發板的機器碼 */

??? ulong??? ??????? bi_boot_params;?????? /* 內核參數的開始地址 */

??? struct???????????????????????? /* RAM配置信息 */

??? {

????????????? ulong start;

????????????? ulong size;

?? ?}bi_dram[CONFIG_NR_DRAM_BANKS];?

} bd_t;

?????? U-Boot啟動內核時要給內核傳遞參數,這時就要使用gd_t,bd_t結構體中的信息來設置標記列表。

?????? 第一階段調用start_armboot指向C語言執行代碼區,首先它要從內存上的重定位數據獲得不完全配置的全局數據表格和板級信息表格,即獲得gd_tbd_t

這兩個類型變量記錄了剛啟動時的信息,并將要記錄作為引導內核和文件系統的參數,如bootargs等等,并且將來還會在啟動內核時,由uboot交由kernel時會有所用。

(3)init_sequence數組

?????? U-Boot使用一個數組init_sequence來存儲對于大多數開發板都要執行的初始化函數的函數指針。init_sequence數組中有較多的編譯選項,去掉編譯選項后init_sequence數組如下所示:

typedef int (init_fnc_t) (void);

?

init_fnc_t *init_sequence[] = {

?????? board_init,??? ? ?? /*開發板相關的配置--board/samsung/mini2440/mini2440.c */

?????? timer_init,??????????? /* 時鐘初始化-- cpu/arm920t/s3c24x0/timer.c */

?????? env_init,? ????????? /*初始化環境變量--common/env_flash.c 或common/env_nand.c*/

?????? init_baudrate,????? /*初始化波特率-- lib_arm/board.c */

?????? serial_init,??????????? /* 串口初始化-- drivers/serial/serial_s3c24x0.c */

?????? console_init_f,??? /* 控制通訊臺初始化階段1-- common/console.c */

?????? display_banner,?? /*打印U-Boot版本、編譯的時間-- gedit lib_arm/board.c */

?????? dram_init,??????????? /*配置可用的RAM-- board/samsung/mini2440/mini2440.c */

?????? display_dram_config,????????????? /* 顯示RAM大小-- lib_arm/board.c */

?????? NULL,

};

?????? 其中的board_init函數在board/samsung/mini2440/mini2440.c中定義,該函數設置了MPLLCOM,UPLLCON,以及一些GPIO寄存器的值,還設置了U-Boot機器碼和內核啟動參數地址 :

/* MINI2440開發板的機器碼 */

gd->bd->bi_arch_number = MACH_TYPE_MINI2440;

?

/* 內核啟動參數地址 */

gd->bd->bi_boot_params?= 0x30000100;??

?????? 其中的dram_init函數在board/samsung/mini2440/mini2440.c中定義如下:

int dram_init (void)

{

????? /* 由于mini2440只有 */

????? gd->bd->bi_dram[0].start = PHYS_SDRAM_1;

????? gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;

?

????? return 0;

}

mini2440使用2片32MB的SDRAM組成了64MB的內存,接在存儲控制器的BANK6,地址空間是0x30000000~0x34000000。

在include/configs/mini2440.h中PHYS_SDRAM_1和PHYS_SDRAM_1_SIZE 分別被定義為0x30000000和0x04000000(64M)。

?????? 分析完上述的數據結構,下面來分析start_armboot函數:

void start_armboot (void)

{

?????? init_fnc_t **init_fnc_ptr;

?????? char *s;

?????? … …

?????? /* 計算全局數據結構的地址gd */

?????? gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));

?????? … …

?????? memset ((void*)gd, 0, sizeof (gd_t));

?????? gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));

?????? memset (gd->bd, 0, sizeof (bd_t));

?????? gd->flags |= GD_FLG_RELOC;

?

?????? monitor_flash_len = _bss_start - _armboot_start;

?

/* 逐個調用init_sequence數組中的初始化函數? */

?????? for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {

????????????? if ((*init_fnc_ptr)() != 0) {

???????????????????? hang ();

????????????? }

?????? }

?

/* armboot_start 在cpu/arm920t/start.S 中被初始化為u-boot.lds連接腳本中的_start */

?????? mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,

???????????????????? CONFIG_SYS_MALLOC_LEN);

?

/* NOR Flash初始化 */

#ifndef CONFIG_SYS_NO_FLASH

?????? /* configure available FLASH banks */

?????? display_flash_config (flash_init ());

#endif /* CONFIG_SYS_NO_FLASH */

?

?????? … …

/* NAND Flash 初始化*/

#if defined(CONFIG_CMD_NAND)

?????? puts ("NAND:? ");

?????? nand_init();???????? /* go init the NAND */

#endif

?????? … …

?????? /*配置環境變量,重新定位 */

?????? env_relocate ();

?????? … …

?????? /* 從環境變量中獲取IP地址 */

?????? gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

?????? stdio_init (); /* get the devices list going. */

?????? jumptable_init ();

?????? … …

?????? console_init_r (); /* fully init console as a device */

?????? … …

?????? /* enable exceptions */

?????? enable_interrupts ();

?

#ifdef CONFIG_USB_DEVICE

?????? usb_init_slave();

#endif

?

?????? /* Initialize from environment */

?????? if ((s = getenv ("loadaddr")) != NULL) {

????????????? load_addr = simple_strtoul (s, NULL, 16);

?????? }

#if defined(CONFIG_CMD_NET)

?????? if ((s = getenv ("bootfile")) != NULL) {

????????????? copy_filename (BootFile, s, sizeof (BootFile));

?????? }

#endif

?????? … …

?????? /* 網卡初始化 */

#if defined(CONFIG_CMD_NET)

#if defined(CONFIG_NET_MULTI)

?????? puts ("Net:?? ");

#endif

?????? eth_initialize(gd->bd);

… …

#endif

?

?????? /* main_loop() can return to retry autoboot, if so just run it again. */

?????? for (;;) {

????????????? main_loop ();

?????? }

?????? /* NOTREACHED - no way out of command loop except booting */

}

?????? main_loop函數在common/main.c中定義。一般情況下,進入main_loop函數若干秒內沒有

1.1.3???????????? U-Boot啟動Linux過程

?????? U-Boot使用標記列表(tagged list)的方式向Linux傳遞參數。標記的數據結構式是tag,在U-Boot源代碼目錄include/asm-arm/setup.h中定義如下:

struct tag_header {

?????? u32 size;?????? /* 表示tag數據結構的聯合u實質存放的數據的大小*/

?????? u32 tag;??????? /* 表示標記的類型 */

};

?

struct tag {

?????? struct tag_header hdr;

?????? union {

????????????? struct tag_core?????????? core;

????????????? struct tag_mem32????? mem;

????????????? struct tag_videotext?? videotext;

????????????? struct tag_ramdisk???? ramdisk;

????????????? struct tag_initrd? initrd;

????????????? struct tag_serialnr?????? serialnr;

????????????? struct tag_revision????? revision;

????????????? struct tag_videolfb???? videolfb;

????????????? struct tag_cmdline???? cmdline;

?

????????????? /*

????????????? ?* Acorn specific

????????????? ?*/

????????????? struct tag_acorn? acorn;

????????????? /*

????????????? ?* DC21285 specific

????????????? ?*/

????????????? struct tag_memclk????? memclk;

?????? } u;

};

?????? U-Boot使用命令bootm來啟動已經加載到內存中的內核。而bootm命令實際上調用的是do_bootm函數。對于Linux內核,do_bootm函數會調用do_bootm_linux函數來設置標記列表和啟動內核。do_bootm_linux函數在lib_arm/bootm.c 中定義如下:

59?? int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)

60?? {

61?? ??? bd_t?????? *bd = gd->bd;

62?? ??? char?????? *s;

63?? ??? int?? machid = bd->bi_arch_number;

64? ???? void?????? (*theKernel)(int zero, int arch, uint params);

65??

66?? #ifdef CONFIG_CMDLINE_TAG

67?? ??? char *commandline = getenv ("bootargs");?? /* U-Boot環境變量bootargs */

68?? #endif

?????? … …

73?? ??? theKernel = (void (*)(int, int, uint))images->ep; /* 獲取內核入口地址 */

?????? … …

86?? #if defined (CONFIG_SETUP_MEMORY_TAGS) || \

87?????? defined (CONFIG_CMDLINE_TAG) || \

88?????? defined (CONFIG_INITRD_TAG) || \

89?????? defined (CONFIG_SERIAL_TAG) || \

90?????? defined (CONFIG_REVISION_TAG) || \

91?????? defined (CONFIG_LCD) || \

92?????? defined (CONFIG_VFD)

93?? ??? setup_start_tag (bd);???????????????????????????????????? /* 設置ATAG_CORE標志 */

?????? … …

100? #ifdef CONFIG_SETUP_MEMORY_TAGS

101? ??? setup_memory_tags (bd);????????????????????? ?????? /* 設置內存標記 */

102? #endif

103? #ifdef CONFIG_CMDLINE_TAG

104? ??? setup_commandline_tag (bd, commandline);????? /* 設置命令行標記 */

105? #endif

?????? … …

113? ??? setup_end_tag (bd);?????????????????????????????? /* 設置ATAG_NONE標志 */??????????

114? #endif

115?

116? ??? /* we assume that the kernel is in place */

117? ??? printf ("\nStarting kernel ...\n\n");

?????? … …

126? ??? cleanup_before_linux ();????????? /* 啟動內核前對CPU作最后的設置 */

127?

128? ??? theKernel (0, machid, bd->bi_boot_params);????? /* 調用內核 */

129? ??? /* does not return */

130?

131? ??? return 1;

132? }

?????? 其中的setup_start_tag,setup_memory_tags,setup_end_tag函數在lib_arm/bootm.c中定義如下:

?????? (1)setup_start_tag函數

static void setup_start_tag (bd_t *bd)

{

?????? params = (struct tag *) bd->bi_boot_params;? /* 內核的參數的開始地址 */

?

?????? params->hdr.tag = ATAG_CORE;

?????? params->hdr.size = tag_size (tag_core);

?

?????? params->u.core.flags = 0;

?????? params->u.core.pagesize = 0;

?????? params->u.core.rootdev = 0;

?

?????? params = tag_next (params);

}

?????? 標記列表必須以ATAG_CORE開始,setup_start_tag函數在內核的參數的開始地址設置了一個ATAG_CORE標記。

?????? (2)setup_memory_tags函數

static void setup_memory_tags (bd_t *bd)

{

?????? int i;

/*設置一個內存標記 */

?????? for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {???

????????????? params->hdr.tag = ATAG_MEM;

????????????? params->hdr.size = tag_size (tag_mem32);

?

????????????? params->u.mem.start = bd->bi_dram[i].start;

????????????? params->u.mem.size = bd->bi_dram[i].size;

?

????????????? params = tag_next (params);

?????? }

}

?????? setup_memory_tags函數設置了一個ATAG_MEM標記,該標記包含內存起始地址,內存大小這兩個參數。

?????? (3)setup_end_tag函數

static void setup_end_tag (bd_t *bd)

{

?????? params->hdr.tag = ATAG_NONE;

?????? params->hdr.size = 0;

}

?????? 標記列表必須以標記ATAG_NONE結束,setup_end_tag函數設置了一個ATAG_NONE標記,表示標記列表的結束。

?????? U-Boot設置好標記列表后就要調用內核了。但調用內核前,CPU必須滿足下面的條件:

(1)??? CPU寄存器的設置

?? r0=0

?? r1=機器碼

?? r2=內核參數標記列表在RAM中的起始地址

(2)??? CPU工作模式

?? 禁止IRQ與FIQ中斷

?? CPU為SVC模式

(3)??? 使數據Cache與指令Cache失效

?????? do_bootm_linux中調用的cleanup_before_linux函數完成了禁止中斷和使Cache失效的功能。cleanup_before_linux函數在cpu/arm920t/cpu.中定義:

int cleanup_before_linux (void)

{

?????? /*

?????? ?* this function is called just before we call linux

?????? ?* it prepares the processor for linux

?????? ?*

?????? ?* we turn off caches etc ...

?????? ?*/

?

?????? disable_interrupts ();???????? /* 禁止FIQ/IRQ中斷 */

?

?????? /* turn off I/D-cache */

?????? icache_disable();?????????????? /* 使指令Cache失效 */

?????? dcache_disable();????????????? /* 使數據Cache失效 */

?????? /* flush I/D-cache */

?????? cache_flush();??????????????????? /* 刷新Cache */

?

?????? return 0;

}

?????? 由于U-Boot啟動以來就一直工作在SVC模式,因此CPU的工作模式就無需設置了。

do_bootm_linux中:

64?? ??? void?????? (*theKernel)(int zero, int arch, uint params);

… …

73?? ??? theKernel = (void (*)(int, int, uint))images->ep;

… …

128? ??? theKernel (0, machid, bd->bi_boot_params);

?????? 第73行代碼將內核的入口地址“images->ep”強制類型轉換為函數指針。根據ATPCS規則,函數的參數個數不超過4個時,使用r0~r3這4個寄存器來傳遞參數。因此第128行的函數調用則會將0放入r0,機器碼machid放入r1,內核參數地址bd->bi_boot_params放入r2,從而完成了寄存器的設置,最后轉到內核的入口地址。

?????? 到這里,U-Boot的工作就結束了,系統跳轉到Linux內核代碼執行。

1.1.4???????????? U-Boot添加命令的方法及U-Boot命令執行過程

?????? 下面以添加menu命令(啟動菜單)為例講解U-Boot添加命令的方法。

(1)??? 建立common/cmd_menu.c

?????? 習慣上通用命令源代碼放在common目錄下,與開發板專有命令源代碼則放在board/<board_dir>目錄下,并且習慣以“cmd_<命令名>.c”為文件名。

(2)??? 定義“menu”命令

?????? 在cmd_menu.c中使用如下的代碼定義“menu”命令:

_BOOT_CMD(

?????? menu,??? 3,??? 0,??? do_menu,

?????? "menu - display a menu, to select the items to do something\n",

?????? " - display a menu, to select the items to do something"

);

?????? 其中U_BOOT_CMD命令格式如下:

U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)

?????? 各個參數的意義如下:

name:命令名,非字符串,但在U_BOOT_CMD中用“#”符號轉化為字符串

maxargs:命令的最大參數個數

rep:是否自動重復(按Enter鍵是否會重復執行)

cmd:該命令對應的響應函數

usage:簡短的使用說明(字符串)

help:較詳細的使用說明(字符串)

?????? 在內存中保存命令的help字段會占用一定的內存,通過配置U-Boot可以選擇是否保存help字段。若在include/configs/mini2440.h中定義了CONFIG_SYS_LONGHELP宏,則在U-Boot中使用help命令查看某個命令的幫助信息時將顯示usage和help字段的內容,否則就只顯示usage字段的內容。

?????? U_BOOT_CMD宏在include/command.h中定義:

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \

cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

?????? “##”與“#”都是預編譯操作符,“##”有字符串連接的功能,“#”表示后面緊接著的是一個字符串。

?????? 其中的cmd_tbl_t在include/command.h中定義如下:

struct cmd_tbl_s {

?????? char????????????? *name;????????? /* 命令名 */

?????? int????????? maxargs;?????? /* 最大參數個數 */

?????? int????????? repeatable;??? /* 是否自動重復 */

?????? int????????? (*cmd)(struct cmd_tbl_s *, int, int, char *[]);? /* ?響應函數 */

?????? char????????????? *usage;???????? /* 簡短的幫助信息 */

#ifdef??? CONFIG_SYS_LONGHELP

?????? char????????????? *help;?????????? /* ?較詳細的幫助信息 */

#endif

#ifdef CONFIG_AUTO_COMPLETE

?????? /* 自動補全參數 */

?????? int????????? (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);

#endif

};

typedef struct cmd_tbl_s? cmd_tbl_t;

?????? 一個cmd_tbl_t結構體變量包含了調用一條命令的所需要的信息。

?????? 其中Struct_Section在include/command.h中定義如下:

#define Struct_Section? __attribute__ ((unused,section (".u_boot_cmd")))

?????? 凡是帶有__attribute__ ((unused,section (".u_boot_cmd"))屬性聲明的變量都將被存放在".u_boot_cmd"段中,并且即使該變量沒有在代碼中顯式的使用編譯器也不產生警告信息。

?????? 在U-Boot連接腳本u-boot.lds中定義了".u_boot_cmd"段:

?????? . = .;

?????? __u_boot_cmd_start = .;????????? /*將 __u_boot_cmd_start指定為當前地址 */

?????? .u_boot_cmd : { *(.u_boot_cmd) }

?????? __u_boot_cmd_end = .;?????????? /*? 將__u_boot_cmd_end指定為當前地址? */

?????? 這表明帶有“.u_boot_cmd”聲明的函數或變量將存儲在“u_boot_cmd”段。這樣只要將U-Boot所有命令對應的cmd_tbl_t變量加上“.u_boot_cmd”聲明,編譯器就會自動將其放在“u_boot_cmd”段,查找cmd_tbl_t變量時只要在__u_boot_cmd_start與__u_boot_cmd_end之間查找就可以了。

?????? 因此“menu”命令的定義經過宏展開后如下:

cmd_tbl_t __u_boot_cmd_menu __attribute__ ((unused,section (".u_boot_cmd"))) = {menu, 3, 0, do_menu, "menu - display a menu, to select the items to do something\n", " - display a menu, to select the items to do something"}

?????? 實質上就是用U_BOOT_CMD宏定義的信息構造了一個cmd_tbl_t類型的結構體。編譯器將該結構體放在“u_boot_cmd”段,執行命令時就可以在“u_boot_cmd”段查找到對應的cmd_tbl_t類型結構體。

(3)??? 實現命令的函數

?????? 在cmd_menu.c中添加“menu”命令的響應函數的實現。具體的實現代碼略:

int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

{

?????? /* 實現代碼略 */

}

(4)??? 將common/cmd_menu.c編譯進u-boot.bin

?????? 在common/Makefile中加入如下代碼:

COBJS-$(CONFIG_BOOT_MENU) += cmd_menu.o

?????? 在include/configs/mini2440.h加入如代碼:

#define CONFIG_BOOT_MENU 1

?????? 重新編譯下載U-Boot就可以使用menu命令了

(5)menu命令執行的過程

?????? 在U-Boot中輸入“menu”命令執行時,U-Boot接收輸入的字符串“menu”,傳遞給run_command函數。run_command函數調用common/command.c中實現的find_cmd函數在__u_boot_cmd_start與__u_boot_cmd_end間查找命令,并返回menu命令的cmd_tbl_t結構。然后run_command函數使用返回的cmd_tbl_t結構中的函數指針調用menu命令的響應函數do_menu,從而完成了命令的執行。

?

?  作者:heaad

?  ?http://www.cnblogs.com/heaad/?

  郵箱:heaad@qq.com

?   本文摘選自作者所寫的一篇文章。轉載請注明,水平有限,歡迎拍磚。?

轉載于:https://www.cnblogs.com/huty/p/8517542.html

總結

以上是生活随笔為你收集整理的【ARM-Linux开发】U-Boot启动过程--详细版的完全分析的全部內容,希望文章能夠幫你解決所遇到的問題。

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

大乳丰满人妻中文字幕日本 | 欧美丰满老熟妇xxxxx性 | 国产精品无码成人午夜电影 | 亚洲国产av美女网站 | 天下第一社区视频www日本 | 中文字幕无码免费久久9一区9 | 人妻人人添人妻人人爱 | 天干天干啦夜天干天2017 | 亚洲狠狠色丁香婷婷综合 | 国产亚洲tv在线观看 | 好爽又高潮了毛片免费下载 | 国产色在线 | 国产 | 免费国产成人高清在线观看网站 | 一本大道久久东京热无码av | 国产精品.xx视频.xxtv | 亚洲中文字幕av在天堂 | 日本一卡2卡3卡四卡精品网站 | 中文字幕无码视频专区 | 欧美国产日韩久久mv | 国产片av国语在线观看 | 成人片黄网站色大片免费观看 | 亚洲 高清 成人 动漫 | 纯爱无遮挡h肉动漫在线播放 | 精品久久久无码人妻字幂 | 欧美自拍另类欧美综合图片区 | 久久久久免费精品国产 | 亚洲s码欧洲m码国产av | 国产成人综合色在线观看网站 | 性做久久久久久久免费看 | 激情五月综合色婷婷一区二区 | 成人aaa片一区国产精品 | 高潮毛片无遮挡高清免费视频 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 欧美日本精品一区二区三区 | 大乳丰满人妻中文字幕日本 | 久久亚洲国产成人精品性色 | 亚洲色偷偷偷综合网 | 在线观看国产午夜福利片 | 精品亚洲韩国一区二区三区 | 亚洲国产欧美国产综合一区 | 日韩精品一区二区av在线 | 18禁黄网站男男禁片免费观看 | 一个人看的视频www在线 | 亚洲中文无码av永久不收费 | 纯爱无遮挡h肉动漫在线播放 | 老司机亚洲精品影院无码 | 1000部啪啪未满十八勿入下载 | 激情内射亚州一区二区三区爱妻 | 无遮挡啪啪摇乳动态图 | 无码国模国产在线观看 | 精品国偷自产在线 | 欧美日本免费一区二区三区 | 国产国产精品人在线视 | 丰满人妻一区二区三区免费视频 | 日本丰满熟妇videos | 99久久人妻精品免费一区 | 狠狠亚洲超碰狼人久久 | 97久久国产亚洲精品超碰热 | 国产在热线精品视频 | 亚洲爆乳精品无码一区二区三区 | 婷婷丁香六月激情综合啪 | 日本精品人妻无码77777 天堂一区人妻无码 | 亚洲男人av天堂午夜在 | 少妇性l交大片欧洲热妇乱xxx | 欧美精品国产综合久久 | 国产午夜精品一区二区三区嫩草 | 成人欧美一区二区三区黑人 | 久久午夜夜伦鲁鲁片无码免费 | 老司机亚洲精品影院无码 | 欧美国产日产一区二区 | 色欲综合久久中文字幕网 | 日本大香伊一区二区三区 | 自拍偷自拍亚洲精品被多人伦好爽 | 国产综合在线观看 | 亚洲国产精品毛片av不卡在线 | 中文无码伦av中文字幕 | 成熟女人特级毛片www免费 | 久久综合狠狠综合久久综合88 | 中文字幕av日韩精品一区二区 | 中文字幕av日韩精品一区二区 | 国产人妻大战黑人第1集 | 人人澡人人妻人人爽人人蜜桃 | 一本无码人妻在中文字幕免费 | 99riav国产精品视频 | 初尝人妻少妇中文字幕 | 免费无码的av片在线观看 | 伊人久久大香线蕉av一区二区 | 国产无套内射久久久国产 | 亚洲精品久久久久avwww潮水 | 在线 国产 欧美 亚洲 天堂 | 欧美日本免费一区二区三区 | 日韩精品无码免费一区二区三区 | 99er热精品视频 | 大地资源中文第3页 | 日韩视频 中文字幕 视频一区 | 无码精品人妻一区二区三区av | 黑人大群体交免费视频 | 国产精品福利视频导航 | 无码福利日韩神码福利片 | 女人被男人躁得好爽免费视频 | 成人免费无码大片a毛片 | 国产综合久久久久鬼色 | 亚洲日本va中文字幕 | 日本熟妇大屁股人妻 | 国产人妻大战黑人第1集 | www国产精品内射老师 | 天下第一社区视频www日本 | 国产精品爱久久久久久久 | 精品无码一区二区三区的天堂 | 一个人免费观看的www视频 | 亚洲国产精华液网站w | 免费观看的无遮挡av | 樱花草在线播放免费中文 | 精品无码国产自产拍在线观看蜜 | 小sao货水好多真紧h无码视频 | 色五月五月丁香亚洲综合网 | 国产电影无码午夜在线播放 | 无码一区二区三区在线 | 亚洲精品久久久久久一区二区 | 日韩无码专区 | 久久五月精品中文字幕 | 十八禁真人啪啪免费网站 | 国产偷国产偷精品高清尤物 | 鲁一鲁av2019在线 | 色偷偷人人澡人人爽人人模 | 日韩精品无码免费一区二区三区 | 天天综合网天天综合色 | 暴力强奷在线播放无码 | 日本又色又爽又黄的a片18禁 | √天堂中文官网8在线 | 精品无码国产一区二区三区av | 丁香花在线影院观看在线播放 | 风流少妇按摩来高潮 | 天天躁夜夜躁狠狠是什么心态 | 又大又紧又粉嫩18p少妇 | 国产在线一区二区三区四区五区 | 午夜免费福利小电影 | 四虎国产精品一区二区 | 人人妻人人藻人人爽欧美一区 | 综合网日日天干夜夜久久 | 久久人妻内射无码一区三区 | 国产69精品久久久久app下载 | 亚洲精品成人福利网站 | 强辱丰满人妻hd中文字幕 | 亚洲の无码国产の无码影院 | 九月婷婷人人澡人人添人人爽 | 人妻少妇被猛烈进入中文字幕 | 国产无av码在线观看 | 男女性色大片免费网站 | 国产精品第一国产精品 | 水蜜桃亚洲一二三四在线 | 国内精品人妻无码久久久影院蜜桃 | 日本一本二本三区免费 | 日本欧美一区二区三区乱码 | 白嫩日本少妇做爰 | 国产午夜亚洲精品不卡 | a在线亚洲男人的天堂 | 亚洲成熟女人毛毛耸耸多 | 国产精品第一国产精品 | 初尝人妻少妇中文字幕 | 人人澡人人妻人人爽人人蜜桃 | 精品无码国产自产拍在线观看蜜 | 亚洲成熟女人毛毛耸耸多 | 日本va欧美va欧美va精品 | 小泽玛莉亚一区二区视频在线 | 一本色道久久综合亚洲精品不卡 | 狠狠cao日日穞夜夜穞av | 天天综合网天天综合色 | 国产疯狂伦交大片 | 亚洲精品中文字幕乱码 | 国模大胆一区二区三区 | 国产热a欧美热a在线视频 | 无套内谢的新婚少妇国语播放 | 漂亮人妻洗澡被公强 日日躁 | 自拍偷自拍亚洲精品10p | 中国女人内谢69xxxx | 国产激情无码一区二区app | 中文字幕日韩精品一区二区三区 | 丰满岳乱妇在线观看中字无码 | 樱花草在线播放免费中文 | 国产xxx69麻豆国语对白 | av无码久久久久不卡免费网站 | 国产精品无码永久免费888 | 老熟女重囗味hdxx69 | 亚洲国产成人a精品不卡在线 | 无码人妻精品一区二区三区下载 | 精品无码国产一区二区三区av | 小泽玛莉亚一区二区视频在线 | 日韩精品久久久肉伦网站 | 午夜成人1000部免费视频 | 日日噜噜噜噜夜夜爽亚洲精品 | 天天摸天天透天天添 | 欧美xxxx黑人又粗又长 | 国产亚洲精品久久久久久国模美 | 伊人久久婷婷五月综合97色 | 国产精品香蕉在线观看 | 老头边吃奶边弄进去呻吟 | 亚洲精品中文字幕久久久久 | 国产农村妇女高潮大叫 | 97久久精品无码一区二区 | 亚洲热妇无码av在线播放 | 思思久久99热只有频精品66 | 久青草影院在线观看国产 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 水蜜桃av无码 | 婷婷色婷婷开心五月四房播播 | 亚洲日韩一区二区三区 | 成人精品一区二区三区中文字幕 | 无码人妻精品一区二区三区不卡 | 日本欧美一区二区三区乱码 | 亚洲国产欧美日韩精品一区二区三区 | 日韩人妻少妇一区二区三区 | 久久综合色之久久综合 | 国产精品怡红院永久免费 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 免费国产黄网站在线观看 | 成年女人永久免费看片 | 国产成人无码a区在线观看视频app | 一本大道久久东京热无码av | 日日碰狠狠丁香久燥 | 国产农村妇女高潮大叫 | 亚洲人交乣女bbw | 国産精品久久久久久久 | 成人毛片一区二区 | 国产偷自视频区视频 | 少妇的肉体aa片免费 | 老子影院午夜精品无码 | 亚洲国产成人av在线观看 | 无码国产色欲xxxxx视频 | 99er热精品视频 | 午夜不卡av免费 一本久久a久久精品vr综合 | 欧美老妇交乱视频在线观看 | 国产人妻精品一区二区三区不卡 | 国内精品人妻无码久久久影院蜜桃 | 国产午夜亚洲精品不卡下载 | 亚洲精品国产精品乱码不卡 | 麻豆蜜桃av蜜臀av色欲av | 天堂在线观看www | 双乳奶水饱满少妇呻吟 | 精品无码av一区二区三区 | www一区二区www免费 | 国产尤物精品视频 | 青春草在线视频免费观看 | 四虎国产精品免费久久 | 成人无码影片精品久久久 | 国产成人精品视频ⅴa片软件竹菊 | 婷婷五月综合缴情在线视频 | 国产欧美精品一区二区三区 | 理论片87福利理论电影 | 国产小呦泬泬99精品 | 久久国产精品二国产精品 | 国产精品无码久久av | 色婷婷香蕉在线一区二区 | 久久www免费人成人片 | 精品久久久久久亚洲精品 | 人妻无码久久精品人妻 | 国产成人亚洲综合无码 | 超碰97人人射妻 | 国产办公室秘书无码精品99 | 无码福利日韩神码福利片 | 欧美xxxx黑人又粗又长 | 99精品无人区乱码1区2区3区 | 国产人妻精品一区二区三区不卡 | 亚洲精品国产a久久久久久 | 欧美丰满少妇xxxx性 | 国产精品无码成人午夜电影 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 亚洲精品国产精品乱码视色 | 夜夜影院未满十八勿进 | 亚洲欧美国产精品专区久久 | 国产精品爱久久久久久久 | 久久99精品国产.久久久久 | 精品少妇爆乳无码av无码专区 | 精品成人av一区二区三区 | 中文字幕 人妻熟女 | 亚洲另类伦春色综合小说 | 国产成人久久精品流白浆 | 97久久国产亚洲精品超碰热 | 久久午夜无码鲁丝片 | 亚洲啪av永久无码精品放毛片 | 国产精品嫩草久久久久 | 国产无遮挡吃胸膜奶免费看 | 亚洲欧美日韩成人高清在线一区 | 两性色午夜免费视频 | 国产精品美女久久久久av爽李琼 | a国产一区二区免费入口 | 国产真人无遮挡作爱免费视频 | 一本无码人妻在中文字幕免费 | 任你躁在线精品免费 | 欧美自拍另类欧美综合图片区 | 中文精品无码中文字幕无码专区 | 精品一区二区三区无码免费视频 | 精品无码国产一区二区三区av | 特大黑人娇小亚洲女 | 人人爽人人澡人人人妻 | 久久久久se色偷偷亚洲精品av | 午夜丰满少妇性开放视频 | 久久精品国产99久久6动漫 | 久久国产精品精品国产色婷婷 | 强辱丰满人妻hd中文字幕 | 中国大陆精品视频xxxx | 欧美性生交xxxxx久久久 | 午夜精品久久久久久久 | 粉嫩少妇内射浓精videos | 在线视频网站www色 | 久久无码专区国产精品s | 久久99精品国产麻豆 | 久久久久国色av免费观看性色 | 成人免费视频在线观看 | 亚洲成a人片在线观看日本 | 久久人人爽人人人人片 | 精品熟女少妇av免费观看 | √8天堂资源地址中文在线 | 国产麻豆精品精东影业av网站 | 精品欧洲av无码一区二区三区 | 色诱久久久久综合网ywww | 欧美丰满熟妇xxxx性ppx人交 | 99久久久无码国产精品免费 | 久久国产精品精品国产色婷婷 | 未满小14洗澡无码视频网站 | 国产一区二区三区日韩精品 | 天海翼激烈高潮到腰振不止 | 亚洲色无码一区二区三区 | 国产真实乱对白精彩久久 | 国产一区二区三区四区五区加勒比 | 国产av久久久久精东av | 国产内射爽爽大片视频社区在线 | 亚洲人成网站色7799 | 永久免费观看国产裸体美女 | 亚洲一区二区三区四区 | 国产成人av免费观看 | 夜精品a片一区二区三区无码白浆 | 在线观看免费人成视频 | 精品国产国产综合精品 | 97无码免费人妻超级碰碰夜夜 | 香蕉久久久久久av成人 | 欧美日韩人成综合在线播放 | 亚洲精品中文字幕久久久久 | 国产成人综合色在线观看网站 | 自拍偷自拍亚洲精品10p | 免费无码一区二区三区蜜桃大 | 久久精品国产一区二区三区 | 丰满人妻一区二区三区免费视频 | 中文字幕日韩精品一区二区三区 | 天堂亚洲2017在线观看 | 久久99精品国产.久久久久 | 亚洲精品久久久久久一区二区 | 国产精品久久久久久亚洲影视内衣 | 精品一二三区久久aaa片 | 巨爆乳无码视频在线观看 | 国语自产偷拍精品视频偷 | 国产午夜亚洲精品不卡 | 免费视频欧美无人区码 | 欧美人妻一区二区三区 | 国产精品久久久久久久9999 | 乱中年女人伦av三区 | 免费观看黄网站 | 中文字幕 亚洲精品 第1页 | 激情国产av做激情国产爱 | 狠狠综合久久久久综合网 | 图片区 小说区 区 亚洲五月 | 无码乱肉视频免费大全合集 | 精品欧洲av无码一区二区三区 | 久久国语露脸国产精品电影 | 初尝人妻少妇中文字幕 | 国产9 9在线 | 中文 | 99riav国产精品视频 | 强奷人妻日本中文字幕 | 国产午夜亚洲精品不卡 | 国产sm调教视频在线观看 | 国产激情精品一区二区三区 | 欧美人与禽zoz0性伦交 | 波多野结衣av一区二区全免费观看 | 亚洲а∨天堂久久精品2021 | 欧美精品在线观看 | 国产午夜福利亚洲第一 | 99精品视频在线观看免费 | 欧美 丝袜 自拍 制服 另类 | 亚拍精品一区二区三区探花 | 国产精品多人p群无码 | 粉嫩少妇内射浓精videos | 国产精品亚洲а∨无码播放麻豆 | 老头边吃奶边弄进去呻吟 | 国产午夜精品一区二区三区嫩草 | 日本在线高清不卡免费播放 | 小泽玛莉亚一区二区视频在线 | 亚拍精品一区二区三区探花 | 成熟人妻av无码专区 | 东京热无码av男人的天堂 | 小泽玛莉亚一区二区视频在线 | 国产午夜手机精彩视频 | 日本va欧美va欧美va精品 | 在线视频网站www色 | 中文字幕无线码免费人妻 | 亚洲综合无码久久精品综合 | 国产在线aaa片一区二区99 | 窝窝午夜理论片影院 | 久久久久亚洲精品男人的天堂 | 高潮毛片无遮挡高清免费视频 | 成人一在线视频日韩国产 | 亚洲精品一区三区三区在线观看 | 国产精品福利视频导航 | 亚洲精品中文字幕乱码 | 国产色精品久久人妻 | 樱花草在线播放免费中文 | 久久久国产一区二区三区 | 色婷婷香蕉在线一区二区 | 国产在线aaa片一区二区99 | 成人无码精品1区2区3区免费看 | 久久国产精品精品国产色婷婷 | aa片在线观看视频在线播放 | 国精产品一品二品国精品69xx | 午夜时刻免费入口 | 欧美成人高清在线播放 | 大地资源中文第3页 | 无码精品国产va在线观看dvd | 欧美性猛交内射兽交老熟妇 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 蜜桃臀无码内射一区二区三区 | 99久久婷婷国产综合精品青草免费 | 无码精品国产va在线观看dvd | 国产精品资源一区二区 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 久久亚洲精品成人无码 | 国产成人无码区免费内射一片色欲 | 久久亚洲中文字幕无码 | 国语自产偷拍精品视频偷 | 亚洲另类伦春色综合小说 | 一个人免费观看的www视频 | 精品无人国产偷自产在线 | 福利一区二区三区视频在线观看 | 欧美人与善在线com | 中文字幕av日韩精品一区二区 | 国产亚av手机在线观看 | 在线看片无码永久免费视频 | 巨爆乳无码视频在线观看 | 久久五月精品中文字幕 | 色综合久久久久综合一本到桃花网 | 蜜桃视频韩日免费播放 | 国产熟妇高潮叫床视频播放 | 国产sm调教视频在线观看 | 国产精品无码一区二区桃花视频 | 色窝窝无码一区二区三区色欲 | 国产精品鲁鲁鲁 | 老熟女重囗味hdxx69 | 国产成人一区二区三区别 | 亚洲阿v天堂在线 | 九九久久精品国产免费看小说 | 精品久久综合1区2区3区激情 | 成在人线av无码免观看麻豆 | 女人被男人躁得好爽免费视频 | av无码不卡在线观看免费 | 午夜免费福利小电影 | 帮老师解开蕾丝奶罩吸乳网站 | 蜜桃视频插满18在线观看 | 色狠狠av一区二区三区 | 亚洲乱码国产乱码精品精 | 自拍偷自拍亚洲精品10p | 小泽玛莉亚一区二区视频在线 | 亚洲中文字幕乱码av波多ji | 日韩精品无码一本二本三本色 | 久久久精品国产sm最大网站 | 亚洲综合另类小说色区 | 波多野结衣乳巨码无在线观看 | 久久久久久久人妻无码中文字幕爆 | 亚洲人亚洲人成电影网站色 | 国产手机在线αⅴ片无码观看 | 国产成人无码av一区二区 | 国产极品视觉盛宴 | 免费国产成人高清在线观看网站 | 日产精品高潮呻吟av久久 | 人人妻人人澡人人爽精品欧美 | 东京一本一道一二三区 | av小次郎收藏 | 强开小婷嫩苞又嫩又紧视频 | 国产亚洲精品久久久久久久久动漫 | 麻豆av传媒蜜桃天美传媒 | 影音先锋中文字幕无码 | 欧美老妇交乱视频在线观看 | 玩弄中年熟妇正在播放 | 在线а√天堂中文官网 | 成年美女黄网站色大免费视频 | 一本一道久久综合久久 | 偷窥村妇洗澡毛毛多 | 天堂久久天堂av色综合 | 十八禁真人啪啪免费网站 | 国产九九九九九九九a片 | 婷婷色婷婷开心五月四房播播 | 一本大道久久东京热无码av | 黑人大群体交免费视频 | 国产麻豆精品精东影业av网站 | 国产亚洲精品久久久久久 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 一本一道久久综合久久 | 狠狠cao日日穞夜夜穞av | 精品国产麻豆免费人成网站 | 日韩人妻少妇一区二区三区 | 国产成人精品一区二区在线小狼 | 亚洲欧美日韩成人高清在线一区 | 国产一区二区三区日韩精品 | 搡女人真爽免费视频大全 | 久久这里只有精品视频9 | 1000部夫妻午夜免费 | 国产亚洲欧美在线专区 | 精品一区二区三区无码免费视频 | 亚洲精品国产a久久久久久 | 精品无码国产一区二区三区av | 黑人玩弄人妻中文在线 | 久久久久久a亚洲欧洲av冫 | 西西人体www44rt大胆高清 | 亚洲日韩av一区二区三区中文 | 俺去俺来也在线www色官网 | 成人精品视频一区二区 | 久久无码中文字幕免费影院蜜桃 | 一个人看的视频www在线 | 天下第一社区视频www日本 | 久久aⅴ免费观看 | 亚洲人成影院在线观看 | 中文字幕色婷婷在线视频 | 99久久99久久免费精品蜜桃 | 亚洲爆乳精品无码一区二区三区 | 国产在线无码精品电影网 | 久久精品人人做人人综合 | 亚洲精品国产品国语在线观看 | 久久久久av无码免费网 | 欧美丰满老熟妇xxxxx性 | 99久久亚洲精品无码毛片 | 国产无遮挡又黄又爽又色 | 正在播放东北夫妻内射 | 日本一区二区三区免费高清 | 日本一区二区三区免费播放 | 精品少妇爆乳无码av无码专区 | 久久伊人色av天堂九九小黄鸭 | 麻豆国产丝袜白领秘书在线观看 | 激情国产av做激情国产爱 | 国产精品久久久久久亚洲影视内衣 | 亚洲中文字幕无码中文字在线 | 中文精品久久久久人妻不卡 | 午夜福利不卡在线视频 | 乱人伦中文视频在线观看 | 亚洲の无码国产の无码影院 | 老司机亚洲精品影院 | 搡女人真爽免费视频大全 | 久久人人爽人人爽人人片ⅴ | 捆绑白丝粉色jk震动捧喷白浆 | 国产亚洲精品久久久久久久 | 亚洲日韩精品欧美一区二区 | 红桃av一区二区三区在线无码av | 曰韩无码二三区中文字幕 | 精品国产一区二区三区四区 | 老太婆性杂交欧美肥老太 | 88国产精品欧美一区二区三区 | 日产精品高潮呻吟av久久 | 国产精品美女久久久 | 东京无码熟妇人妻av在线网址 | 奇米影视7777久久精品 | 午夜福利电影 | 国产精华av午夜在线观看 | 国产在线一区二区三区四区五区 | 久久99精品久久久久婷婷 | 蜜臀av无码人妻精品 | 免费人成在线视频无码 | 人妻互换免费中文字幕 | 日本精品高清一区二区 | 又大又硬又爽免费视频 | 亚洲国产一区二区三区在线观看 | 成人一区二区免费视频 | 国产av无码专区亚洲a∨毛片 | 图片区 小说区 区 亚洲五月 | 亚洲男人av香蕉爽爽爽爽 | 日日碰狠狠躁久久躁蜜桃 | 国产精品久久久久影院嫩草 | 亚洲色无码一区二区三区 | 人人澡人人透人人爽 | 少妇一晚三次一区二区三区 | 国产艳妇av在线观看果冻传媒 | 99久久精品国产一区二区蜜芽 | 欧美 日韩 亚洲 在线 | 国产偷自视频区视频 | 高清不卡一区二区三区 | 欧美 亚洲 国产 另类 | 日本xxxx色视频在线观看免费 | 亚洲狠狠色丁香婷婷综合 | 女人被男人躁得好爽免费视频 | 国产精品va在线观看无码 | 国产精品亚洲а∨无码播放麻豆 | 亚洲乱码国产乱码精品精 | 青青久在线视频免费观看 | 成年美女黄网站色大免费全看 | 亚洲综合精品香蕉久久网 | 国产亚洲精品久久久久久国模美 | 国产精品自产拍在线观看 | 永久黄网站色视频免费直播 | 精品国产一区av天美传媒 | 亚洲一区二区三区在线观看网站 | 国产成人无码av在线影院 | 国产九九九九九九九a片 | 极品尤物被啪到呻吟喷水 | 特大黑人娇小亚洲女 | 久久www免费人成人片 | 亚洲熟熟妇xxxx | 精品久久久久久亚洲精品 | 国产香蕉尹人视频在线 | 婷婷丁香五月天综合东京热 | 一本久久伊人热热精品中文字幕 | 国产精品二区一区二区aⅴ污介绍 | 国产亚洲欧美在线专区 | 熟女体下毛毛黑森林 | 国产乱子伦视频在线播放 | 97精品人妻一区二区三区香蕉 | 日韩欧美成人免费观看 | 88国产精品欧美一区二区三区 | 日韩av无码一区二区三区 | 人妻体内射精一区二区三四 | 亚洲经典千人经典日产 | 国产熟妇高潮叫床视频播放 | 麻豆蜜桃av蜜臀av色欲av | 少妇激情av一区二区 | 成人亚洲精品久久久久软件 | 久久久久99精品国产片 | 日韩少妇白浆无码系列 | 国产凸凹视频一区二区 | 国产亚洲视频中文字幕97精品 | 亚洲精品美女久久久久久久 | 男人的天堂av网站 | 人妻少妇被猛烈进入中文字幕 | 成年美女黄网站色大免费全看 | 国产在线无码精品电影网 | 亚洲va欧美va天堂v国产综合 | 又大又紧又粉嫩18p少妇 | 麻豆国产人妻欲求不满谁演的 | 国产亚洲精品精品国产亚洲综合 | 成人性做爰aaa片免费看 | 四虎永久在线精品免费网址 | 国产艳妇av在线观看果冻传媒 | 日本一本二本三区免费 | 国产亚洲精品久久久久久 | 日本一区二区更新不卡 | 久久无码专区国产精品s | 亲嘴扒胸摸屁股激烈网站 | av香港经典三级级 在线 | 亚洲狠狠色丁香婷婷综合 | 激情综合激情五月俺也去 | 国产成人久久精品流白浆 | 牲欲强的熟妇农村老妇女视频 | 四虎影视成人永久免费观看视频 | 无码人妻久久一区二区三区不卡 | 在线观看国产午夜福利片 | 麻豆精品国产精华精华液好用吗 | 少妇愉情理伦片bd | 色一情一乱一伦 | 无码人妻丰满熟妇区五十路百度 | 中文久久乱码一区二区 | 精品人妻人人做人人爽夜夜爽 | 99久久婷婷国产综合精品青草免费 | 亚洲aⅴ无码成人网站国产app | 乌克兰少妇性做爰 | 暴力强奷在线播放无码 | 久久久久人妻一区精品色欧美 | 午夜男女很黄的视频 | 亚洲中文字幕无码一久久区 | 无码人妻精品一区二区三区不卡 | 成人性做爰aaa片免费看不忠 | 精品国产青草久久久久福利 | 俺去俺来也在线www色官网 | 99久久久无码国产aaa精品 | 天天av天天av天天透 | 亚洲精品无码人妻无码 | 人人澡人摸人人添 | 亚洲国产精品久久久久久 | 一本久久a久久精品vr综合 | 特级做a爰片毛片免费69 | 国产在线一区二区三区四区五区 | 黑人巨大精品欧美一区二区 | 中文字幕无码av波多野吉衣 | 亚洲精品成人av在线 | 激情五月综合色婷婷一区二区 | 国产亚洲欧美日韩亚洲中文色 | 欧美老妇交乱视频在线观看 | 性做久久久久久久久 | 99久久99久久免费精品蜜桃 | а√资源新版在线天堂 | 国产精品无码久久av | 76少妇精品导航 | 99久久久国产精品无码免费 | 欧美三级不卡在线观看 | 国产激情无码一区二区app | 国产真人无遮挡作爱免费视频 | 六月丁香婷婷色狠狠久久 | 99久久人妻精品免费二区 | 精品熟女少妇av免费观看 | 欧美三级a做爰在线观看 | 日本精品高清一区二区 | 国产综合久久久久鬼色 | 日本熟妇人妻xxxxx人hd | 国产午夜亚洲精品不卡下载 | 最新国产乱人伦偷精品免费网站 | 久久亚洲精品成人无码 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 中文字幕无码av波多野吉衣 | 熟女少妇在线视频播放 | 国产熟妇另类久久久久 | 精品乱子伦一区二区三区 | 午夜精品久久久久久久久 | 天堂一区人妻无码 | 丰满诱人的人妻3 | 国产成人无码午夜视频在线观看 | 国产高清av在线播放 | 波多野结衣av一区二区全免费观看 | 国产精品a成v人在线播放 | 中文精品无码中文字幕无码专区 | 国产精品久久久久久久9999 | 中文字幕人妻无码一区二区三区 | 久久国产劲爆∧v内射 | 99国产精品白浆在线观看免费 | 亚洲国产av精品一区二区蜜芽 | 欧洲欧美人成视频在线 | 人妻有码中文字幕在线 | 精品久久久久久人妻无码中文字幕 | 亚洲人成网站免费播放 | 国产又粗又硬又大爽黄老大爷视 | 欧美xxxx黑人又粗又长 | 免费乱码人妻系列无码专区 | 亚洲精品久久久久中文第一幕 | 成人试看120秒体验区 | 日本爽爽爽爽爽爽在线观看免 | 男女猛烈xx00免费视频试看 | 免费国产成人高清在线观看网站 | 一二三四社区在线中文视频 | 蜜桃视频韩日免费播放 | 国产麻豆精品一区二区三区v视界 | 久久久精品国产sm最大网站 | 欧美亚洲国产一区二区三区 | 久久久精品456亚洲影院 | 玩弄中年熟妇正在播放 | 国产亚洲tv在线观看 | 兔费看少妇性l交大片免费 | 青青久在线视频免费观看 | 一二三四在线观看免费视频 | 国精产品一品二品国精品69xx | 国产精品爱久久久久久久 | 久久久久人妻一区精品色欧美 | 性生交大片免费看女人按摩摩 | 日产精品99久久久久久 | 国产sm调教视频在线观看 | 色欲人妻aaaaaaa无码 | 麻豆精品国产精华精华液好用吗 | 精品国偷自产在线 | 18精品久久久无码午夜福利 | 精品无码国产一区二区三区av | 国产午夜福利亚洲第一 | 亚洲の无码国产の无码步美 | 亚洲色偷偷男人的天堂 | 久久精品中文闷骚内射 | 国产又爽又猛又粗的视频a片 | 超碰97人人射妻 | 亚洲 日韩 欧美 成人 在线观看 | 国产精品成人av在线观看 | 日韩精品无码一本二本三本色 | 青草青草久热国产精品 | 麻豆md0077饥渴少妇 | 特黄特色大片免费播放器图片 | 国产成人午夜福利在线播放 | 国产成人无码av一区二区 | 国产精品99久久精品爆乳 | 亚洲 激情 小说 另类 欧美 | 国产成人综合美国十次 | 精品一二三区久久aaa片 | 国产人妻久久精品二区三区老狼 | 日本www一道久久久免费榴莲 | 亚洲成av人片在线观看无码不卡 | 国产亚洲欧美日韩亚洲中文色 | 一本色道久久综合亚洲精品不卡 | 成 人 网 站国产免费观看 | 亚洲日韩乱码中文无码蜜桃臀网站 | 日本乱偷人妻中文字幕 | 无码av免费一区二区三区试看 | 国产成人无码av在线影院 | 性色欲情网站iwww九文堂 | 色偷偷人人澡人人爽人人模 | 俄罗斯老熟妇色xxxx | 男女猛烈xx00免费视频试看 | 噜噜噜亚洲色成人网站 | 亚洲综合无码久久精品综合 | 无码国模国产在线观看 | 精品久久久久久亚洲精品 | 久久97精品久久久久久久不卡 | 亚洲日本va中文字幕 | 一区二区传媒有限公司 | 日韩精品一区二区av在线 | 野外少妇愉情中文字幕 | 亚洲成在人网站无码天堂 | 亚洲精品国偷拍自产在线麻豆 | 一区二区三区乱码在线 | 欧洲 | 思思久久99热只有频精品66 | 国产亚洲美女精品久久久2020 | 在线a亚洲视频播放在线观看 | 日日鲁鲁鲁夜夜爽爽狠狠 | 国产欧美熟妇另类久久久 | 无人区乱码一区二区三区 | 欧美老人巨大xxxx做受 | 18无码粉嫩小泬无套在线观看 | 色婷婷av一区二区三区之红樱桃 | 日韩欧美群交p片內射中文 | 一二三四在线观看免费视频 | 麻豆精品国产精华精华液好用吗 | 国产成人无码区免费内射一片色欲 | 亚洲国产精品无码一区二区三区 | 精品国产一区二区三区四区 | 久久人妻内射无码一区三区 | 18无码粉嫩小泬无套在线观看 | 色老头在线一区二区三区 | 国产精品高潮呻吟av久久4虎 | 欧洲极品少妇 | 奇米影视7777久久精品 | 中文字幕乱妇无码av在线 | 扒开双腿疯狂进出爽爽爽视频 | 色婷婷av一区二区三区之红樱桃 | 国产婷婷色一区二区三区在线 | 亚洲a无码综合a国产av中文 | 亚洲精品午夜国产va久久成人 | 精品一区二区不卡无码av | 无码精品人妻一区二区三区av | 一本精品99久久精品77 | 久久综合九色综合欧美狠狠 | 熟妇人妻中文av无码 | 精品国产一区二区三区av 性色 | 久久精品无码一区二区三区 | 九九热爱视频精品 | 国产无套粉嫩白浆在线 | 亚洲国产精品毛片av不卡在线 | 一个人免费观看的www视频 | 中文字幕av伊人av无码av | 亚洲国产av美女网站 | 国产av一区二区三区最新精品 | 久久久久99精品国产片 | 中文无码成人免费视频在线观看 | 中文精品无码中文字幕无码专区 | 色婷婷久久一区二区三区麻豆 | 18精品久久久无码午夜福利 | 无套内射视频囯产 | 亚洲国产av精品一区二区蜜芽 | 天堂亚洲2017在线观看 | 亚洲小说春色综合另类 | 99久久婷婷国产综合精品青草免费 | 色五月丁香五月综合五月 | 色婷婷综合中文久久一本 | 99麻豆久久久国产精品免费 | 老熟妇仑乱视频一区二区 | 精品 日韩 国产 欧美 视频 | 久久久久久亚洲精品a片成人 | 国产人妻久久精品二区三区老狼 | 国内精品人妻无码久久久影院 | 国产热a欧美热a在线视频 | 日韩 欧美 动漫 国产 制服 | 欧美日韩综合一区二区三区 | 国产精品香蕉在线观看 | 国内精品人妻无码久久久影院 | 国产成人综合在线女婷五月99播放 | 国产精品成人av在线观看 | 成人aaa片一区国产精品 | 亚洲欧美色中文字幕在线 | 人妻人人添人妻人人爱 | 性啪啪chinese东北女人 | a国产一区二区免费入口 | 国产69精品久久久久app下载 | 欧美黑人巨大xxxxx | 欧美人与禽zoz0性伦交 | 夫妻免费无码v看片 | 久久综合激激的五月天 | 国产艳妇av在线观看果冻传媒 | 亚洲成a人片在线观看日本 | 国产精品亚洲lv粉色 | 亚洲の无码国产の无码步美 | 日韩精品无码一本二本三本色 | 少妇无套内谢久久久久 | 无码av免费一区二区三区试看 | 国内揄拍国内精品少妇国语 | 成人无码视频在线观看网站 | 久久国产自偷自偷免费一区调 | 丰满人妻翻云覆雨呻吟视频 | 亚洲精品一区二区三区在线观看 | 国产免费久久精品国产传媒 | 国产激情艳情在线看视频 | 男人扒开女人内裤强吻桶进去 | 国产无遮挡吃胸膜奶免费看 | 午夜时刻免费入口 | 7777奇米四色成人眼影 | 欧美怡红院免费全部视频 | 亚洲国产一区二区三区在线观看 | 人人爽人人澡人人高潮 | 午夜福利不卡在线视频 | a在线观看免费网站大全 | 激情亚洲一区国产精品 | 欧洲熟妇色 欧美 | 亚拍精品一区二区三区探花 | 亚洲中文字幕无码中字 | 初尝人妻少妇中文字幕 | 波多野结衣乳巨码无在线观看 | 免费人成网站视频在线观看 | 男人和女人高潮免费网站 | 色窝窝无码一区二区三区色欲 | 久久久久av无码免费网 | 国产高清av在线播放 | 真人与拘做受免费视频一 | 亚洲国产一区二区三区在线观看 | 成 人 网 站国产免费观看 | 日本肉体xxxx裸交 | 亚洲人成网站在线播放942 | 中国女人内谢69xxxx | 精品无码国产自产拍在线观看蜜 | 蜜桃视频插满18在线观看 | 夜精品a片一区二区三区无码白浆 | 午夜嘿嘿嘿影院 | 人妻插b视频一区二区三区 | 国产亲子乱弄免费视频 | 亚洲精品久久久久久一区二区 | 天天躁夜夜躁狠狠是什么心态 | 亚洲gv猛男gv无码男同 | 人人妻人人澡人人爽欧美精品 | 国产69精品久久久久app下载 | 国产欧美熟妇另类久久久 | 国内精品久久毛片一区二区 | 国产亚洲视频中文字幕97精品 | 免费无码的av片在线观看 | 久久人人97超碰a片精品 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 人人妻人人澡人人爽人人精品 | 国产在线精品一区二区高清不卡 | 性欧美大战久久久久久久 | 成人无码视频免费播放 | 亚洲爆乳精品无码一区二区三区 | 中文字幕无码日韩专区 | 免费中文字幕日韩欧美 | 99久久久国产精品无码免费 | 中文字幕乱码中文乱码51精品 | 亚洲人成网站免费播放 | 丁香花在线影院观看在线播放 | 无遮无挡爽爽免费视频 | 国产精品久久精品三级 | 精品久久久久久人妻无码中文字幕 | 丝袜足控一区二区三区 | 自拍偷自拍亚洲精品10p | 国产av无码专区亚洲awww | 国产精品久久久久影院嫩草 | 日韩精品一区二区av在线 | 天干天干啦夜天干天2017 | 国产成人综合美国十次 | 国产情侣作爱视频免费观看 | 一本色道婷婷久久欧美 | 特黄特色大片免费播放器图片 | 亚洲成av人影院在线观看 | 人妻少妇精品视频专区 | 97久久精品无码一区二区 | 亚洲综合伊人久久大杳蕉 | 久久这里只有精品视频9 | 日韩人妻少妇一区二区三区 | 中文字幕人妻丝袜二区 | 欧美国产亚洲日韩在线二区 | 丰满少妇高潮惨叫视频 | 无码成人精品区在线观看 | 国产 浪潮av性色四虎 | 亚洲小说春色综合另类 | 天堂久久天堂av色综合 | 无码国内精品人妻少妇 | 久久久精品国产sm最大网站 | 亚洲色欲色欲天天天www | 岛国片人妻三上悠亚 | 正在播放东北夫妻内射 | 色一情一乱一伦 | 午夜肉伦伦影院 | 国产成人精品视频ⅴa片软件竹菊 | 动漫av网站免费观看 | 亚洲精品成a人在线观看 | 国产av剧情md精品麻豆 | 亚洲一区二区三区在线观看网站 | 亚洲精品一区二区三区大桥未久 | 免费观看的无遮挡av | 99视频精品全部免费免费观看 | 免费人成在线观看网站 | 免费观看的无遮挡av | 日本一卡2卡3卡四卡精品网站 | 成人性做爰aaa片免费看不忠 | 国产精品久久国产三级国 | 国产真实夫妇视频 | 18禁止看的免费污网站 | 成 人 网 站国产免费观看 | 永久免费精品精品永久-夜色 | 国产 浪潮av性色四虎 | 国产亚洲视频中文字幕97精品 | 久久久久久久久蜜桃 | 无码帝国www无码专区色综合 | 亚洲精品国偷拍自产在线观看蜜桃 | 久久无码人妻影院 | 国产精品资源一区二区 | 99久久人妻精品免费二区 | 一本久久a久久精品亚洲 | 在线观看免费人成视频 | 久久99精品久久久久久动态图 | 久久久久久a亚洲欧洲av冫 | 中文毛片无遮挡高清免费 | 久久久久久av无码免费看大片 | 97色伦图片97综合影院 | 性生交大片免费看l | 中国大陆精品视频xxxx | 欧美精品免费观看二区 | 国产激情精品一区二区三区 | 免费观看的无遮挡av | 2019nv天堂香蕉在线观看 | 最近的中文字幕在线看视频 | 亚洲天堂2017无码中文 | 国产av一区二区三区最新精品 | 欧美日韩人成综合在线播放 | 国产无套粉嫩白浆在线 | 一二三四在线观看免费视频 | 日本va欧美va欧美va精品 | 国产精品va在线播放 | 久久久久久亚洲精品a片成人 | 无码国产乱人伦偷精品视频 | 99久久久国产精品无码免费 | 久久国内精品自在自线 | 国产精品人妻一区二区三区四 | 亚洲国产精品久久久天堂 | 麻花豆传媒剧国产免费mv在线 | 久久久久亚洲精品男人的天堂 | av无码电影一区二区三区 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 麻豆国产人妻欲求不满 | 无码人妻久久一区二区三区不卡 | 麻豆精品国产精华精华液好用吗 | 夜精品a片一区二区三区无码白浆 | 少妇厨房愉情理9仑片视频 | 亚洲中文字幕久久无码 | 亚洲成av人影院在线观看 | 久久久久免费精品国产 | 日本精品少妇一区二区三区 | 亚洲一区二区三区偷拍女厕 | 亚洲精品国产第一综合99久久 | 在线精品亚洲一区二区 | 蜜桃无码一区二区三区 | 乱人伦中文视频在线观看 | 成人欧美一区二区三区黑人 | 成人片黄网站色大片免费观看 | 最新国产麻豆aⅴ精品无码 | 内射老妇bbwx0c0ck | 国产亚洲欧美日韩亚洲中文色 | 漂亮人妻洗澡被公强 日日躁 | 熟妇激情内射com | 亚洲欧美中文字幕5发布 | 久久精品无码一区二区三区 | 天天摸天天透天天添 | 国产乱人偷精品人妻a片 | 久久久久久a亚洲欧洲av冫 | 又湿又紧又大又爽a视频国产 | 青草视频在线播放 | 女人被男人爽到呻吟的视频 | 国产精品理论片在线观看 | √8天堂资源地址中文在线 | 一本色道久久综合亚洲精品不卡 | 日本丰满熟妇videos | 我要看www免费看插插视频 | 狠狠亚洲超碰狼人久久 | 少妇被黑人到高潮喷出白浆 | 午夜丰满少妇性开放视频 | 精品久久综合1区2区3区激情 | 欧美日韩一区二区综合 | 日本精品久久久久中文字幕 | 学生妹亚洲一区二区 | 国产欧美精品一区二区三区 | 性生交大片免费看l | 大地资源网第二页免费观看 | 麻豆国产人妻欲求不满 | 亚洲s色大片在线观看 | 久久人人爽人人爽人人片av高清 | 麻豆果冻传媒2021精品传媒一区下载 | 东京热一精品无码av | 自拍偷自拍亚洲精品被多人伦好爽 | 亚洲 激情 小说 另类 欧美 | 捆绑白丝粉色jk震动捧喷白浆 | 无码国产激情在线观看 | 亚洲日本一区二区三区在线 | 最新国产麻豆aⅴ精品无码 | 日本又色又爽又黄的a片18禁 | 亚洲精品一区三区三区在线观看 | 55夜色66夜色国产精品视频 | 在线观看国产一区二区三区 | 99久久婷婷国产综合精品青草免费 | 日本熟妇浓毛 | 国产人妖乱国产精品人妖 | 亚无码乱人伦一区二区 | 欧美老妇与禽交 | 欧美人与动性行为视频 | 日日碰狠狠躁久久躁蜜桃 | 在线а√天堂中文官网 | 风流少妇按摩来高潮 | 国产午夜亚洲精品不卡下载 | 任你躁国产自任一区二区三区 | 日本肉体xxxx裸交 | 久久久精品456亚洲影院 | 国产亚洲精品久久久久久国模美 | 久久久久久av无码免费看大片 | 国产成人无码a区在线观看视频app | 亚洲精品一区二区三区在线 | 日韩精品无码免费一区二区三区 | 无码人妻出轨黑人中文字幕 | 午夜福利一区二区三区在线观看 | 国产 精品 自在自线 | 成人免费视频在线观看 | 精品少妇爆乳无码av无码专区 | v一区无码内射国产 | 美女黄网站人色视频免费国产 | 国产网红无码精品视频 | 日本熟妇乱子伦xxxx | 东京热一精品无码av | 女人和拘做爰正片视频 | 中文字幕无码av激情不卡 | 国产成人无码区免费内射一片色欲 | 性生交片免费无码看人 | 日本xxxx色视频在线观看免费 | 亚洲精品国偷拍自产在线观看蜜桃 | 亚洲一区二区三区 | 久激情内射婷内射蜜桃人妖 | 日韩精品成人一区二区三区 | 正在播放老肥熟妇露脸 | 日本一卡二卡不卡视频查询 | 亚洲色大成网站www | 精品日本一区二区三区在线观看 | 2019nv天堂香蕉在线观看 | 亚洲一区二区三区在线观看网站 | 日本高清一区免费中文视频 | 欧美老妇与禽交 | 国产无遮挡吃胸膜奶免费看 | 国产偷国产偷精品高清尤物 | 亚洲欧洲日本综合aⅴ在线 | 国产高清av在线播放 | 精品欧洲av无码一区二区三区 | 狠狠色丁香久久婷婷综合五月 | 成熟人妻av无码专区 | 成人欧美一区二区三区黑人免费 | www一区二区www免费 | 无码精品国产va在线观看dvd | 99久久精品无码一区二区毛片 | 国産精品久久久久久久 | 亚洲乱亚洲乱妇50p | 亚洲综合在线一区二区三区 | 成人试看120秒体验区 | 成熟女人特级毛片www免费 | 亚洲国产一区二区三区在线观看 | 日本欧美一区二区三区乱码 | 国内少妇偷人精品视频 | 国产精品国产自线拍免费软件 | 激情内射日本一区二区三区 | 国产成人精品一区二区在线小狼 | 国产精品第一国产精品 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 一本色道久久综合亚洲精品不卡 | 熟妇人妻中文av无码 | 国产午夜精品一区二区三区嫩草 | 亚洲の无码国产の无码步美 | 中文字幕无码av激情不卡 | 特级做a爰片毛片免费69 | 人妻中文无码久热丝袜 | 久久久中文久久久无码 | 俄罗斯老熟妇色xxxx | 色窝窝无码一区二区三区色欲 | 亚洲一区二区三区香蕉 | 亚洲中文字幕无码中文字在线 | 2020久久超碰国产精品最新 | 日日摸夜夜摸狠狠摸婷婷 | 欧美自拍另类欧美综合图片区 | 中文字幕久久久久人妻 | 377p欧洲日本亚洲大胆 | 99久久久无码国产aaa精品 | 东京热无码av男人的天堂 | 色一情一乱一伦一区二区三欧美 | 少妇一晚三次一区二区三区 | a片免费视频在线观看 | 日本一本二本三区免费 | 精品日本一区二区三区在线观看 | 无码午夜成人1000部免费视频 | 国产成人无码午夜视频在线观看 | 天天爽夜夜爽夜夜爽 | 欧美刺激性大交 | 日本精品人妻无码免费大全 | 国产人妻人伦精品1国产丝袜 | 无码av中文字幕免费放 | 亚洲精品一区二区三区在线 | 国产国产精品人在线视 | 免费无码午夜福利片69 | 国产精品久久国产三级国 | аⅴ资源天堂资源库在线 | 精品无码国产一区二区三区av | 亚洲中文字幕乱码av波多ji | 中文精品久久久久人妻不卡 | 国产亲子乱弄免费视频 | 亚洲成a人片在线观看无码 | 成人一在线视频日韩国产 | 国产综合在线观看 | 国语自产偷拍精品视频偷 | 无码福利日韩神码福利片 | yw尤物av无码国产在线观看 | 久久久久国色av免费观看性色 | 久久97精品久久久久久久不卡 | 又大又硬又爽免费视频 | 无遮挡国产高潮视频免费观看 | 久久综合色之久久综合 | 亚洲精品一区二区三区婷婷月 | 51国偷自产一区二区三区 | 亚洲成a人片在线观看无码3d | 熟妇人妻激情偷爽文 | 欧美人与禽zoz0性伦交 | 人妻无码αv中文字幕久久琪琪布 | 久久久久亚洲精品男人的天堂 | 欧美大屁股xxxxhd黑色 | 国产精品美女久久久网av | 久久无码人妻影院 | 成人免费视频一区二区 | 无码国产激情在线观看 | 国产日产欧产精品精品app | 狂野欧美性猛xxxx乱大交 | а√天堂www在线天堂小说 | 大乳丰满人妻中文字幕日本 | 俺去俺来也www色官网 | 国产区女主播在线观看 | 精品人妻人人做人人爽 | 国产激情精品一区二区三区 | 亚洲熟妇自偷自拍另类 | 久久无码人妻影院 | 亚洲国产精品一区二区美利坚 | 国产极品视觉盛宴 | 少妇无码吹潮 | 水蜜桃av无码 | 久久精品国产大片免费观看 | 中文字幕日产无线码一区 | 天天摸天天碰天天添 | 大肉大捧一进一出好爽视频 | 精品国产精品久久一区免费式 | 午夜精品久久久内射近拍高清 | 免费无码午夜福利片69 | 亚洲の无码国产の无码步美 | 国产精品va在线观看无码 | 日本护士毛茸茸高潮 | 精品久久久久久亚洲精品 | 国产一区二区三区四区五区加勒比 | 日日天干夜夜狠狠爱 | 人妻少妇精品无码专区动漫 | 成 人影片 免费观看 | 欧美freesex黑人又粗又大 | 3d动漫精品啪啪一区二区中 | 久久综合给久久狠狠97色 | 国产明星裸体无码xxxx视频 | 天堂а√在线地址中文在线 | 俺去俺来也在线www色官网 | a国产一区二区免费入口 | 成人影院yy111111在线观看 | 欧美xxxx黑人又粗又长 | 国产精品美女久久久网av | 色综合天天综合狠狠爱 | 免费播放一区二区三区 | 欧美性猛交xxxx富婆 | 粉嫩少妇内射浓精videos | 久久久久久亚洲精品a片成人 | 国产情侣作爱视频免费观看 | 狠狠躁日日躁夜夜躁2020 | 中文无码成人免费视频在线观看 | 国产人妻大战黑人第1集 | 亚洲一区二区三区国产精华液 | 牲欲强的熟妇农村老妇女 | 一本久道久久综合婷婷五月 | 亚洲中文字幕va福利 | 成人无码视频在线观看网站 | 久久精品国产99精品亚洲 | 国产人妻久久精品二区三区老狼 | 久久99精品国产.久久久久 | 97久久超碰中文字幕 | 真人与拘做受免费视频一 | 未满成年国产在线观看 | 欧美丰满老熟妇xxxxx性 | 正在播放东北夫妻内射 | 少妇人妻av毛片在线看 | 精品久久综合1区2区3区激情 | 爱做久久久久久 | 亚洲国产一区二区三区在线观看 | 久久久av男人的天堂 | 成人精品视频一区二区 | 在教室伦流澡到高潮hnp视频 | 88国产精品欧美一区二区三区 | 无码人妻少妇伦在线电影 | 久久视频在线观看精品 | 亚洲人成网站在线播放942 | 少妇无码一区二区二三区 | 99国产精品白浆在线观看免费 | av在线亚洲欧洲日产一区二区 | 国产香蕉97碰碰久久人人 | 亚洲中文字幕成人无码 | 丁香啪啪综合成人亚洲 | 精品人妻av区 | 精品国偷自产在线视频 | 亚洲成a人一区二区三区 | 久久无码人妻影院 | 亚洲区欧美区综合区自拍区 | 国产艳妇av在线观看果冻传媒 | 性色欲网站人妻丰满中文久久不卡 | 波多野42部无码喷潮在线 | 免费国产成人高清在线观看网站 | 无码一区二区三区在线观看 | 久久国产精品偷任你爽任你 | 国产精品毛片一区二区 | 夜精品a片一区二区三区无码白浆 | 亚洲一区二区三区 | 欧美日韩一区二区三区自拍 | 久久人人97超碰a片精品 | 嫩b人妻精品一区二区三区 | 国内精品一区二区三区不卡 | 黑人粗大猛烈进出高潮视频 | 荫蒂添的好舒服视频囗交 | 人人妻人人澡人人爽精品欧美 | 国产片av国语在线观看 | 国产绳艺sm调教室论坛 | 成人aaa片一区国产精品 | ass日本丰满熟妇pics | 免费国产黄网站在线观看 | 亚洲国产高清在线观看视频 | 黑森林福利视频导航 | 中文字幕人妻无码一夲道 | 日产精品高潮呻吟av久久 | 蜜臀aⅴ国产精品久久久国产老师 | 欧美乱妇无乱码大黄a片 | 老司机亚洲精品影院 | 无码播放一区二区三区 | 一个人看的视频www在线 | 天堂在线观看www | 2020久久香蕉国产线看观看 | 成人三级无码视频在线观看 | 久久精品中文闷骚内射 | 国产成人一区二区三区别 | 国产福利视频一区二区 | 一本久久伊人热热精品中文字幕 | 欧美丰满熟妇xxxx | 日韩欧美成人免费观看 | 最近的中文字幕在线看视频 | 最新国产麻豆aⅴ精品无码 | 老熟妇乱子伦牲交视频 | 中文字幕无码免费久久9一区9 | 国产精品亚洲lv粉色 | 亚洲精品一区二区三区大桥未久 | 日产国产精品亚洲系列 | 久久综合久久自在自线精品自 | 国语自产偷拍精品视频偷 | 人妻少妇精品无码专区二区 | 中文字幕 亚洲精品 第1页 | 乱人伦人妻中文字幕无码久久网 | 国产无套内射久久久国产 | 欧美亚洲国产一区二区三区 | 精品无码一区二区三区爱欲 | 国产无套粉嫩白浆在线 | 久久久成人毛片无码 | 国产精品欧美成人 | 中文字幕日产无线码一区 | 99久久婷婷国产综合精品青草免费 | 无遮挡国产高潮视频免费观看 | 成人无码精品一区二区三区 | 精品乱子伦一区二区三区 | 精品久久久久久人妻无码中文字幕 | 人妻夜夜爽天天爽三区 | 国产精品亚洲五月天高清 | 红桃av一区二区三区在线无码av | 色婷婷久久一区二区三区麻豆 | 2020久久超碰国产精品最新 | 麻花豆传媒剧国产免费mv在线 | 亚洲の无码国产の无码步美 | 色欲久久久天天天综合网精品 | 波多野结衣一区二区三区av免费 | 精品无人国产偷自产在线 | 国产精品人人爽人人做我的可爱 | 国产精品久久久久影院嫩草 | 少妇人妻大乳在线视频 | 国产成人综合在线女婷五月99播放 | 国产精华av午夜在线观看 | 亚洲日本va午夜在线电影 | 亚洲精品成人福利网站 | 午夜理论片yy44880影院 | 无码毛片视频一区二区本码 | 久久亚洲国产成人精品性色 | 精品无人国产偷自产在线 | 久久亚洲精品成人无码 | 色五月五月丁香亚洲综合网 | av人摸人人人澡人人超碰下载 | 亚洲中文字幕在线观看 | 东京热无码av男人的天堂 | 亚洲国产精品一区二区第一页 | 亚洲精品成人福利网站 | 成人女人看片免费视频放人 | 97夜夜澡人人爽人人喊中国片 | 精品无码国产自产拍在线观看蜜 | 亚洲精品一区二区三区在线 | 国产午夜无码视频在线观看 | 国产免费观看黄av片 | 99久久精品无码一区二区毛片 | 一本一道久久综合久久 | 久久国产自偷自偷免费一区调 | 99久久久无码国产aaa精品 | 色欲综合久久中文字幕网 | 在教室伦流澡到高潮hnp视频 | 67194成是人免费无码 | 国产日产欧产精品精品app | 无码任你躁久久久久久久 | 国产亚洲美女精品久久久2020 | 内射后入在线观看一区 | 色一情一乱一伦一视频免费看 | 成人无码影片精品久久久 | 亚洲 另类 在线 欧美 制服 | 婷婷丁香五月天综合东京热 | 久久亚洲国产成人精品性色 | 亚洲国产精品久久久天堂 | 精品国产一区二区三区四区在线看 | 久激情内射婷内射蜜桃人妖 | 在线看片无码永久免费视频 | 国产九九九九九九九a片 | 伊人久久大香线蕉亚洲 | 亚洲综合无码一区二区三区 | 人人爽人人爽人人片av亚洲 | 亚洲乱亚洲乱妇50p | 老熟妇乱子伦牲交视频 | 亚洲国产精品无码一区二区三区 | 人妻夜夜爽天天爽三区 | 强开小婷嫩苞又嫩又紧视频 | 国产又爽又猛又粗的视频a片 | 日本丰满护士爆乳xxxx | 国产香蕉尹人视频在线 | 国产午夜亚洲精品不卡 | 精品久久综合1区2区3区激情 | 久久精品成人欧美大片 | 亚洲男人av香蕉爽爽爽爽 | 波多野结衣av一区二区全免费观看 | 无套内射视频囯产 | 少妇高潮喷潮久久久影院 | 国产亚洲美女精品久久久2020 | 人妻插b视频一区二区三区 | 亚洲国产一区二区三区在线观看 | 国产亚av手机在线观看 | 久久成人a毛片免费观看网站 | 性色欲网站人妻丰满中文久久不卡 | 亚洲精品欧美二区三区中文字幕 | 欧美日韩亚洲国产精品 | 国产午夜手机精彩视频 | 精品无人国产偷自产在线 | 无套内谢的新婚少妇国语播放 | 精品久久综合1区2区3区激情 | 黑人巨大精品欧美黑寡妇 | 国产小呦泬泬99精品 | 国模大胆一区二区三区 | 国产亚洲日韩欧美另类第八页 | 蜜桃视频韩日免费播放 | 国产农村妇女高潮大叫 | 中文字幕色婷婷在线视频 | 久久天天躁狠狠躁夜夜免费观看 | 国产97色在线 | 免 | 正在播放东北夫妻内射 | 国产内射老熟女aaaa | 国产无遮挡吃胸膜奶免费看 | 日韩无套无码精品 | 伊人久久大香线蕉av一区二区 | 午夜精品一区二区三区在线观看 | 国产又爽又猛又粗的视频a片 | av小次郎收藏 | 又紧又大又爽精品一区二区 | 图片区 小说区 区 亚洲五月 | 日韩少妇白浆无码系列 | 内射后入在线观看一区 | 美女张开腿让人桶 | 国产小呦泬泬99精品 | 激情国产av做激情国产爱 | 5858s亚洲色大成网站www | 国产精品高潮呻吟av久久 | 国产三级精品三级男人的天堂 | 国内精品九九久久久精品 | www成人国产高清内射 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 熟妇女人妻丰满少妇中文字幕 | 啦啦啦www在线观看免费视频 | 性欧美疯狂xxxxbbbb | 久久久精品欧美一区二区免费 | 亚洲精品一区三区三区在线观看 | 亚洲精品一区二区三区大桥未久 | 亚洲欧美色中文字幕在线 | 久久综合网欧美色妞网 | 玩弄人妻少妇500系列视频 | 色综合久久网 | 国产日产欧产精品精品app | 日产国产精品亚洲系列 | 中文字幕中文有码在线 | 国产热a欧美热a在线视频 | 国产人妻久久精品二区三区老狼 | 少妇的肉体aa片免费 | 午夜成人1000部免费视频 | 国产无遮挡又黄又爽又色 | 国产精品-区区久久久狼 | 亲嘴扒胸摸屁股激烈网站 | 精品无码成人片一区二区98 | 亚洲中文字幕久久无码 | 人妻中文无码久热丝袜 | 色窝窝无码一区二区三区色欲 | 在线观看免费人成视频 | 老熟妇乱子伦牲交视频 | 免费观看又污又黄的网站 | 欧美精品国产综合久久 | 亚洲大尺度无码无码专区 | 男女下面进入的视频免费午夜 | 国产人妻精品一区二区三区 | 久久亚洲日韩精品一区二区三区 | 国内精品人妻无码久久久影院蜜桃 | 在线观看国产午夜福利片 | 天下第一社区视频www日本 | 小泽玛莉亚一区二区视频在线 | 欧美丰满熟妇xxxx性ppx人交 | 国产精品久久久久久亚洲影视内衣 | 夜先锋av资源网站 | 国产成人精品视频ⅴa片软件竹菊 | 国产精品久久久 | 思思久久99热只有频精品66 | 久久午夜无码鲁丝片午夜精品 | 色综合久久久无码中文字幕 | 大地资源中文第3页 | 色婷婷综合中文久久一本 | 久久99精品久久久久婷婷 | 水蜜桃亚洲一二三四在线 | 无码国内精品人妻少妇 | 少妇高潮一区二区三区99 | 亚洲日本一区二区三区在线 | 少妇无码一区二区二三区 | 九九综合va免费看 | 老头边吃奶边弄进去呻吟 | 色诱久久久久综合网ywww | 国产午夜亚洲精品不卡 | 又粗又大又硬毛片免费看 | 国产精品亚洲五月天高清 | 成熟妇人a片免费看网站 | 久久久久99精品成人片 | 欧美黑人乱大交 | 人妻无码αv中文字幕久久琪琪布 | 日本在线高清不卡免费播放 | 97久久超碰中文字幕 | 成熟妇人a片免费看网站 | 我要看www免费看插插视频 | 无码人妻精品一区二区三区下载 | 大地资源中文第3页 | 精品无人区无码乱码毛片国产 | 玩弄少妇高潮ⅹxxxyw | 日本成熟视频免费视频 | 亚洲欧美日韩综合久久久 | 丰满岳乱妇在线观看中字无码 | 人妻aⅴ无码一区二区三区 | 久久人人爽人人爽人人片av高清 | 国内少妇偷人精品视频 | 天天拍夜夜添久久精品大 | 亚洲自偷自偷在线制服 | aⅴ亚洲 日韩 色 图网站 播放 | 欧美国产日产一区二区 | 国产乡下妇女做爰 | 国内精品九九久久久精品 | 国产激情精品一区二区三区 | 少妇人妻偷人精品无码视频 | 欧美人与物videos另类 | 日本一本二本三区免费 | 日韩人妻无码一区二区三区久久99 | 午夜无码区在线观看 | 亚洲成av人在线观看网址 | 无码国产乱人伦偷精品视频 | 成人精品天堂一区二区三区 | 久久综合久久自在自线精品自 | 成在人线av无码免观看麻豆 | 免费网站看v片在线18禁无码 | 福利一区二区三区视频在线观看 | 国产激情一区二区三区 | 中文毛片无遮挡高清免费 | 77777熟女视频在线观看 а天堂中文在线官网 | 亚洲精品一区三区三区在线观看 | 国产美女极度色诱视频www | 亚洲一区二区三区国产精华液 | 精品aⅴ一区二区三区 | 国产亚洲人成a在线v网站 | 国产亚洲精品久久久久久国模美 | 久久久久久国产精品无码下载 | 99久久精品无码一区二区毛片 | 亚洲中文无码av永久不收费 | 成人亚洲精品久久久久 | 爽爽影院免费观看 | 中文字幕+乱码+中文字幕一区 | 嫩b人妻精品一区二区三区 | 无码精品人妻一区二区三区av | 清纯唯美经典一区二区 | 精品偷自拍另类在线观看 | 国产成人一区二区三区别 | 国产精品多人p群无码 | 四虎永久在线精品免费网址 | 久久精品人人做人人综合试看 | 精品无码一区二区三区爱欲 | 嫩b人妻精品一区二区三区 | 澳门永久av免费网站 | 国产亚洲精品精品国产亚洲综合 | 亚洲成av人在线观看网址 | 98国产精品综合一区二区三区 | 中文字幕无码日韩专区 | 扒开双腿疯狂进出爽爽爽视频 | 纯爱无遮挡h肉动漫在线播放 | 国产精品igao视频网 | 精品人人妻人人澡人人爽人人 | 国产麻豆精品一区二区三区v视界 | 四虎影视成人永久免费观看视频 | 亚洲一区二区三区四区 | 夜夜高潮次次欢爽av女 | 国产成人精品优优av | 亚洲码国产精品高潮在线 | 无码毛片视频一区二区本码 | 亚洲国产高清在线观看视频 | 在线精品国产一区二区三区 | 午夜精品一区二区三区在线观看 | 国产av剧情md精品麻豆 | 日本一卡二卡不卡视频查询 | 色综合久久久无码网中文 | 亚洲天堂2017无码中文 | 97精品国产97久久久久久免费 | 少妇人妻av毛片在线看 | 小sao货水好多真紧h无码视频 | 99麻豆久久久国产精品免费 | 欧美日韩一区二区免费视频 | 成人女人看片免费视频放人 | 性生交大片免费看女人按摩摩 | 午夜福利试看120秒体验区 | 水蜜桃av无码 | 久久成人a毛片免费观看网站 | 亚洲国产精品美女久久久久 | 亚洲经典千人经典日产 | 成人无码视频免费播放 | 久久精品女人的天堂av | 少妇一晚三次一区二区三区 | 欧美高清在线精品一区 | 日本又色又爽又黄的a片18禁 | 久久99国产综合精品 | 亚无码乱人伦一区二区 | 在线观看免费人成视频 | 欧美人妻一区二区三区 | 久久婷婷五月综合色国产香蕉 | 无码国产色欲xxxxx视频 | 正在播放老肥熟妇露脸 | 国模大胆一区二区三区 | 自拍偷自拍亚洲精品10p | 内射欧美老妇wbb | 天堂无码人妻精品一区二区三区 | 色婷婷综合激情综在线播放 | 蜜臀av在线播放 久久综合激激的五月天 | 免费人成网站视频在线观看 | 天堂亚洲2017在线观看 | 国产人妻精品一区二区三区不卡 | 女人高潮内射99精品 | 性开放的女人aaa片 | 色综合久久88色综合天天 | 伊人久久大香线蕉亚洲 | 撕开奶罩揉吮奶头视频 | 又大又硬又黄的免费视频 | 中国女人内谢69xxxxxa片 | 色一情一乱一伦一视频免费看 | 噜噜噜亚洲色成人网站 | 国产成人无码午夜视频在线观看 | 天堂无码人妻精品一区二区三区 | 成人一在线视频日韩国产 | 日本丰满熟妇videos | 国产精品福利视频导航 | 少妇无码一区二区二三区 | 欧美精品无码一区二区三区 | 精品一区二区三区无码免费视频 | 国产精品成人av在线观看 | 亚洲色www成人永久网址 | 国产精品资源一区二区 | 性欧美牲交xxxxx视频 |