日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux-Android启动之Init进程前传

發(fā)布時(shí)間:2023/12/15 linux 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux-Android启动之Init进程前传 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

????? 對(duì)Linux-Android系統(tǒng)的啟動(dòng)做了一些分析,下面的一篇文章側(cè)重講述Linux啟動(dòng)過程中函數(shù)Start_kernel()被調(diào)用之前的一些分析,同時(shí)也對(duì)函數(shù)Start_kernel()之后的代碼流程作了概述,我希望關(guān)于Linux-Android系統(tǒng)的啟動(dòng)的專題能夠繼續(xù)地寫下去,哈哈。如果有不正確或者不完善的地方,歡迎前來拍磚留言或者發(fā)郵件到guopeixin@126.com進(jìn)行討論,現(xiàn)行謝過。

?

一. 內(nèi)核自引導(dǎo)程序


1. 內(nèi)核zimage自解壓

?這部分代碼在arch/${arch}/boot/compressed/head.S中,該文件的代碼在zimage的生成過程中,將會(huì)被打包到zimage中。
?head.S會(huì)首先初始化自解壓相關(guān)的如內(nèi)存等環(huán)境,接下來就去調(diào)用decompress_kernel去解壓,并調(diào)用call_kernel函數(shù)去啟動(dòng)vmlinux。
?去下面僅僅列舉一下head.S文件中最重要的部分:
----------------------------------------------------------------
/*
?* We're not in danger of overwriting ourselves.? Do this the simple way.
?*
?* r4???? = kernel execution address
?* r7???? = architecture ID
?*/
wont_overwrite:?mov?r0, r4
??mov?r3, r7
??bl?decompress_kernel
??b?call_kernel
...
call_kernel:?bl?cache_clean_flush
??bl?cache_off
??mov?r0, #0???@ must be zero
??mov?r1, r7???@ restore architecture number
??mov?r2, r8???@ restore atags pointer
??mov?pc, r4???@ call kernel
----------------------------------------------------------------
?其中函數(shù)decompress_kernel在arch/${arch}/boot/compressed/misc.c中實(shí)現(xiàn),功能就是完成zimage鏡像的自解壓,顯然該自解壓的過程需

要配置相應(yīng)的解壓地址等,這部分代碼如下:
----------------------------------------------------------------
ulg
decompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
??? int arch_id)
{
?output_data??= (uch *)output_start;?/* Points to kernel start */
?free_mem_ptr??= free_mem_ptr_p; /* 顯然,這個(gè)地址是從通過寄存器傳進(jìn)來的 */
?free_mem_end_ptr?= free_mem_ptr_end_p;
?__machine_arch_type?= arch_id;

?arch_decomp_setup();

?makecrc();
?putstr("Uncompressing Linux...");
?gunzip();
?putstr(" done, booting the kernel./n");
?return output_ptr;
}
----------------------------------------------------------------
?調(diào)用call_kernel后首先關(guān)閉cache,然后就跳轉(zhuǎn)到vmlinux入口去執(zhí)行并將系統(tǒng)的控制權(quán)交給了vmlinux。


2. 內(nèi)核vmlinux入口

>> vmlinux的編譯簡(jiǎn)單描述
?因?yàn)檫@里會(huì)牽扯到兩個(gè)文件head.S和head-nommu.S,所以下面簡(jiǎn)單的描述一下vmlinux的生成過程。來看一下/arch/${arch}/kernel/makefile

,在該文件的最后腳本如下:
----------------------------------------------------------------
#
# Makefile for the linux kernel.
#

AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)

ifdef CONFIG_DYNAMIC_FTRACE
CFLAGS_REMOVE_ftrace.o = -pg
endif

# Object file lists.

obj-y??:= compat.o elf.o entry-armv.o entry-common.o irq.o /
???? process.o ptrace.o setup.o signal.o /
???? sys_arm.o stacktrace.o time.o traps.o

obj-$(CONFIG_ISA_DMA_API)?+= dma.o
obj-$(CONFIG_ARCH_ACORN)?+= ecard.o
obj-$(CONFIG_FIQ)??+= fiq.o
obj-$(CONFIG_MODULES)??+= armksyms.o module.o
obj-$(CONFIG_ARTHUR)??+= arthur.o
obj-$(CONFIG_ISA_DMA)??+= dma-isa.o
obj-$(CONFIG_PCI)??+= bios32.o isa.o
obj-$(CONFIG_SMP)??+= smp.o
obj-$(CONFIG_DYNAMIC_FTRACE)?+= ftrace.o
obj-$(CONFIG_KEXEC)??+= machine_kexec.o relocate_kernel.o
obj-$(CONFIG_KPROBES)??+= kprobes.o kprobes-decode.o
obj-$(CONFIG_ATAGS_PROC)?+= atags.o
obj-$(CONFIG_OABI_COMPAT)?+= sys_oabi-compat.o
obj-$(CONFIG_ARM_THUMBEE)?+= thumbee.o
obj-$(CONFIG_KGDB)??+= kgdb.o

obj-$(CONFIG_CRUNCH)??+= crunch.o crunch-bits.o
AFLAGS_crunch-bits.o??:= -Wa,-mcpu=ep9312

obj-$(CONFIG_CPU_XSCALE)?+= xscale-cp0.o
obj-$(CONFIG_CPU_XSC3)??+= xscale-cp0.o
obj-$(CONFIG_IWMMXT)??+= iwmmxt.o
AFLAGS_iwmmxt.o???:= -Wa,-mcpu=iwmmxt

ifneq ($(CONFIG_ARCH_EBSA110),y)
? obj-y??+= io.o
endif

head-y???:= head$(MMUEXT).o
obj-$(CONFIG_DEBUG_LL)?+= debug.o

extra-y := $(head-y) init_task.o vmlinux.lds
----------------------------------------------------------------
?可以看到,文件的結(jié)束位置有一行代碼“head-y???:= head$(MMUEXT).o”,其中MMUEXT在/arch/${arch}/makefile中

定義,實(shí)際上對(duì)于沒有mmu的處理器,MMUEXT就是nommu,而對(duì)于包含mmu的處理器,它的值是空,參照MMUEXT在/arch/${arch}/makefile中的相關(guān)代碼

如下:
----------------------------------------------------------------
# defines filename extension depending memory manement type.
ifeq ($(CONFIG_MMU),)
MMUEXT??:= -nommu
endif
----------------------------------------------------------------
?所以對(duì)于諸如S3C6410之類的包含MMU的處理器,實(shí)際上最終vmlinux開始位置的代碼就是/arch/${arch}/kernel/head.S.

>> head.S文件的分析
?需要注意的是,對(duì)于該文件的描述,一般的書籍上可能是僅僅對(duì)老版本的linux系統(tǒng)進(jìn)行了分析,就是說該文件結(jié)束位置直接調(diào)用了

start_kernel?函數(shù),至此開始執(zhí)行c代碼。其實(shí),并不是這樣的。
?下面簡(jiǎn)單的列寫一下head.S的內(nèi)容:
----------------------------------------------------------------/*
?* Kernel startup entry point.
?* ---------------------------
?*
?* This is normally called from the decompressor code.? The requirements
?* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
?* r1 = machine nr, r2 = atags pointer.
?*
?* This code is mostly position independent, so if you link the kernel at
?* 0xc0008000, you call this at __pa(0xc0008000).
?*
?* See linux/arch/arm/tools/mach-types for the complete list of machine
?* numbers for r1.
?*
?* We're trying to keep crap to a minimum; DO NOT add any machine specific
?* crap here - that's what the boot loader (or in extreme, well justified
?* circumstances, zImage) is for.
?*/
?.section ".text.head", "ax"
ENTRY(stext)
?msr?cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
??????@ and irqs disabled
?mrc?p15, 0, r9, c0, c0??@ get processor id
?bl?__lookup_processor_type??@ r5=procinfo r9=cpuid
?movs?r10, r5????@ invalid processor (r5=0)?
?beq?__error_p???@ yes, error 'p'
?bl?__lookup_machine_type??@ r5=machinfo
?movs?r8, r5????@ invalid machine (r5=0)?
?beq?__error_a???@ yes, error 'a'
?bl?__vet_atags
?bl?__create_page_tables

?/*
? * The following calls CPU specific code in a position independent
? * manner.? See arch/arm/mm/proc-*.S for details.? r10 = base of
? * xxx_proc_info structure selected by __lookup_machine_type
? * above.? On return, the CPU will be ready for the MMU to be
? * turned on, and r0 will hold the CPU control register value.
? */
?ldr?r13, __switch_data??@ address to jump to after
??????@ mmu has been enabled
?adr?lr, __enable_mmu??@ return (PIC) address
?add?pc, r10, #PROCINFO_INITFUNC
ENDPROC(stext)

#if defined(CONFIG_SMP)
ENTRY(secondary_startup)
?/*
? * Common entry point for secondary CPUs.
? *
? * Ensure that we're in SVC mode, and IRQs are disabled.? Lookup
? * the processor type - there is no need to check the machine type
? * as it has already been validated by the primary processor.
? */
?msr?cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
?mrc?p15, 0, r9, c0, c0??@ get processor id
?bl?__lookup_processor_type
?movs?r10, r5????@ invalid processor?
?moveq?r0, #'p'???@ yes, error 'p'
?beq?__error

?/*
? * Use the page tables supplied from? __cpu_up.
? */
?adr?r4, __secondary_data
?ldmia?r4, {r5, r7, r13}??@ address to jump to after
?sub?r4, r4, r5???@ mmu has been enabled
?ldr?r4, [r7, r4]???@ get secondary_data.pgdir
?adr?lr, __enable_mmu??@ return address
?add?pc, r10, #PROCINFO_INITFUNC?@ initialise processor
??????@ (return control reg)
ENDPROC(secondary_startup)

?/*
? * r6? = &secondary_data
? */
ENTRY(__secondary_switched)
?ldr?sp, [r7, #4]???@ get secondary_data.stack
?mov?fp, #0
?b?secondary_start_kernel
ENDPROC(__secondary_switched)

?.type?__secondary_data, %object
__secondary_data:
?.long?.
?.long?secondary_data
?.long?__secondary_switched
#endif /* defined(CONFIG_SMP) */

/*
?* Setup common bits before finally enabling the MMU.? Essentially
?* this is just loading the page table pointer and domain access
?* registers.
?*/
__enable_mmu:
#ifdef CONFIG_ALIGNMENT_TRAP
?orr?r0, r0, #CR_A
#else
?bic?r0, r0, #CR_A
#endif
#ifdef CONFIG_CPU_DCACHE_DISABLE
?bic?r0, r0, #CR_C
#endif
#ifdef CONFIG_CPU_BPREDICT_DISABLE
?bic?r0, r0, #CR_Z
#endif
#ifdef CONFIG_CPU_ICACHE_DISABLE
?bic?r0, r0, #CR_I
#endif
?mov?r5, #(domain_val(DOMAIN_USER, DOMAIN_MANAGER) | /
??????? domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | /
??????? domain_val(DOMAIN_TABLE, DOMAIN_MANAGER) | /
??????? domain_val(DOMAIN_IO, DOMAIN_CLIENT))
?mcr?p15, 0, r5, c3, c0, 0??@ load domain access register
?mcr?p15, 0, r4, c2, c0, 0??@ load page table pointer
?b?__turn_mmu_on
ENDPROC(__enable_mmu)

/*
?* Enable the MMU.? This completely changes the structure of the visible
?* memory space.? You will not be able to trace execution through this.
?* If you have an enquiry about this, *please* check the linux-arm-kernel
?* mailing list archives BEFORE sending another post to the list.
?*
?*? r0? = cp#15 control register
?*? r13 = *virtual* address to jump to upon completion
?*
?* other registers depend on the function called upon completion
?*/
?.align?5
__turn_mmu_on:
?mov?r0, r0
?mcr?p15, 0, r0, c1, c0, 0??@ write control reg
?mrc?p15, 0, r3, c0, c0, 0??@ read id reg
?mov?r3, r3
?mov?r3, r3
?mov?pc, r13
ENDPROC(__turn_mmu_on)

#include "head-common.S"
----------------------------------------------------------------
?可能大家注意到,上面有大段的文字是secondary_startup以及CONFIG_SMP等,其實(shí)這個(gè)是對(duì)于SMP系統(tǒng)才會(huì)采用的代碼。眾所周知,SMP是對(duì)

稱多處理的簡(jiǎn)稱,是指系統(tǒng)中使用了一組處理器,各CPU之間共享內(nèi)存子系統(tǒng)和總線結(jié)構(gòu),對(duì)應(yīng)的有非對(duì)稱多處理,嵌入式設(shè)備上我們并不會(huì)使用到

SMP的功能。
?乍一看,無論如何也調(diào)用不到網(wǎng)上所謂的start_kernel函數(shù)中,大家注意看“l(fā)dr?r13, __switch_data”,這里就是將函數(shù)__switch_data的

地址保存到r13,并在函數(shù)__enable_mmu-->__turn_mmu_on結(jié)束位置的“mov?pc, r13”中將__switch_data調(diào)用起來。而函數(shù)__switch_data是實(shí)

現(xiàn)在/arch/${arch}/kernel/head-common.S中的一個(gè)函數(shù),而函數(shù)start_kernel就是由__switch_data調(diào)用起來的。
?你一定在奇怪,那么函數(shù)__enable_mmu是怎么調(diào)用起來的呢,呵呵,你簡(jiǎn)直是太聰明、太細(xì)心了。那趕緊聽我跟你說吧,代碼“add?pc,

r10, #PROCINFO_INITFUNC”將會(huì)跳轉(zhuǎn)到/arch/${arch}/mm/proc-arn-926.S中的初始化函數(shù)__arm926_setup中,并在該函數(shù)結(jié)束的位置以“mov?pc,

lr”的方式調(diào)用__enable_mmu,千萬別告訴我你忘記了前面提到的__enable_mmu的值保存在lr中哦。
?至于為什么代碼“add?pc, r10, #PROCINFO_INITFUNC”將會(huì)跳轉(zhuǎn)到/arch/${arch}/mm/proc-arn-926.S中的初始化函數(shù)__arm926_setup

中,我這里就不列舉了。可以參照后面我轉(zhuǎn)載的一篇文章。
----------------------------------------------------------------
?.type?__arm926_setup, #function
__arm926_setup:
?mov?r0, #0
?mcr?p15, 0, r0, c7, c7??@ invalidate I,D caches on v4
?mcr?p15, 0, r0, c7, c10, 4??@ drain write buffer on v4
#ifdef CONFIG_MMU
?mcr?p15, 0, r0, c8, c7??@ invalidate I,D TLBs on v4
#endif


#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
?mov?r0, #4????@ disable write-back on caches explicitly
?mcr?p15, 7, r0, c15, c0, 0
#endif

?adr?r5, arm926_crval
?ldmia?r5, {r5, r6}
?mrc?p15, 0, r0, c1, c0??@ get control register v4
?bic?r0, r0, r5
?orr?r0, r0, r6
#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
?orr?r0, r0, #0x4000???@ .1.. .... .... ....
#endif
?mov?pc, lr
----------------------------------------------------------------
?好了,終于調(diào)用到start_kernel了,這是任何版本的linux內(nèi)核通用的初始化函數(shù)。


3. Linux系統(tǒng)初始化

?前面已經(jīng)提到,函數(shù)start_kernel是任何版本的linux內(nèi)核通用的初始化函數(shù),也是匯編代碼執(zhí)行結(jié)束后的第一個(gè)c函數(shù),它實(shí)現(xiàn)在

init/main.c中。
?有關(guān)start_kernel的代碼很長(zhǎng),初始化了很多東西,比如調(diào)用了setup_arch()、timer_init()、init_IRQ、console_init()、

pgtable_cache_init()、security_init()、signals_init()和rest_init()等,這里只對(duì)rest_init()做簡(jiǎn)單的分析。
?下面首先列寫一下rest_init()的代碼:
----------------------------------------------------------------
/*
?* We need to finalize in a non-__init function or else race conditions
?* between the root thread and the init thread may cause start_kernel to
?* be reaped by free_initmem before the root thread has proceeded to
?* cpu_idle.
?*
?* gcc-3.4 accidentally inlines this function, so use noinline.
?*/

static noinline void __init_refok rest_init(void)
?__releases(kernel_lock)
{
?int pid;

?kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
?numa_default_policy();
?pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
?kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
?unlock_kernel();

?/*
? * The boot idle thread must execute schedule()
? * at least once to get things moving:
? */
?init_idle_bootup_task(current);
?rcu_scheduler_starting();
?preempt_enable_no_resched();
?schedule();
?preempt_disable();

?/* Call into cpu_idle with preempt disabled */
?cpu_idle();
}
----------------------------------------------------------------
?可以看到,函數(shù)rest_init()首先會(huì)去創(chuàng)建線程kernel_init(注意:這里和網(wǎng)上或者相關(guān)書籍中描述的也不一樣,可能是Linux版本的問題)

,有些文檔中描述這里創(chuàng)建的是Init線程,雖然名字不一致,但是具體的實(shí)現(xiàn)是基本一致的,基本上都是完成根文件系統(tǒng)的掛載、初始化所有Linux的

設(shè)備驅(qū)動(dòng)(就是調(diào)用驅(qū)動(dòng)的初始化函數(shù),類似于CE/Mobile中的Device Manager對(duì)設(shè)備驅(qū)動(dòng)的初始化)以及啟動(dòng)用戶空間Init進(jìn)程。
?由于手中的rest_init進(jìn)程和網(wǎng)上描述的都是不一致的,所以這里也進(jìn)行了簡(jiǎn)要的列舉,代碼如下:
----------------------------------------------------------------
static int __init kernel_init(void * unused)
{
?lock_kernel();
?/*
? * init can run on any cpu.
? */
?set_cpus_allowed_ptr(current, CPU_MASK_ALL_PTR);
?/*
? * Tell the world that we're going to be the grim
? * reaper of innocent orphaned children.
? *
? * We don't want people to have to make incorrect
? * assumptions about where in the task array this
? * can be found.
? */
?init_pid_ns.child_reaper = current;

?cad_pid = task_pid(current);

?smp_prepare_cpus(setup_max_cpus);

?do_pre_smp_initcalls();
?start_boot_trace();

?smp_init();
?sched_init_smp();

?cpuset_init_smp();

?do_basic_setup();

?/*
? * check if there is an early userspace init.? If yes, let it do all
? * the work
? */

?if (!ramdisk_execute_command)
??ramdisk_execute_command = "/init";

?if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
??ramdisk_execute_command = NULL;
??prepare_namespace();
?}

?/*
? * Ok, we have completed the initial bootup, and
? * we're essentially up and running. Get rid of the
? * initmem segments and start the user-mode stuff..
? */

?init_post();
?return 0;
}

static noinline int init_post(void)
{
?/* need to finish all async __init code before freeing the memory */
?async_synchronize_full();
?free_initmem();
?unlock_kernel();
?mark_rodata_ro();
?system_state = SYSTEM_RUNNING;
?numa_default_policy();

?if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
??printk(KERN_WARNING "Warning: unable to open an initial console./n");

?(void) sys_dup(0);
?(void) sys_dup(0);

?current->signal->flags |= SIGNAL_UNKILLABLE;

?if (ramdisk_execute_command) {
??run_init_process(ramdisk_execute_command);
??printk(KERN_WARNING "Failed to execute %s/n",
????ramdisk_execute_command);
?}

?/*
? * We try each of these until one succeeds.
? *
? * The Bourne shell can be used instead of init if we are
? * trying to recover a really broken machine.
? */
?if (execute_command) {
??run_init_process(execute_command);
??printk(KERN_WARNING "Failed to execute %s.? Attempting "
?????"defaults.../n", execute_command);
?}
?run_init_process("/sbin/init");
?run_init_process("/etc/init");
?run_init_process("/bin/init");
?run_init_process("/bin/sh");

?panic("No init found.? Try passing init= option to kernel.");
}
----------------------------------------------------------------
?可以看到,和網(wǎng)絡(luò)上相關(guān)的描述不一樣的是,這里首先會(huì)去初始化設(shè)備驅(qū)動(dòng),而不是像網(wǎng)上或者數(shù)據(jù)上所描述的一樣,首先去加載跟文件系

統(tǒng),難道不存在初始化的時(shí)候需要訪問文件的驅(qū)動(dòng)了?或者以前的做法純屬一種安全的考慮?
?這些問題就留到以后對(duì)Linux&Android有深入地了解之后再去考慮吧!
?好了,搞定!!!

總結(jié)

以上是生活随笔為你收集整理的Linux-Android启动之Init进程前传的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 成人片在线看 | 亚洲色图激情小说 | 99热免费在线 | 国产猛男猛女超爽免费视频 | 伊人一级片 | 欧美性受xxxx黑人xyx | 黑人巨大精品一区二区在线 | 日韩黄色免费网站 | 手机av在线网 | 91麻豆精品国产91久久久久久久久 | 在线手机av| 黄色在线观看网址 | 日韩电影网站 | 毛片视频网站在线观看 | 欧美激情在线狂野欧美精品 | 日韩欧美在线免费观看 | v片在线看| 一级黄色录像免费观看 | 亚洲欧美日韩综合一区二区 | 午夜精品免费 | 国产欧美精品国产国产专区 | 老牛嫩草二区三区观影体验 | 激情的网站 | 黄色高清免费 | 91视频插插插 | 国产三级在线播放 | 欧美性做爰毛片 | 少妇高潮毛片 | 啪啪在线视频 | 日本理论中文字幕 | 亚洲欧美精品午睡沙发 | 97caop| 欧美激情欧美激情在线五月 | 久久av一区二区三区 | 国产成人无码av | 精品xxxx | 欧美日韩综合在线观看 | 少妇厨房愉情理伦bd在线观看 | 亚洲视频欧洲视频 | 免费看片成人 | 淫辱的世界(调教sm)by | 99久久精品国产一区二区成人 | 精品国产黄色片 | 日日夜夜精品免费 | xxx性日本 | 亚洲黄v | 久久精品国产亚洲av麻豆 | 婷婷五月综合激情 | 成人国产精品免费观看 | 亚洲丝袜在线观看 | 六月婷婷综合网 | 中国少妇av| 亚洲精品男人的天堂 | 国产伦精品一区二区三区视频痴汉 | 国产精品av久久久久久无 | 国产一区视频在线播放 | 男女爽爽视频 | 成人在线视频在线观看 | 国产麻豆久久 | 97se亚洲国产综合在线 | 欧美成人dvd在线视频 | 日本欧美一本 | 天天天色 | 日本一区视频在线播放 | 手机在线观看av | 国产精品久久久久影院老司 | 亚洲天堂免费观看 | 啪啪日韩 | 美女啪啪一区二区 | 羞羞草影院 | 国产精品电影一区二区三区 | 3d动漫精品啪啪一区二区竹菊 | 国产精品视频在线播放 | 麻豆tv在线观看 | 亚洲成人一级片 | 91在线在线 | 欧美精品四区 | 中国性老太hd大全69 | 办公室摸腿吻胸激情视频 | 秋霞av鲁丝片一区二区 | 亚洲国产中文字幕在线观看 | 日韩人妻精品中文字幕 | 亚洲黄色一区二区 | 精品成人av一区二区在线播放 | 91porn在线 | 成人免费观看视频大全 | 亚洲aaaa级特黄毛片 | 99综合久久| 久久中文字幕在线观看 | 超碰2021| 天天干天天操天天插 | 中文字幕自拍偷拍 | 久久人人爽人人 | 亚洲一级Av无码毛片久久精品 | 国产一区二区三区四区五区 | 娇喘顶撞深初h1v1 | 欧美色图一区二区三区 | 日韩一二三区在线观看 | 黄色网页在线免费观看 |