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

歡迎訪問 生活随笔!

生活随笔

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

linux

main() 函数解析(一)——Linux-0.11 剖析笔记(六)

發布時間:2025/3/15 linux 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 main() 函数解析(一)——Linux-0.11 剖析笔记(六) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1. 宏定義`_syscall0`
  • 2. `setup.s`讀取的參數
  • 3. 讀取CMOS實時時鐘信息
    • 3.1 `outb_p(value,port)`
    • 3.2 `inb_p(port)`
    • 3.3 `outb(value,port)`和`inb(port)`
    • 3.4 CMOS與RTC
    • 3.5 time_init函數
  • 4. main函數
    • 4.1 根設備號
    • 4.2 復制硬盤參數表
    • 4.3 計算主內存起始位置
    • 4.4 虛擬盤
    • 4.5 `mem_init`函數
    • 4.6 `trap_init`函數
      • 4.6.1 `set_trap_gate(n,addr) `
      • 4.6.2 `idt`數組
      • 4.6.3 `set_system_gate(n,addr)`

說明:本文由舊文 main()函數解析(一) 修改而來,略有改動。

經過了前面的各種鋪墊,終于來到了main函數。

1. 宏定義_syscall0

先說這幾個內聯函數

static inline _syscall0(int,fork) static inline _syscall0(int,pause) static inline _syscall1(int,setup,void *,BIOS) static inline _syscall0(int,sync)

比如

static inline _syscall0(int,fork)

_syscall0()是在文件unistd.h中定義,它以內嵌匯編的形式調用 Linux 的系統調用中斷 int 0x80。

系統調用(通常稱為syscalls)是 Linux內核與上層應用程序進行交互通信的唯一接口。用戶程序通過直接或間接(通過庫函數)調用中斷int 0x80(在eax寄存器中指定系統調用功能號),即可使用內核資源,包括系統硬件資源。

_syscall0()其實是一個宏,這個宏定義在include/unistd.h 文件第 133 行:

#define _syscall0(type,name) \ type name(void) \ { \ long __res; \ __asm__ volatile ("int $0x80" \ : "=a" (__res) \: "0" (__NR_##name)); \ if (__res >= 0) \return (type) __res; \ errno = -__res; \ return -1; \ }

第 5 行:匯編語句,表示系統調用,產生軟中斷,0x80 號中斷;

第 6 行:輸出部分,"=a" 表示用寄存器 eax,當匯編語句執行后,把 eax 的值傳給變量__res,作為返回值;

第 7 行:輸入部分,“0” 表示和第 0 個輸出變量有相同的約束,即使用寄存器 eax,把__NR_name的值賦給 eax,指明系統調用功能號;

第 8~9 行: 如果返回值 >=0,則直接返回該值;

第10~11行: 否則置出錯號(errno 是全局變量),并返回-1。

內嵌匯編語法如下。對此不熟悉的朋友可以專門找資料學習,可以參考我的博文:

C 語言內聯匯編介紹

__asm__(匯編語句模板: 輸出部分: 輸入部分: 破壞描述部分)

根據_syscall0()的宏定義,我們把static inline _syscall0(int,fork)展開,得到:

static inline int fork(void) { long __res; __asm__ volatile ("int $0x80" : "=a" (__res) : "0" (2)); if (__res >= 0) return (int) __res; errno = -__res; return -1; }

實際上展開結果就是上面一行。

可以手工展開,也可以用命令展開。用命令展開的方法是:

首先進入到 Linux-0.11 源碼路徑下,比如~/oslab/linux-0.11,然后輸入命令:

gcc -E init/main.c -o main.i -I./include

如果你還沒有實驗環境,那趕緊弄一個吧,方法是 Linux 0.11 實驗環境搭建或者Linux 0.11 實驗環境搭建與調試

以上的展開結果實在是太長了,分行寫如下:

static inline int fork(void) {long __res;__asm__ volatile ("int $0x80" : "=a" (__res) : "0" (2)); if (__res >= 0)return (int) __res; errno = -__res;return -1; }

第6行:括號里的“2”是因為在文件unistd.h中有#define __NR_fork 2,表示系統中斷調用號。

gcc會把上述“函數”體中的語句直接插入到調用fork()語句的代碼處,因此執行fork()不會引起函數調用。另外,宏名稱字符串syscall0中最后的0 表示無參數,1表示帶1個參數。如果系統調用帶有1個參數,那么就應該使用宏_syscall1()。

2. setup.s讀取的參數

/** This is set up by the setup-routine at boot-time*/ #define EXT_MEM_K (*(unsigned short *)0x90002) #define DRIVE_INFO (*(struct drive_info *)0x90080) #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)

以上三行,右側的地址其實是setup.s運行時,讀取了一些參數,并保存到了相應位置。忘了的同學可以參考我的博文 bootsect.s 分析—— Linux-0.11 學習筆記(一)

  • EXT_MEM_K (0x9002):系統從 1MB 開始的擴展內存大小,以KB為單位;

  • DRIVE_INFO (0x90080) :硬盤參數表,包括第1個和第2個硬盤,共32字節;

  • ORIG_ROOT_DEV :根文件系統所在的設備號3.

  • 3. 讀取CMOS實時時鐘信息

    #define CMOS_READ(addr) ({ \ outb_p(0x80|addr,0x70); \ // 把 (0x80|addr) 寫入端口0x70 inb_p(0x71); \ // 讀端口0x71 })

    要想搞清楚上面的代碼,就先要弄清楚outb_p和inb_p。outb_p和inb_p都是宏,在文件\include\asm\io.h中定義。

    3.1 outb_p(value,port)

    #define outb_p(value,port) \__asm__ ("outb %%al,%%dx\n" \"\tjmp 1f\n" \"1:\tjmp 1f\n" \"1:"::"a" (value),"d" (port))

    功能:向端口 port 寫值 value

    注意:第4行和第5行開頭的 “1:” 是標號。

    第2行:把 al 的值寫入端口 dx;

    第3行:跳轉到1處,即下一句;這樣寫是為了延時;

    第4行:同第3行;

    第5行:內聯匯編的輸入部分,port作為端口號,傳給 edx; value作為要寫入的值,傳給 eax;

    所以, outb_p(value,port)表示把value寫入端口port.

    3.2 inb_p(port)

    #define inb_p(port) ({ \unsigned char _v; \__asm__ volatile ("inb %%dx,%%al\n" \"\tjmp 1f\n" \"1:\tjmp 1f\n" \"1:":"=a" (_v):"d" (port)); \_v; \})

    第3行:讀端口 dx 到 al;

    第4~5行:跳轉到1處,即下一句;為了延時;

    第 6 行分為兩部分,輸入部分是"d" (port),表示把端口號port傳給edx;輸出部分是"=a" (_v),表示把 eax 的值傳給_v

    第7行:_v 的值作為整個表達式的返回值。

    所以, inb_p(port)表示讀取端口port的值。

    對于第 7 行,要說明一下,這種用法是可以的。

    比如

    int main(void) {int x = 10;int y = 1;int c = ({x;y;});printf("c = %d\n",c); }

    第 5 行,這樣寫合法,結果輸出 1

    可以參考我的博文:C語言的復合語句表達式

    3.3 outb(value,port)和inb(port)

    #define outb(value,port) \ __asm__ ("outb %%al,%%dx"::"a" (value),"d" (port))#define inb(port) ({ \ unsigned char _v; \ __asm__ volatile ("inb %%dx,%%al":"=a" (_v):"d" (port)); \ _v; \ })

    既然都分析到這里了,那就把這兩個宏也說了吧。這兩個宏和上面的差不多,只不過不帶延遲。

    3.4 CMOS與RTC

    PC 機的 CMOS 內存是由電池供電的 64 或 128 字節內存塊,通常是系統實時鐘芯片RTC (Real Time Chip) 的一部分。有些機器還有更大的內存容量。該 64 字節的CMOS原先在IBM PC-XT機器上用于保存時鐘和日期信息,存放的格式是BCD碼。由于這些信息僅用去 14 字節,因此剩余的字節就可用來存放一些系統配置數據。

    CMOS的地址空間在基本地址空間之外。**要訪問它需要通過端口 0x70、 0x71 進行。0x70 是地址端口,0x71 是數據端口。**為了讀取指定偏移位置的字節,必須首先使用out指令向地址端口 0x70 發送指定字節的偏移位置值,然后使用in指令從數據端口 0x71 讀取指定的字節信息。同樣,對于寫操作也需要首先向地址端口 0x70 發送指定字節的偏移值,然后把數據寫到數據端口 0x71 中去。

    outb_p(0x80|addr,0x70);把欲讀取的字節地址(addr)與0x80進行或操作是沒有必要的。因為那時的CMOS內存容量還沒有超過128(=111_1111b)字節,因此不需要把b7設為1。之所以會有這樣的操作是因為當時Linus手頭缺乏有關CMOS方面的資料,CMOS中時鐘和日期的偏移地址都是他逐步實驗出來的,也許在他的實驗中將偏移地址與0x80進行或操作(并且還修改了其他地方)后正好取得了所有正確的結果,因此他的代碼中也就有了這步不必要的操作。不過從1.0版本之后,該操作就被去除了。

    下表是 CMOS 內存信息的一張簡表。

    CMOS 64 字節信息簡表

    3.5 time_init函數

    static void time_init(void){struct tm time;do {time.tm_sec = CMOS_READ(0); // 秒time.tm_min = CMOS_READ(2); // 分time.tm_hour = CMOS_READ(4); // 時time.tm_mday = CMOS_READ(7); // 日time.tm_mon = CMOS_READ(8); // 月time.tm_year = CMOS_READ(9); // 年(since 1900)} while (time.tm_sec != CMOS_READ(0));BCD_TO_BIN(time.tm_sec);BCD_TO_BIN(time.tm_min);BCD_TO_BIN(time.tm_hour);BCD_TO_BIN(time.tm_mday);BCD_TO_BIN(time.tm_mon);BCD_TO_BIN(time.tm_year);time.tm_mon--;startup_time = kernel_mktime(&time);}

    結合上面的表格,6~11行非常好懂。

    第12行:while (time.tm_sec != CMOS_READ(0));為什么有這個do-while循環呢?

    CMOS的訪問速度很慢。為了減小時間誤差,在讀取了所有數值后,若此時CMOS中秒值發生了變化,那么就重新讀取所有值。這樣內核就能把與CMOS時間誤差控制在1秒之內。

    注意,讀取的值是BCD(Binary Coded Decimal)碼格式。

    BCD碼:是一種十進制數字編碼的形式。在這種編碼下,每個十進制數字用一串單獨的二進制比特來存儲與表示。常見的有以4位表示1個十進制數字,稱為壓縮的BCD碼(compressed or packed);或者以8位表示1個十進制數字,稱為未壓縮的BCD碼(uncompressed or zoned)。

    比如當前時間是10:35:20,那么讀出的二進制數是:

    0001_0000b:0011_0101b:0010_0000b

    #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)// (val)&15 即 (val)&0xF, 得到個位數;// (val)>>4)*10 把十位上的數字乘以10;

    這個宏的作用是把BCD格式的值轉換成二進制(或者說十進制,總之存到PC里都是二進制)

    time.tm_mon--;startup_time = kernel_mktime(&time);

    第2行:調用函數kernel_mktime(),計算從 1970 年 1 月 1 日 0 時起到現在經過的秒數,作為開機時間,保存到全局變量startup_time 中。更具體的分析可以參考我的博文 kernel_mktime() 詳解

    4. main函數

    void main(void) /* This really IS void, no error here. */ { /* The startup routine assumes (well, ...) this */ /** Interrupts are still disabled. Do necessary setups, then* enable them*/ROOT_DEV = ORIG_ROOT_DEV; //0x21Cdrive_info = DRIVE_INFO;memory_end = (1<<20) + (EXT_MEM_K<<10); //EXT_MEM_K = 0x3c00, memory_end = 0x100_0000memory_end &= 0xfffff000; //0x100_0000 = 16Mif (memory_end > 16*1024*1024)memory_end = 16*1024*1024;if (memory_end > 12*1024*1024) buffer_memory_end = 4*1024*1024; //buffer_memory_end = 4M else if (memory_end > 6*1024*1024)buffer_memory_end = 2*1024*1024;elsebuffer_memory_end = 1*1024*1024;main_memory_start = buffer_memory_end; //4M #ifdef RAMDISK_SIZE //=1025main_memory_start += rd_init(main_memory_start, RAMDISK_SIZE*1024); #endifmem_init(main_memory_start,memory_end);trap_init();blk_dev_init();chr_dev_init();tty_init();time_init();sched_init();buffer_init(buffer_memory_end);hd_init();floppy_init();sti();move_to_user_mode();if (!fork()) { /* we count on this going ok */init();} /** NOTE!! For any other task 'pause()' would mean we have to get a* signal to awaken, but task0 is the sole exception (see 'schedule()')* as task 0 gets activated at every idle moment (when no other tasks* can run). For task0 'pause()' just means we go check if some other* task can run, and if not we return here.*/for(;;) pause(); }

    4.1 根設備號

    ROOT_DEV = ORIG_ROOT_DEV;

    ROOT_DEV 是什么? 在 fs/super.c 中,定義了 int ROOT_DEV = 0;

    ORIG_ROOT_DEV 是什么?本文件內有宏定義

    #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)

    ROOT_DEV = ORIG_ROOT_DEV;這條語句執行后(依據我的實驗環境),ROOT_DEV = 0x21C

    在bootsect.s中,有

    mov %cs:root_dev+0, %axcmp $0, %axjne root_definedmov %cs:sectors+0, %bxmov $0x0208, %ax # /dev/ps0 - 1.2Mbcmp $15, %bxje root_definedmov $0x021c, %ax # /dev/PS0 - 1.44Mb, excute here when debugcmp $18, %bxje root_defined undef_root:jmp undef_root root_defined:mov %ax, %cs:root_dev+0....org 508 root_dev:.word ROOT_DEV !這里存放根文件系統所在設備號(init/main.c中會用)

    這段代碼的意思,可以參考我的博文 bootsect.s 解讀——Linux-0.11 剖析筆記(二)

    “確認根文件系統設備號” 這節

    設備號 = 主設備號*256 + 次設備號(即 dev_no = (major << 8) + minor )

    在 Linux 中軟驅的主設備號是 2,次設備號 = type*4 + nr,其中 nr 為 0-3 分別對應軟驅 A、B、C 或 D; type 是軟驅的類型(2 表示1.2 MB 或 7 表示 1.44 MB 等)。

    0x21C = 2<<8 + (7*4+0),所以根設備是 1.44M 的 A 驅動器。

    4.2 復制硬盤參數表

    第 9 行,drive_info = DRIVE_INFO;

    本文件內有代碼

    #define DRIVE_INFO (*(struct drive_info *)0x90080) ... struct drive_info { char dummy[32]; } drive_info;

    用意是復制 0x90080 處的硬盤參數表

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tt1JtmY9-1596350698833)(pics/image-20200801084436199.png)]

    4.3 計算主內存起始位置

    本文件中有

    #define EXT_MEM_K (*(unsigned short *)0x90002)

    EXT_MEM_K 表示系統從 1MB 開始的擴展內存值,單位是 KB,所以要左移 10 位

    memory_end = (1<<20) + (EXT_MEM_K<<10); memory_end &= 0xfffff000; // 忽略不到 4KB(1頁)的內存數if (memory_end > 16*1024*1024) //如果內存超過16M,則按16M計memory_end = 16*1024*1024;if (memory_end > 12*1024*1024) //如果內存超過12M,則設置緩沖區末端=4Mbuffer_memory_end = 4*1024*1024; else if (memory_end > 6*1024*1024)//如果內存超過6M,則設置緩沖區末端=2Mbuffer_memory_end = 2*1024*1024;elsebuffer_memory_end = 1*1024*1024;//否則設置緩沖區末端=1Mmain_memory_start = buffer_memory_end; //主內存起始位置=緩沖區末端

    注意,代碼注釋部分的值是我通過實驗測試出來的,你的實驗環境不一定是這個值。

    第1行:計算出內存大小

    第2行:忽略不到4KB的內存數

    這里的緩沖區需要解釋一下。

    為了提高系統訪問塊設備的速度,內核在內存中開辟了一塊高速緩沖區,將其劃分為一個個與磁盤塊大小相等的緩沖塊來暫存與塊設備之間的交換數據,以減少I/O操作的次數,提高系統的性能。緩沖塊中保存著最近訪問磁盤的數據,內核在讀塊設備之前先搜索緩沖區,如果數據在緩沖區中就不需要再從磁盤中讀,否則向塊設備發出讀的指令。當內核寫塊設備時,先將數據寫入緩沖區,什么時候將數據同步到塊設備視具體情況而定,這樣做是為了盡可能久地將數據停留在內存以減少對塊設備的操作。

    在我的環境中,通過單步調試,代碼執行第6行,也就是說緩沖區末端(buffer_memory_end)在4M處,也就是主內存的起始位置(main_memory_start)。

    4.4 虛擬盤

    #ifdef RAMDISKmain_memory_start += rd_init(main_memory_start, RAMDISK*1024); #endif

    當 linux/Makefile文件中設置的RAMDISK值不為零時,表示系統會創建 RAM 虛擬盤設備。 在這種情況下,就會執行第2行,即主內存區的起始地址后移,也就是說主內存區頭部還要劃去一部分,供虛擬盤存放數據。

    對于我的實驗環境,Makefile 文件中有

    RAMDISK = #-DRAMDISK=512

    所以,虛擬盤的大小是0.5 * 1K * 1K = 0.5 M

    如圖所示,內核程序占據在物理內存的開始部分,接下來是供硬盤或軟盤等塊設備使用的高速緩沖區部分(其中要扣除顯卡內存和 ROM BIOS 所占用的內存,它們的地址范圍是 640KB~1MB)。

    關于高速緩沖區:如前文所述,當一個進程需要讀取塊設備中的數據時,系統會首先把數據讀到高速緩沖區中;當有數據需要寫到塊設備上時,系統也是先將數據放到高速緩沖區中,然后由塊設備驅動程序寫到相應的設備上。

    內存的最后部分是供所有程序可以隨時申請和使用的主內存區。內核程序在使用主內存區時,也同樣先要向內核內存管理模塊提出申請,在申請成功后方能使用。

    對于含有 RAM 虛擬盤的系統,主內存區頭部還要劃去一部分,供虛擬盤存放數據。

    long rd_init(long mem_start, int length) {int i;char *cp;blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;rd_start = (char *) mem_start;rd_length = length;cp = rd_start;for (i=0; i < length; i++)*cp++ = '\0';return(length); }

    第6行:MAJOR_NR 的值是1。因為在這個函數所在文件里,有 #define MAJOR_NR 1

    blk_dev是一個數組,其成員類型是struct blk_dev_struct

    struct blk_dev_struct blk_dev[NR_BLK_DEV] = {{ NULL, NULL }, /* no_dev */{ NULL, NULL }, /* dev mem */{ NULL, NULL }, /* dev fd */{ NULL, NULL }, /* dev hd */{ NULL, NULL }, /* dev ttyx */{ NULL, NULL }, /* dev tty */{ NULL, NULL } /* dev lp */ };

    struct blk_dev_struct的定義是

    struct blk_dev_struct {void (*request_fn)(void);struct request * current_request; };

    可以看出,2個成員都是指針,request_fn指向函數,current_request指向struct request.

    回到函數rd_init:

    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;

    DEVICE_REQUEST實際上是設備請求函數do_rd_request

    因為#define DEVICE_REQUEST do_rd_request

    void do_rd_request(void) {int len;char *addr;INIT_REQUEST;addr = rd_start + (CURRENT->sector << 9);len = CURRENT->nr_sectors << 9;if ((MINOR(CURRENT->dev) != 1) || (addr+len > rd_start+rd_length)) {end_request(0);goto repeat;}if (CURRENT-> cmd == WRITE) {(void) memcpy(addr,CURRENT->buffer,len);} else if (CURRENT->cmd == READ) {(void) memcpy(CURRENT->buffer, addr,len);} elsepanic("unknown ramdisk-command");end_request(1);goto repeat; }

    此函數的代碼,我們先不深入,以后用到再說。我們關注的是rd_init函數的以下幾行:

    rd_start = (char *) mem_start;rd_length = length;cp = rd_start; // cp是 char * 類型for (i=0; i < length; i++)*cp++ = '\0'; //以上3行, 盤區清零return(length);

    rd_start和rd_length都是全局變量,定義在文件kernel\blk_drv\ramdisk.c中:

    char *rd_start; //虛擬盤的起始地址 int rd_length = 0; //虛擬盤空間大小,以B為單位

    4.5 mem_init函數

    該函數對 1MB 以上內存區域以頁面為單位進行管理前的初始化設置工作。

    一個頁面長度為4KB字節。該函數把1MB以上所有物理內存劃分成一個個頁面,并使用一個頁面映射字節數組mem_map[] 來管理這些頁面。對于具有 16MB 內存容量的機器,該數組共有3840( (16M-1M)/4K=3840 )項 ,即可管理3840個物理頁面。

    每當一個物理內存頁面被占用時就把 mem_map[]中對應的的字節值增1 ;若釋放一個物理頁面,就把對應字節值減 1。 若字節值為0 , 則表示對應頁面空閑; 若字節值 >=1,則表示對應頁面被占用或被不同程序共享占用。

    在該版本內核中,最多能管理16MB的物理內存,大于16MB的內存將棄掉不用。對于具有16MB內存的PC機系統,在沒有設置虛擬盤 RAMDISK 的情況下start_mem通常是4MB,end_mem是 16MB。因此主內存區范圍是4MB~16MB,共有3072(=12M/4K)個物理頁面可供分配。如果設置了 RAMDISK,那么start_mem會大于4MB.

    void mem_init(long start_mem, long end_mem) {int i;HIGH_MEMORY = end_mem;// 參數start_mem是可用作頁面分配的主內存區起始地址//(已去除RAMDISK所占內存空間)。 // end_mem是實際物理內存最大地址。//地址范圍start_mem到end_mem是主內存區。 for (i=0 ; i<PAGING_PAGES ; i++) //PAGING_PAGES = 3840mem_map[i] = USED; // 表示不可用?i = MAP_NR(start_mem); // i=主內存區起始位置處頁面號end_mem -= start_mem; // 首尾相減,算出主內存區的大小end_mem >>= 12; // 主內存區的總頁面數while (end_mem-->0)mem_map[i++]=0; // 以上2行, 主內存區頁面對應字節值清零 }

    第11~12行: 首先將 1MB 到 16MB 范圍內所有內存頁面設置為已占用狀態,即各項字節值全部設置成 USED(100)

    PAGING_PAGES 被定義為(PAGING_MEM0RY>>12),即(15*1024*1024)>>12=3840

    #define LOW_MEM 0x100000 #define PAGING_MEMORY (15*1024*1024) // 從 1M 到 16M #define PAGING_PAGES (PAGING_MEMORY>>12) // 除以 4K #define MAP_NR(addr) (((addr)-LOW_MEM)>>12) #define USED 100

    第13行:MAP_NR(start_mem) 即是(start_mem-0x100000)>>12,計算出主內存區起始位置處頁面號。

    4.6 trap_init函數

    void trap_init(void) {int i;set_trap_gate(0,&divide_error);set_trap_gate(1,&debug);set_trap_gate(2,&nmi);set_system_gate(3,&int3); /* int3-5 can be called from all */set_system_gate(4,&overflow);set_system_gate(5,&bounds);......}

    以上代碼主要是安裝陷阱門。我們拿第5行作為例子,具體分析一下。

    4.6.1 set_trap_gate(n,addr)

    因為

    #define set_trap_gate(n,addr) \ _set_gate(&idt[n],15,0,addr)

    所以,set_trap_gate(n,addr)其實是_set_gate(&idt[n],15,0,addr),也就是下面7~15行的內嵌匯編代碼。

    #define set_trap_gate(n,addr) \_set_gate(&idt[n],15,0,addr)...#define _set_gate(gate_addr,type,dpl,addr) \ __asm__ ("movw %%dx,%%ax\n\t" \"movw %0,%%dx\n\t" \"movl %%eax,%1\n\t" \"movl %%edx,%2" \: \: "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ "o" (*((char *) (gate_addr))), \"o" (*(4+(char *) (gate_addr))), \"d" ((char *) (addr)),"a" (0x00080000))

    d: 表示 edx

    a: 表示 eax

    i: 允許一個立即整形操作數,包括其值僅在匯編時確定的符號常量。

    o: 允許一個內存操作數,但只有當地址是可偏移的。即該地址加上一個小的偏移量,結果是一個有效的內存地址。

    第 8-10 行,分別有 %0, %1,2%,這分別代表 12-14 行的表達式。

    以上內嵌匯編代碼沒有輸出部分,僅有輸入部分。

    上圖是陷阱門的格式,上面是高4字節(代碼中用 edx 表示),下面是低4字節(代碼中用 eax 表示)。注意:過程入口點偏移值不是物理地址,而是線性地址。

    第15行:

    "d" ((char *) (addr))表示用 addr 加載 edx;此時,偏移值的[31:16]就位。

    addr 是異常處理函數入口點的地址。因為內核代碼段的線性基址是0,所以偏移值等于函數的線性地址,又因為內核在之前的分頁中采用了恒等映射機制——線性地址等于物理地址,所以偏移值等于函數的物理地址。

    "a" (0x00080000) :表示用 0x0008_0000 加載 eax;此時,段選擇符就位。

    段選擇子(符)的值是0x08,為什么是這個值呢?因為在進入main函數之前,已經設置好了GDT,0x08是代碼段的選擇子。忘了的話可以參考我的博文 head.s 分析 第三節。

    第7行的"movw %%dx,%%ax\n\t"表示用 dx 加載 ax;此時,偏移值的[15:0]就位,eax也就位。

    第8行的"movw %0,%%dx\n\t",表示用(0x8000+(dpl<<13)+(type<<8))加載 dx,

    這里的 8 表示 P=1; 此時,edx 就位。

    根據_set_gate(&idt[n],15,0,addr)的參數可知type=15(表示陷阱門), dpl=0。(0x8000+(dpl<<13)+(type<<8))拼出了陷阱門的第4~5字節(edx的低字)。

    第9行"movl %%eax,%1\n\t"表示把 eax 的值賦給*((char *) (gate_addr)),就是賦給idt[n]的前4字節。

    第10行"movl %%edx,%2" 表示把 edx 的值賦給*(4+(char *)(gate_addr)),就是賦給idt[n]的后4字節。這8字節拼起來就是完整的idt[n].

    4.6.2 idt數組

    idt是中斷描述符表(其實是數組),一共有 256 個表項,一個表項占8字節。

    %1對應第13行的(*((char *) (gate_addr)))

    gate_addr就是第2行的&idt[n],那么idt是什么呢?在文件include\linux\head.h中有:

    typedef struct desc_struct {unsigned long a,b; } desc_table[256];extern desc_table idt,gdt;

    1~3行:為struct desc_struct [256]取了一個別名——desc_table,也就是說desc_table的類型是“struct desc_struct類型的數組”。

    第6行,注意extern關鍵字,聲明(而不是定義)了 idt 和 gdt,它們的類型都是desc_table,即“struct desc_struct類型的數組”。所以,&idt[n]是數組idt第n個元素的地址。

    可能有人要問, idt 和 gdt的定義在哪里呢?
    它們是在匯編代碼boot/head.s中定義的。
    在本文件末尾有:

    idt: .fill 256,8,0 # idt is uninitializedgdt: .quad 0x0000000000000000 /* NULL descriptor */.quad 0x00c09a0000000fff /* 16Mb */.quad 0x00c0920000000fff /* 16Mb */.quad 0x0000000000000000 /* TEMPORARY - don't use */.fill 252,8,0 /* space for LDT's and TSS's etc */

    另外本文件開頭有

    .globl idt,gdt,pg_dir,tmp_floppy_area

    .globl xxx表示把符號xxx聲明為全局變量/標號,以供其他源文件訪問。

    好了,我們總結一下 _set_gate(gate_addr,type,dpl,addr) 這個宏

    #define _set_gate(gate_addr,type,dpl,addr) \ __asm__ ("movw %%dx,%%ax\n\t" \ //將偏移地址低字與選擇符組合成描述符低4字節(eax)"movw %0,%%dx\n\t" \ //將類型標志與偏移地址高字組合成描述符高4字節(edx)"movl %%eax,%1\n\t" \ //分別設置門描述符的低4字節和高4字節"movl %%edx,%2" \ : \: "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \"o" (*((char *) (gate_addr))), \"o" (*(4+(char *) (gate_addr))), \"d" ((char *) (addr)),"a" (0x00080000))

    _set_gate(gate_addr,type,dpl,addr)此宏用于設置門描述符,即填寫 IDT 中的某一項

    根據參數中的中斷或異常處理過程地址 addr 、門描述符類型 type 和特權級信息 dpl ,設置位于地址 gate_addr 處的門描述符。(注意:下面的“偏移”是相對于內核代碼或數據段來說的。)

    gate_addr:描述符存儲地址;
    type:描述符類型;
    dpl:描述符特權級;
    addr:偏移地址。

    %0:由dpl,type組合成的類型值;
    %1:描述符低 4 字節的存儲地址;
    %2:描述符高 4 字節的存儲地址;
    %3:即 (char *) (addr),edx(程序偏移地址addr);
    %4:即 0x00080000,eax(高字中含有段選擇符0x8) 。

    4.6.3 set_system_gate(n,addr)

    #define set_system_gate(n,addr) \_set_gate(&idt[n],15,3,addr)

    這個宏和set_trap_gate(n,addr)的區別僅有一點:前者的dpl=3,后者的dpl=0;

    分析到這里, trap_init函數的大意已經明了。

    void trap_init(void) {int i;set_trap_gate(0,&divide_error);set_trap_gate(1,&debug);set_trap_gate(2,&nmi);set_system_gate(3,&int3); /* int3-5 can be called from all */set_system_gate(4,&overflow);set_system_gate(5,&bounds);set_trap_gate(6,&invalid_op);set_trap_gate(7,&device_not_available);set_trap_gate(8,&double_fault);set_trap_gate(9,&coprocessor_segment_overrun);set_trap_gate(10,&invalid_TSS);set_trap_gate(11,&segment_not_present);set_trap_gate(12,&stack_segment);set_trap_gate(13,&general_protection);set_trap_gate(14,&page_fault);set_trap_gate(15,&reserved);set_trap_gate(16,&coprocessor_error);for (i=17;i<48;i++)set_trap_gate(i,&reserved);set_trap_gate(45,&irq13); // 設置協處理器中斷0x2d(=45)的陷阱門描述符outb_p(inb_p(0x21)&0xfb,0x21); // 允許8259A主芯片的IRQ2中斷請求outb(inb_p(0xA1)&0xdf,0xA1);set_trap_gate(39,&parallel_interrupt); //設置并行口1的中斷0x27(=39)陷阱門描述符 }

    5~21 行:設置IDT的描述符。其中斷點陷阱中斷int3、溢出中斷overflow、邊界出錯中斷bounds可以由任何程序產生,所以 DPL = 3

    22~23行:把int 17 ~ int 48的陷阱門先設置為reserved,以后各個硬件初始化時會重新設置自己的陷阱門。

    注意:set_trap_gate的第二個參數是中斷處理函數的入口點,它們的代碼在文件linux/kernel/asm.s或者linux/kernel/system_call.s中。

    第25行:outb_p(inb_p(0x21)&0xfb,0x21);

    0x21是 8259A 主片命令字OCW1的端口地址,用于對其中斷屏蔽寄存器 IMR 進行讀/寫操作。

    inb_p(0x21)&0xfb讀出 IMR 的值,然后與0xfb(=1111_1011b),即清零D2位,也就是允許主片的 IRQ2 中斷請求。

    注意:Linux-0.11 系統把主片的 ICW2 設置為 0x20,表示主片中斷請求0~7級對應的中斷號是 0x20~0x27;把從片的 ICW2 設置成 0x28,表示從片中斷請求8~15級對應的中斷號是 0x28~0x2f。

    第26行:outb(inb_p(0xA1)&0xdf,0xA1);

    0xA1是 8259A 從片命令字OCW1的端口地址。原理同上,inb_p(0xA1)&0xdf讀出從片 IMR 的值,然后與0xdf(=1101_1111),即清零D5位,由上圖可知,允許從片 IRQ13 協處理器中斷。

    關于8259A的編程,可以參考我的博文: 詳解8259A

    囿于篇幅,對main()函數的分析先到這里。

    —【未完待續】—

    參考資料

    《Linux內核完全剖析》(趙炯,機械工業出版社,2006)

    與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的main() 函数解析(一)——Linux-0.11 剖析笔记(六)的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    国产精品久久久久免费观看 | 国产原创91 | 免费观看91视频 | 久射网| 97电影手机版 | 久久高视频 | 国产精品 日韩精品 | 欧美激情奇米色 | 久久爱综合 | 婷婷在线网 | 日日碰夜夜爽 | 亚洲电影一区二区 | 婷婷伊人五月天 | av免费线看 | 97福利社 | 国产日本在线 | 国产精品一区二区av日韩在线 | 麻豆91在线 | 午夜成人影视 | 狠狠躁夜夜躁人人爽超碰91 | 在线观看视频一区二区 | 亚洲欧洲精品一区 | 亚洲精品在线视频网站 | av官网在线 | 国产中文字幕视频在线观看 | av看片在线| 日本久久久精品视频 | 粉嫩高清一区二区三区 | 在线观看免费成人av | 国产成人精品午夜在线播放 | 久久九九影视网 | 国产999精品久久久久久麻豆 | 亚洲精品乱码久久久久久9色 | 国内外成人免费在线视频 | 久久国产欧美日韩精品 | 久久一精品 | 美女国产 | 国产一区二区三区网站 | www.超碰 | 精品国产亚洲日本 | 久久久久黄色 | 四虎5151久久欧美毛片 | 视频成人永久免费视频 | 日韩av资源站 | 成人国产精品入口 | 蜜臀av网站 | 精品久久久久久久久久岛国gif | 日本深夜福利视频 | 五月天狠狠操 | 午夜久草| 婷婷综合视频 | 九九热精品在线 | 99精品视频在线观看免费 | 国产免费亚洲 | av在线直接看 | 久久草网站 | 在线只有精品 | 亚洲色图 校园春色 | 在线性视频日韩欧美 | 一区二区精品久久 | 在线天堂亚洲 | 欧美日韩亚洲第一页 | 精品国内自产拍在线观看视频 | 国产精品9999 | 最新国产在线视频 | 在线中文视频 | 伊人五月 | 最新av在线网站 | 亚洲永久国产精品 | 久久午夜精品影院一区 | 欧美福利片在线观看 | 久久久久成人精品 | 99久久99久久免费精品蜜臀 | 免费午夜av | 亚洲激情五月 | 国产福利av| 久久久在线观看 | 国产尤物一区二区三区 | 日本激情视频中文字幕 | 国产一级视屏 | 最新99热 | 久久欧美精品 | 日韩欧美电影在线观看 | 精品欧美一区二区三区久久久 | 99久久99久久免费精品蜜臀 | 啪啪小视频网站 | 亚洲人成在线电影 | 色播99 | 久久久久9999亚洲精品 | 中文在线资源 | 国产资源在线视频 | 久久久精品午夜 | 国产在线国偷精品产拍免费yy | av不卡中文字幕 | 日韩www在线 | 波多野结衣在线视频免费观看 | av在线播放免费 | 99久久日韩精品免费热麻豆美女 | 91九色porny蝌蚪视频 | 天天射天| 亚洲欧洲xxxx | 久久国精品 | 狠狠色狠狠色综合系列 | 丰满少妇在线观看 | 91精彩视频在线观看 | 天天操天天操一操 | 久久久精品国产一区二区 | 91试看| 亚洲欧美精品在线 | 91亚洲永久精品 | 国产成人综| 成人在线观看网址 | 亚洲国产精品成人精品 | 美女在线观看网站 | 18久久久久久 | 国产在线视频资源 | 美女黄频免费 | av电影在线播放 | 最近中文字幕 | 人人爱爱| 97操操操 | 极品中文字幕 | a v在线观看 | 天天干天天拍天天操天天拍 | 91一区一区三区 | 狠狠操狠狠干天天操 | 欧美精品网站 | 日本少妇高清做爰视频 | 午夜精品久久久久久久99婷婷 | 成人久久久久久久久久 | 久久av中文字幕片 | 久久中文欧美 | a天堂最新版中文在线地址 久久99久久精品国产 | 成全在线视频免费观看 | 欧美日韩在线观看一区 | 国产九色视频在线观看 | 免费亚洲一区二区 | 日韩色高清 | 在线看的毛片 | 久久久久99精品成人片三人毛片 | 日本韩国中文字幕 | 天天干天天在线 | 国产精品12| japanesexxx乱女另类 | 国产精品国产三级国产 | 99精品黄色片免费大全 | 人人狠狠综合久久亚洲婷 | 五月婷婷深开心 | 中文字幕丰满人伦在线 | 成人av影院在线观看 | 成人av免费在线播放 | 国产香蕉久久 | 天天射,天天干 | 国内精品亚洲 | 亚洲精品视频久久 | 国产你懂的在线 | 青青草国产精品视频 | 在线观看免费视频你懂的 | 欧美福利网址 | 中日韩欧美精彩视频 | av大全免费在线观看 | 精品国产一区二区三区四区vr | 最近av在线| 丝袜美女在线观看 | 日韩精品中文字幕在线不卡尤物 | 丝袜av一区 | 国产片网站 | 超碰97在线资源 | 亚洲每日更新 | 国产不卡视频在线 | 久草视频网| 综合av在线 | 四虎影视成人永久免费观看视频 | 精品视频亚洲 | 午夜a区 | 国产精品久久久久免费观看 | 在线视频日韩一区 | 激情一区二区三区欧美 | 在线观看视频亚洲 | 中午字幕在线观看 | 在线亚州 | 日韩在线观看的 | 国产小视频91 | 欧美精品第一 | 亚洲国产精品va在线 | 韩国av永久免费 | 欧美日韩精品在线播放 | 99热国产在线中文 | av在线免费不卡 | 狠狠操电影网 | 欧洲高潮三级做爰 | 狠狠久久婷婷 | 久久毛片网 | 国产91学生粉嫩喷水 | 久操97| 中文字幕五区 | 久久久久久久久久久久久国产精品 | 国产国产人免费人成免费视频 | 特级毛片爽www免费版 | 一区中文字幕 | 五月婷婷六月丁香 | 草草草影院| 国产精品久久久久久久久久新婚 | 国产91影院 | 精品嫩模福利一区二区蜜臀 | 黄免费在线观看 | 91视频中文字幕 | 亚洲精品在线播放视频 | 香蕉视频日本 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 国产一区二区高清视频 | 青青看片 | 天堂av在线中文在线 | 国产色视频网站 | 91在线中字| 草久在线观看 | 五月婷婷毛片 | 99热这里只有精品国产首页 | 在线观看国产日韩 | 久久精品理论 | 日本女人的性生活视频 | 国产二区精品 | 国产一区二区在线免费 | 黄色软件网站在线观看 | 亚洲国产中文字幕在线观看 | 亚洲国产日韩av | 亚洲欧美日韩国产一区二区三区 | 91丨九色丨91啦蝌蚪老版 | 日韩精品无码一区二区三区 | 日韩理论在线播放 | 在线成人观看 | 久久99久| 天天射天天艹 | 99精品国产成人一区二区 | 国产精品美女久久久久久网站 | 国产精品久久久久aaaa九色 | 黄色aa久久 | 亚洲精品久久久久www | 99久久精品久久久久久清纯 | 国产精久久久久久久 | 夜夜夜夜爽 | 亚洲精品在线视频网站 | 香蕉视频在线播放 | 精品亚洲国产视频 | 日韩精品欧美一区 | 人人玩人人添人人 | 日韩理论在线观看 | 久久午夜精品 | 国产精品激情偷乱一区二区∴ | 97视频免费播放 | 波多野结衣视频一区二区三区 | 99久久国产免费看 | 免费在线观看午夜视频 | 国产一级免费在线观看 | 成人av一区二区兰花在线播放 | avove黑丝 | 在线视频91 | 国产精品成人自拍 | 在线99热 | 日韩精品中文字幕在线观看 | 91激情视频在线观看 | 久久99国产精品久久99 | 国产精品欧美激情在线观看 | 成人一级片在线观看 | 欧美极品xxxxx | 中国一级特黄毛片大片久久 | 国产亚洲精品久久久久久 | www.夜夜操 | 日韩免费av网址 | 国产一级黄 | 色小说av | 一区二区三区四区在线 | 揉bbb玩bbb少妇bbb | 日韩精品免费一区二区三区 | 欧美激情精品久久久 | 国产黄色片在线免费观看 | 亚洲高清资源 | 在线成人高清电影 | 久久香蕉影视 | 96视频免费在线观看 | 国产91欧美 | 中文字幕在线观看第一区 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 麻豆91精品| 毛片网在线 | 手机av在线免费观看 | 久久国产精品99久久久久 | 亚洲欧美色婷婷 | 天天综合导航 | 国产毛片久久 | 黄色网址在线播放 | 99热这里只有精品在线观看 | 狂野欧美激情性xxxx欧美 | 国产免费av一区二区三区 | 日日草视频 | 九九免费观看视频 | 国产精品久久99综合免费观看尤物 | 精品免费观看 | 色综合咪咪久久网 | 国产h片在线观看 | 国产精品一区二区果冻传媒 | 国产亚洲精品久久久久久久久久久久 | 国产中文字幕在线看 | 久久色在线播放 | 狠狠干 狠狠操 | 国产免费观看高清完整版 | 婷婷色影院 | 激情av资源 | 99久久久国产精品免费观看 | 久久精品五月 | 日日日日 | 区一区二区三区中文字幕 | 成人天堂网 | 丁香婷婷激情国产高清秒播 | 九九九九九九精品任你躁 | 久久精品com| 久久久久久国产精品美女 | 丁香婷婷激情网 | 国产亚洲精品久久 | 亚洲精品一区二区在线观看 | 日韩亚洲精品电影 | 精品一区av | 国产精品久久久久久久久免费 | 成人av在线播放网站 | 日韩 国产 | 国产专区欧美专区 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 国产中文视频 | 国产午夜精品一区二区三区欧美 | 一级黄视频 | 在线观看黄色小视频 | 手机在线看永久av片免费 | 国产成人久久 | 国产小视频网站 | 在线精品视频免费观看 | 久久久久久毛片精品免费不卡 | 国产精品久久久久久久久久新婚 | 婷婷综合五月天 | 成人在线播放免费观看 | 波多野结衣一区三区 | 日韩av片免费在线观看 | 最新av在线播放 | 亚洲 欧美日韩 国产 中文 | 97精产国品一二三产区在线 | 亚洲成人免费在线观看 | 国产日韩一区在线 | 久久免费视屏 | 日韩av在线小说 | 一二三区av | 日韩三级av | 国产精品18久久久久久久久久久久 | 国产精品99久久久久的智能播放 | 欧美成年性 | 欧美 日韩 性 | 国产婷婷视频在线 | 热re99久久精品国产66热 | 久久九九视频 | 狠狠狠综合 | 国产高清视频网 | 欧美日韩电影在线播放 | www麻豆视频 | 日韩免费一级a毛片在线播放一级 | 中文字幕永久 | 国产成人精品一区二区在线观看 | 日日夜夜免费精品视频 | 九九综合在线 | 欧美一区二区免费在线观看 | 日韩av高潮 | 久草手机视频 | 久久av影视 | 999久久久免费精品国产 | www.com久久久 | 很污的网站 | 国产精品福利久久久 | 91网页版在线观看 | 一区二区三区www | 国产高清成人av | 激情开心站 | 456成人精品影院 | 夜夜夜影院 | 欧美一级片在线播放 | 美女视频黄在线观看 | 亚洲一区二区高潮无套美女 | 麻豆传媒视频在线播放 | 天堂在线一区二区 | 黄色影院在线播放 | 一级做a爱片性色毛片www | 日韩h在线观看 | 午夜在线日韩 | 麻花豆传媒mv在线观看网站 | 婷婷六月天在线 | 国产成年免费视频 | 黄色的网站免费看 | 国产三级国产精品国产专区50 | 成年人视频在线免费播放 | 久久视奸 | 在线看中文字幕 | 一 级 黄 色 片免费看的 | 黄色日批网站 | 成人午夜剧场在线观看 | 一级片色播影院 | 99久久99久久精品免费 | 9在线观看免费高清完整版 玖玖爱免费视频 | 国产91粉嫩白浆在线观看 | 看片黄网站 | 成人毛片一区二区三区 | 91xav | 在线免费黄色 | 色综合久久88色综合天天 | 日本高清中文字幕有码在线 | 永久免费看av | 99久久久国产精品 | 久久婷婷五月综合色丁香 | 一区二区三区高清在线 | 97超碰在线播放 | 啪啪激情网 | 亚洲精品在线观看视频 | 色五丁香 | 在线观看视频你懂得 | 夜夜操天天干 | a亚洲视频 | 欧美久久九九 | 久久精品亚洲精品国产欧美 | av在线播放中文字幕 | 久99精品| 伊人资源视频在线 | 亚洲精品美女久久久 | av免费看电影 | 91成熟丰满女人少妇 | 超碰97在线看 | 正在播放一区二区 | 国产精品久久99综合免费观看尤物 | av网站在线免费观看 | 国产精品久久久久久久久久不蜜月 | 亚洲精品玖玖玖av在线看 | 国产高清区 | 九九精品在线观看 | 超碰在线中文字幕 | 色鬼综合网| 在线色亚洲 | 日韩网站一区 | 国产激情久久久 | 久久精品这里热有精品 | www.888.av| 又黄又爽免费视频 | 日韩免费高清在线观看 | 黄色特级一级片 | 97在线视频免费看 | 五月天开心 | 免费碰碰| 国产精品国产三级国产专区53 | 免费视频成人 | 成人97视频一区二区 | www.av中文字幕.com | 久久99精品久久久久久秒播蜜臀 | 少妇按摩av | 日本系列中文字幕 | 国产色女| 在线a视频免费观看 | 91九色在线视频 | 91黄色影视 | 天天干干| 日韩中文幕 | 六月丁香婷婷在线 | 国产成人精品久久亚洲高清不卡 | av网站在线观看播放 | 久久免费的精品国产v∧ | 波多野结衣在线视频免费观看 | 日韩二区三区在线观看 | 欧美五月婷婷 | av网站免费线看精品 | 99精品视频精品精品视频 | 亚洲深爱激情 | 国产69精品久久99的直播节目 | 美女久久久久久久久久 | 字幕网av| 国产精品一区二区果冻传媒 | 99精品视频免费在线观看 | 久久人操 | 男女视频国产 | 国产精品黑丝在线观看 | 久久精品一区二区三区中文字幕 | 一区二区三区视频网站 | 欧美性爽爽 | 精品国产成人av在线免 | 国产精品久久久区三区天天噜 | 成人av午夜 | 成人91在线观看 | 日韩国产精品毛片 | 色综合www | 欧美巨大荫蒂茸毛毛人妖 | 国产xx视频 | 九九久久国产 | 中文字幕在线播放一区二区 | 五月婷婷在线播放 | av激情五月| 操操操人人人 | 91福利影院在线观看 | 日韩区视频 | 免费人成在线观看网站 | 国产精品成人久久 | 国产在线观看不卡 | 国产成人久久久久 | 99精品免费久久久久久久久日本 | 国产美女在线观看 | 精品国产一区二区三区久久久 | 久久久精品国产一区二区 | 国产99久久久国产精品 | 免费在线观看成人av | 中文字幕日韩精品有码视频 | 国产亚洲精品久久19p | 久久精品第一页 | 免费日韩 精品中文字幕视频在线 | 五月天婷婷免费视频 | 日本精品视频在线播放 | 五月导航 | www.久久精品视频 | 久久久久久国产精品久久 | 黄色av成人在线 | 天天翘av | 免费中文字幕在线观看 | 深夜免费福利网站 | 欧美看片| 亚洲国产精品影院 | 国产午夜精品av一区二区 | 久久视频一区二区 | 婷婷激情综合五月天 | 国产综合香蕉五月婷在线 | 最新av在线网站 | 国产高清久久久久 | 黄色高清视频在线观看 | 国产精品18久久久久久久久久久久 | 日韩免费一级a毛片在线播放一级 | www.天天干 | 亚洲欧洲精品一区二区精品久久久 | 日韩黄色免费电影 | 91爱爱免费观看 | 日日爽日日操 | 久久99久国产精品黄毛片入口 | 女人高潮特级毛片 | 久久久五月天 | 久久久国产一区二区三区四区小说 | 友田真希x88av | 日韩理论在线观看 | 日韩理论在线播放 | 久久午夜视频 | 国产成人精品一区二区三区福利 | 精品少妇一区二区三区在线 | 欧洲色吧| 美女av电影| 免费情缘 | 日韩综合色 | 国产成人福利在线 | 一区三区视频在线观看 | 国产成人av免费在线观看 | 精品亚洲一区二区三区 | 999成人网 | 欧美一级片在线观看视频 | 狠狠夜夜 | 国产在线高清精品 | 国产精品久久久久久久久久99 | 国产老妇av | 久草在线视频新 | 狠狠操狠狠干天天操 | 日韩一区二区三区在线观看 | 久久精品成人热国产成 | 亚洲精品www久久久久久 | 欧美极品在线播放 | 日韩久久影院 | 色在线高清 | 亚洲精品久久在线 | 91视频在线免费看 | 久久精品99精品国产香蕉 | 中文字幕久久久精品 | 国产午夜视频在线观看 | 欧美日韩国产综合一区二区 | 在线视频国产区 | 国产中文字幕亚洲 | 国产在线一线 | 又黄又刺激又爽的视频 | 成人免费大片黄在线播放 | 欧美日韩不卡在线视频 | 欧美午夜精品久久久久 | 中文字幕在线精品 | 丁香婷婷激情啪啪 | 狠狠色丁香婷婷综合久小说久 | 美女黄频 | 色综合天天视频在线观看 | 久草精品网| 国产精品午夜在线观看 | 在线国产99 | 深夜免费福利视频 | 国产伦精品一区二区三区四区视频 | 国产精品淫 | 亚洲国产婷婷 | 欧美日韩国产综合一区二区 | 色婷婷激情四射 | 久久1区 | 偷拍区另类综合在线 | 亚洲专区在线播放 | 成人黄色在线 | 欧美日韩在线免费观看 | 久久99精品久久久久久 | 欧美一级片免费播放 | 久草观看视频 | 亚洲日本一区二区在线 | 日本狠狠干 | 99国产在线视频 | 色a网| 99久高清在线观看视频99精品热在线观看视频 | 天天搞天天干天天色 | 久久超碰99| 91理论片午午伦夜理片久久 | 中文乱幕日产无线码1区 | 四虎国产精品永久在线国在线 | 久久久久美女 | 欧美大片aaa | www.色com| 久久黄色美女 | www日日夜夜| 超级碰碰免费视频 | 三级免费黄 | 国产一级小视频 | 国产午夜精品一区二区三区四区 | 人人澡人人澡人人 | 日本免费久久高清视频 | 日本精品久久久一区二区三区 | 97色视频在线 | 一区二区精 | 日韩在线视频精品 | 婷婷伊人网 | 一级黄色电影网站 | av一级片在线观看 | 欧美片网站yy | 久久综合偷偷噜噜噜色 | 韩国av一区二区三区在线观看 | 欧美日韩视频免费 | 国产中文字幕在线播放 | 亚洲无毛专区 | 色网站视频 | 在线中文字幕电影 | 麻豆94tv免费版 | 在线观看完整版 | 日韩av手机在线观看 | 中文字幕资源在线 | 日日干激情五月 | 日本aaaa级毛片在线看 | 国产高清在线免费 | 色资源网免费观看视频 | 久久国产免费视频 | 色综合天天射 | 久久国产精品99久久久久 | 亚洲精品国产自产拍在线观看 | 日韩在线观看网站 | 波多野结衣电影久久 | 综合色天天 | 国产精品久久久一区二区三区网站 | 国产精品国产亚洲精品看不卡 | 中文字幕日韩免费视频 | 在线观看成年人 | 亚洲精品一区二区三区在线观看 | 在线免费高清视频 | 久久欧美精品 | 九九在线视频免费观看 | 久草视频在线新免费 | 亚洲精品国产成人 | 久久综合九色综合久久久精品综合 | 国产亚洲精品久久久久久大师 | 日韩av黄 | 天堂网中文在线 | 99 视频 高清 | 九九爱免费视频在线观看 | 亚洲精品18p| 日韩成人在线一区二区 | 久久毛片高清国产 | 婷婷六月久久 | 亚洲精品人人 | 麻豆成人小视频 | 日韩| 曰韩在线 | 国产精品视频免费观看 | 婷婷午夜 | 成 人 黄 色 视频播放1 | 日日夜日日干 | 在线观看麻豆av | 91禁在线观看 | 日日干av | 麻豆视频在线看 | 久久99婷婷| 国产1区在线观看 | 亚洲精品白浆高清久久久久久 | 丰满少妇一级片 | 久久字幕精品一区 | 国产亚洲精品精品精品 | 91久久丝袜国产露脸动漫 | 又黄又爽免费视频 | 91香蕉亚洲精品 | 天天操福利视频 | 国产一区二区电影在线观看 | 久久久久综合网 | 婷婷性综合 | 中文字幕观看视频 | 国产精品麻豆视频 | 粉嫩av一区二区三区免费 | 久久午夜网 | 伊人小视频 | 久久伊人操 | 国产永久网站 | 国产经典三级 | 国产在线播放一区二区三区 | 丁香六月在线 | 成人a级大片 | 国产精品久久久久久久久久白浆 | 久久影院一区 | 97色在线观看免费视频 | 亚洲精品福利在线观看 | 最新国产精品拍自在线播放 | 91九色丨porny丨丰满6 | 97国产一区二区 | 国产精品亚洲精品 | 韩国在线一区 | 亚洲精品国产综合久久 | 亚洲乱码中文字幕综合 | 激情狠狠干 | 国产在线不卡精品 | 亚洲欧美视频在线播放 | 国产资源在线免费观看 | 日本天天操 | 黄色网在线播放 | 国产亚洲成人网 | 成+人+色综合 | 天天做天天爱夜夜爽 | 99精品视频在线免费观看 | 91桃色在线播放 | 欧美色婷 | 韩国三级av在线 | 揉bbb玩bbb少妇bbb | 成人毛片一区 | 精品一区二区在线免费观看 | 中文字幕在线播放av | 国产91在线 | 美洲 | 免费瑟瑟网站 | 久久在线看| 亚洲精品在线网站 | 中文字幕电影网 | 久久免费视频一区 | 成人久久精品视频 | 国产五码一区 | 午夜美女福利 | 久久免费在线观看 | 骄小bbw搡bbbb揉bbbb | 欧美了一区在线观看 | 毛片久久久 | 精品 一区 在线 | 玖玖玖国产精品 | 精品一区精品二区 | 日韩一级片网址 | 香蕉影视在线观看 | 国产福利精品在线观看 | av电影中文字幕 | 99视频国产精品免费观看 | 精品在线观看一区二区三区 | 中文字幕视频观看 | 欧美男男激情videos | 在线观看国产麻豆 | 91麻豆精品国产自产在线 | 中文字幕亚洲欧美 | 久草在线视频网站 | 精品毛片久久久久久 | 美女视频黄网站 | 亚洲激情在线观看 | 国产日韩精品一区二区在线观看播放 | 国产小视频91| 国产18精品乱码免费看 | 91精品国产欧美一区二区成人 | 国内精品久久影院 | 国产成人一区二区三区免费看 | 黄色视屏在线免费观看 | 久草在线最新视频 | 久久99精品国产91久久来源 | 色婷婷狠狠五月综合天色拍 | 香蕉视频91 | 丁香婷婷激情网 | 91 在线视频播放 | 毛片一二区 | 手机av电影在线观看 | 青青草国产精品视频 | 久久在线视频在线 | 成人免费看片网址 | 激情五月av | 中文字幕成人一区 | 狠狠久久综合 | 日韩av一区二区在线 | 国产在线97 | 8x成人在线 | 91麻豆精品国产91 | 色网站在线看 | 日韩三级视频在线看 | 91手机视频 | 国产美女精品 | 国产理论片在线观看 | 在线观看视频 | 久久久久久久久久电影 | 欧美日韩一区三区 | 色播亚洲婷婷 | 亚洲欧美国产视频 | 网址你懂的在线观看 | 手机看片 | 免费在线观看中文字幕 | 一级α片| 97超视频免费观看 | 亚洲免费在线播放视频 | 国产婷婷久久 | 精品字幕| 9在线观看免费高清完整版 玖玖爱免费视频 | 日韩精品专区在线影院重磅 | 视频在线观看99 | 亚洲婷婷在线视频 | 欧美激情综合五月 | 六月丁香六月婷婷 | 久久激情小说 | 欧美日韩性生活 | 国产小视频在线免费观看视频 | 久久夜色精品国产欧美乱 | 在线观看日韩一区 | 激情久久网 | 午夜影院一级片 | 99热在线这里只有精品 | 国产综合福利在线 | 91中文在线| 国产在线国偷精品产拍 | 奇米影视8888 | 亚洲 综合 激情 | 亚州视频在线 | 美女激情影院 | 三级毛片视频 | 国产69精品久久久久久久久久 | 日韩精品资源 | 久久精品波多野结衣 | 久久尤物电影视频在线观看 | 911亚洲精品第一 | 欧美成人精品三级在线观看播放 | 免费黄在线观看 | 波多野结衣视频一区 | 亚洲一区二区三区毛片 | 天天射一射 | 国产精品美女久久久久久久久久久 | 亚洲资源在线网 | 国产高清绿奴videos | 999久久久久久久久6666 | 在线免费性生活片 | 国产视频中文字幕在线观看 | av大片免费 | 波多野结衣在线观看一区二区三区 | 精品欧美一区二区精品久久 | 亚洲欧美国产视频 | 中文字幕在线观看免费高清电影 | 欧美日韩视频免费看 | 国产福利一区二区三区视频 | 国产精品免费观看网站 | 国产视频99 | 噜噜色官网 | 国产精品久久久久久久久久久久午 | 天堂久久电影网 | 久久99操| 免费视频xnxx com | 亚洲视频精选 | 亚洲人人网 | 精品国产一区二区三区四区在线观看 | 日韩电影中文字幕在线观看 | 国内精品视频在线 | 极品久久久 | 久久免费资源 | 国产美女黄网站免费 | 欧美色婷 | 精品专区一区二区 | 亚洲伦理一区 | 特级黄录像视频 | 国产麻豆剧果冻传媒视频播放量 | 欧美经典久久 | a久久久久久 | 激情小说 五月 | 久久久九九 | 在线观看av大片 | 国产精品2020 | 国产在线视频在线观看 | 欧美美女视频在线观看 | 免费高清在线视频一区· | 曰本三级在线 | 天天操夜夜操国产精品 | 国产美女免费观看 | 黄色成年 | 三级av免费看 | 日韩高清免费在线 | 日韩午夜大片 | 国产999在线| 在线涩涩 | 午夜精品中文字幕 | 黄www在线观看 | 久久成人视屏 | 日韩精品一区二区三区第95 | 久久字幕网 | 91麻豆看国产在线紧急地址 | 一二三区高清 | 中文字幕不卡在线88 | 婷婷丁香九月 | 国产精品福利久久久 | 国产成年免费视频 | 男女精品久久 | 一区二区三区高清 | 国产麻豆剧传媒免费观看 | 丁香久久久 | 日韩三级一区 | 激情五月伊人 | www日 | 一区二区中文字幕在线播放 | 在线观看www91| 999久久久久久久久 69av视频在线观看 | 国产又粗又猛又色又黄网站 | 在线播放亚洲 | 日韩乱码在线 | 精品视频一区在线 | 久一网站| 欧美久久九九 | 国产精品粉嫩 | 久久精品二区 | 国产精品嫩草影院99网站 | 欧美精品一区二区蜜臀亚洲 | 五月婷婷色丁香 | 成年人看片网站 | 91九色在线播放 | 免费福利片2019潦草影视午夜 | 久久黄色免费视频 | 国产欧美中文字幕 | 久草av在线播放 | 成人网444ppp| 1000部国产精品成人观看 | 麻花天美星空视频 | 成人久久免费视频 | 亚洲视频免费在线观看 | 激情大尺度视频 | 偷拍区另类综合在线 | 国产香蕉在线 | 四虎www. | 亚洲黄色网络 | 久久久99精品免费观看app | 丁香九月激情综合 | 91麻豆精品国产午夜天堂 | 99精品区 | 91麻豆精品一区二区三区 | 欧美激情视频在线观看免费 | 中文字幕有码在线 | 黄网站色成年免费观看 | 成人免费看视频 | 国产成人精品999在线观看 | 国产原创91 | 欧美日本在线视频 | 免费看黄色毛片 | 天天精品视频 | 国产精品原创av片国产免费 | 亚洲综合成人婷婷小说 | 青青啪 | www成人av| 91完整版| 免费网站v | 欧美精品网站 | 丝袜网站在线观看 | 超碰99在线 | 99热 精品在线 | 欧美日韩精品在线观看视频 | 日韩精品一区二区三区水蜜桃 | 久久综合狠狠综合久久狠狠色综合 | 亚洲精品小视频在线观看 | 91网在线看 | 久久精品中文字幕一区二区三区 | 国产精品久久久久久久av大片 | 亚洲综合色婷婷 | 女人18毛片a级毛片一区二区 | av免费成人| 国产精品久久久久久欧美 | 在线观看视频三级 | 精品国产免费人成在线观看 | 国产又粗又硬又爽的视频 | 欧美成人播放 | 国产馆在线播放 | .国产精品成人自产拍在线观看6 | 激情视频免费观看 | 国产精品成久久久久 | 天天干天天射天天爽 | 国产欧美精品一区二区三区 | 精品国产一区二区三区免费 | av观看网站 | ,久久福利影视 | 色综合中文综合网 | 午夜精品三区 | 国产精品乱码久久久 | 亚洲精品美女免费 | 中文字幕黄色网址 |