
Android&&Linux Kernel进阶系列
文章平均质量分 74
Android&&Linux Kernel进阶系列
Android系统攻城狮
《Android系统多媒体进阶实战》一书作者
展开
-
Android内核之物理地址映射到kernel虚拟地址:kmap用法实例(七十七)
本篇目的:Android内核之物理地址映射到kernel虚拟地址:kmap用法实例kmap()函数在Linux内核中的作用是将物理地址映射到内核虚拟地址空间中的一个区域。在Linux内核中,由于内存管理的复杂性,需要经常访问物理地址,但同时又需要在内核虚拟地址空间中进行操作。kmap()函数允许内核通过临时映射的方式在内核虚拟地址空间中访问物理页面,以便执行各种操作,比如数据复制、处理等。原创 2024-05-18 02:30:00 · 1094 阅读 · 0 评论 -
Android内核之安全复制字符串: strscpy用法实例(七十六)
Linux内核中的strscpy函数是一个用于在内存受限的环境中复制的函数,它将源字符串安全地复制到目标缓冲区,即使在源字符串长度未知或可能很长的情况下也不会导致缓冲区溢出。这是通过确保源字符串不会超过目标缓冲区的大小来实现的。函数原型通常定义为:dest: 目标字符串缓冲区的地址。src: 源字符串的地址。size: 目标缓冲区的大小。strscpy函数会检查目标缓冲区的大小,并只复制最多size-1个字符,留下最后一个位置用于添加null字符('\0'),以确保字符串以正确的格式结束。原创 2024-05-17 05:30:00 · 1496 阅读 · 0 评论 -
Android内核之Binder对象引用获取管理:binder_get_ref_olocked用法实例(七十五)
本篇目的:Android内核之Binder对象引用获取管理:binder_get_ref_olocked用法实例在 Android 系统中,Binder 是一种关键的进程间通信(IPC)机制,它被广泛应用于不同应用组件之间以及应用与系统服务之间的通信。Binder 机制的核心是 Binder 驱动,它位于 Android 内核中,负责管理和调度进程间的通信请求。在 Binder 驱动的实现中,函数扮演着至关重要的角色。首先,让我们了解一下 Binder 通信的基本原理。原创 2024-05-11 17:22:28 · 1160 阅读 · 0 评论 -
Android内核之解决报错:error: ISO C90 forbids mixing declarations and code(七十四)
本篇目的:Android内核之解决报错:error: ISO C90 forbids mixing declarations and code在编程中,特别是在使用C或C++语言时,我们经常会遇到编译器错误。其中一个常见的错误是 “error: ISO C90 forbids mixing declarations and code”。这个错误是由于在C90标准中,声明和代码混合使用是不被允许的。C90标准是C语言的第一个国际标准,于1990年发布。在这个标准中,规定了声明和代码必须分开编写。原创 2024-05-11 15:53:59 · 1163 阅读 · 0 评论 -
Android内核之Binder消息处理:binder_transaction用法实例(七十三)
本篇目的:Android内核之Binder消息处理:binder_transaction用法实例binder_transaction 函数是 Android Binder 驱动中的一个核心函数,它用于在 Binder 机制中实现客户端向服务端发送请求并接收响应的过程。以下是对 binder_transaction 函数作用的详细介绍:消息传递: 在 Android 中,Binder 机制允许不同的应用程序或系统组件之间进行进程间通信(IPC)。原创 2024-05-09 09:17:56 · 1454 阅读 · 0 评论 -
Android内核之Binder通信读操作:binder_thread_read用法实例(七十二)
本篇目的:Android内核之Binder通信读操作:binder_thread_read用法实例在 Android 操作系统中,Binder 驱动是用于进程间通信(IPC)的核心组件,负责在不同的应用程序之间传递消息和数据。在这个驱动中,函数起着至关重要的作用,它是负责从 Binder 队列中读取消息的关键部分。首先,理解 Binder 的基本工作原理是很重要的。当一个应用程序(或者 Android 系统的其他组件)想要向另一个应用程序发送消息时,它会将消息发送到 Binder 驱动中的队列中。而。原创 2024-05-09 09:09:41 · 1028 阅读 · 0 评论 -
Android内核之Binder通信写操作:binder_thread_write用法实例(七十一)
本篇目的:Android内核之Binder通信写操作:binder_thread_write用法实例函数是Android内核中用于Binder线程通信的关键函数之一。Binder是Android系统中用于进程间通信(IPC)的机制,它通过驱动程序实现。在Binder机制中,每个进程都有一个专门的Binder线程,用于处理与其他进程的通信请求。函数主要负责向目标Binder线程发送消息。原创 2024-05-08 10:48:10 · 1114 阅读 · 0 评论 -
Android内核之Binder读写通信:binder_ioctl_write_read用法实例(七十)
本篇目的:Android内核之IPC通信:binder_ioctl_write_read用法实例是Android系统中Binder驱动的关键函数之一,用于在用户空间和内核空间之间进行进程间通信(IPC)。Android的Binder机制是一种高效的IPC机制,用于在Android系统中进行进程间通信,特别是在应用程序和系统服务之间。该函数的主要作用是通过ioctl系统调用在用户空间和内核空间之间传递数据。原创 2024-05-08 10:42:52 · 1180 阅读 · 0 评论 -
Linux内核之注册平台总线:platform_driver_register用法实例(六十九)
本篇目的:Linux内核之注册平台总线:platform_driver_register用法实例platform_driver_register() 函数是 Linux 内核中用于注册平台驱动程序的函数。平台驱动程序通常用于与硬件平台相关的设备驱动,如嵌入式系统中的设备,这些设备不使用标准的总线(如 PCI、USB 等),而是通过特定的平台总线连接到系统。该函数的作用是将一个已经填充好的 platform_driver 结构体注册到内核中。注册后,内核将会为该驱动程序提供对应的设备匹配和探测功能。原创 2024-05-07 21:04:43 · 1407 阅读 · 0 评论 -
Linux内核之获取文件系统超级块:sget用法实例(六十八)
本篇目的:Linux内核之获取文件系统超级块:sget用法实例sget 函数是 Linux 内核中的一个重要函数,用于获取文件系统的超级块结构。超级块是文件系统的关键数据结构,包含有关文件系统的重要信息,如块大小、inode 结构、挂载点等。该函数的作用是根据指定的文件系统类型、测试函数和设置函数,以及其他参数,尝试获取文件系统的超级块。具体来说,它的作用包括:文件系统超级块的获取:通过指定的文件系统类型,函数尝试获取与之对应的超级块。这使得在进行文件系统相关操作之前能够获取到必要的文件系统信息。原创 2024-05-07 20:45:29 · 903 阅读 · 0 评论 -
Linux内核之原子操作:atomic_long_dec用法实例(六十七)
本篇目的:Linux内核之原子操作:atomic_long_dec用法实例atomic_long_dec() 函数是 Linux 内核中用于对长整型(long)原子操作的函数之一。它的作用是以原子方式减少一个长整型变量的值,并且保证这个操作是不可中断的,即在多线程环境下也能保证数据的一致性和正确性。在 Linux 内核中,原子操作是一种特殊的操作,能够保证在多处理器或者多核系统上的并发执行过程中,对共享数据的访问是安全的,不会发生竞态条件(Race Condition)或者数据不一致的情况。原创 2024-05-02 17:02:43 · 813 阅读 · 0 评论 -
Linux内核之原子操作:atomic_long_inc用法实例(六十六)
本篇目的:Linux内核之原子操作:atomic_long_inc用法实例atomic_long_inc() 函数是 Linux 内核中用于对长整型(long)原子操作的函数之一。它的主要作用是以原子方式增加一个长整型变量的值,并且保证这个操作是不可中断的,即在多线程环境下也能保证数据的一致性和正确性。在 Linux 内核中,原子操作是一种特殊的操作,能够保证在多处理器或者多核系统上的并发执行过程中,对共享数据的访问是安- 全的,不会发生竞态条件(Race Condition)或者数据不一致的情况。原创 2024-05-02 16:55:24 · 1118 阅读 · 2 评论 -
Linux内核之页面映射到虚拟地址:insert_page用法实例(六十五)
本篇目的:Linux内核之页面映射到虚拟地址:insert_page用法实例insert_page() 函数是 Linux 内核中用于将页面映射到虚拟地址空间的关键函数之一。其作用是将给定的页面映射到指定的虚拟地址空间中的指定地址,并设置页面的保护标志。这个函数通常用于虚拟内存管理中,用于建立物理页面和虚拟地址之间的映射关系。在 Linux 内核中,虚拟内存管理是一项重要的任务,负责管理物理内存和虚拟地址空间之间的映射关系。这种映射关系允许进程使用虚拟地址来访问物理内存,而不需要关心物理内存的实际位置。原创 2024-05-01 18:05:05 · 825 阅读 · 0 评论 -
Linux内核之虚拟内存区域页分配:alloc_pages_vma用法实例(六十四)
本篇目的:Linux内核之虚拟内存区域页分配:alloc_pages_vma用法实例alloc_pages_vma() 是Linux内核中用于在给定虚拟内存区域(VMA)中分配内存页面的函数。在操作系统中,内存管理是一个关键的任务,而分配内存页是其中的一项基本操作。该函数的作用是为进程或内核的特定需求在虚拟地址空间中动态分配连续的物理内存页,并返回一个指向分配内存页描述符的指针。在Linux内核中,虚拟内存区域(VMA)是一种用来管理进程虚拟地址空间的数据结构。原创 2024-05-01 17:45:45 · 1509 阅读 · 2 评论 -
Linux内核之设定inode链接计数:set_nlink用法实例(六十三)
本篇目的:Linux内核之设定inode链接计数:set_nlink用法实例在Linux内核中,set_nlink函数用于设置一个inode的链接数(link count)。每个inode都有一个链接数,它表示有多少个文件名指向这个inode。链接数是文件系统中的一个重要概念,它影响着文件的删除和磁盘空间的回收。原创 2024-04-30 11:50:29 · 1221 阅读 · 2 评论 -
Linux内核之临时映射内核内存:kmap_atomic用法实例(六十二)
本篇目的:Linux内核之临时映射内核内存:kmap_atomic用法实例kmap_atomic 和 kunmap_atomic 是 Linux 内核中用于在驱动程序中临时映射内核内存的函数。它们通常用于驱动程序中需要在中断上下文中访问内核内存时。原创 2024-04-30 11:30:46 · 1127 阅读 · 0 评论 -
Linux内核之hook机制:call_void_hook用法实例(六十一)
本篇目的:Linux内核之hook机制:call_void_hook用法实例char * lsm;\ ____ptr?\ pos;char * lsm;\ ____ptr?\ pos;char * lsm;\ ____ptr?\ pos;char * lsm;\ ____ptr?\ pos;原创 2024-04-24 06:15:00 · 1141 阅读 · 0 评论 -
Linux内核之宏_IOWR:如何生成ioctl控制命令(六十)
本篇目的:Linux内核之宏_IOWR:如何生成ioctl控制命令在Linux内核中,_IOWR是一个宏,用于生成系统调用中ioctl命令代码的一部分。ioctl(“input/output control”)系统调用是Linux中用于与设备文件交互的接口,它允许用户空间程序向设备驱动发送控制命令,并可能传递或接收数据。_IOWR宏用于构造一个ioctl命令,该命令支持双向数据传输,即可以同时从用户空间读取数据和向用户空间写入数据。原创 2024-04-24 05:00:00 · 1732 阅读 · 0 评论 -
Linux内核之内存回收器:shrinker用法实例(五十九)
本篇目的:Linux内核之内存回收器:shrinker用法实例struct shrinker 是 Linux 内核中用于管理内存回收器的结构体。它允许内核在系统内存紧张时释放不再需要的内存对象,以确保系统的稳定性和性能。原创 2024-04-23 06:00:00 · 1221 阅读 · 0 评论 -
Linux内核之slab、slub内存分配器实例用法区别(五十八)
本篇目的:Linux内核之slab、slub内存分配器用法实例区别在Linux内核中,slab和slub都是内存分配器,用于管理内核空间的内存分配和释放。它们的作用是优化内存分配和释放的性能,减少内存碎片化,并提高系统的性能和稳定性。原创 2024-04-22 05:15:00 · 1277 阅读 · 2 评论 -
Linux内核之注册字符设备:alloc_chrdev_region静态注册、register_chrdev动态注册(五十七)
简介: 优快云博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.原创 2024-04-22 04:00:00 · 1737 阅读 · 0 评论 -
Linux内核之内核通知文件系统创建的路径:fsnotify_create用法实例(五十六)
本篇目的:Linux内核之内核通知文件系统创建的路径:fsnotify_create用法实例fsnotify_create 函数是 Linux 内核中的一个函数,用于通知文件系统中的文件或目录创建事件。当新的文件或目录被创建时,内核会调用 fsnotify_create 函数来向文件系统通知机制注册相应的创建事件监听器。// 审计文件系统事件:通知有新的子节点被创建// 发送文件系统通知事件:文件被创建参数说明:inode:新创建的文件或目录所属的父目录的索引节点。原创 2024-04-21 06:15:00 · 898 阅读 · 0 评论 -
Linux内核之文件系统访问:目录项、inode、物理磁盘访问关系(五十五)
本篇目的:Linux内核之目录项/inode/物理磁盘访问关系在Linux文件系统中,目录项(dentry)、inode和物理磁盘之间的关系是理解和文件访问流程的关键。原创 2024-04-21 04:15:00 · 1051 阅读 · 0 评论 -
Linux内核之目录项关联inode索引节点:d_instantiate用法实例(五十四)
本篇目的:Linux内核之目录项关联inode索引节点:d_instantiate用法实例在Linux内核中,函数是一个关键的文件系统接口,它用于将目录项(dentry)与inode关联起来。这个函数在文件系统的路径查找过程中被调用,对于文件系统的性能和稳定性有着重要影响。原创 2024-04-20 06:15:00 · 1053 阅读 · 0 评论 -
Linux内核之读、写信号量:up_read、up_write用法实例(五十三)
本篇目的:Linux内核之读写信号量:up_read/up_write用法实例在 Linux 内核中,up_read 和 up_write 是用于管理读写信号量的函数,通常与 down_read 和 down_write 函数一起使用,用于实现读写锁。up_read函数:作用:释放读取锁定信号量。用法: up_read(& sem);说明:up_read 函数用于释放先前通过 down_read 函数获取的读取锁。它使得其他进程或线程能够获取读取锁,允许多个并发读取操作。原创 2024-04-20 05:45:00 · 1484 阅读 · 0 评论 -
Linux内核之查找文件系统中文件或目录:lookup_one_len用法实例(五十二)
本篇目的:Linux内核之查找文件系统中路径:lookup_one_len用法实例Linux内核中的函数是文件系统路径查找中的一个关键函数,它用于在VFS(Virtual File System)层中根据给定的路径名查找目录项(dentry)。这个函数的主要作用是在文件系统中寻找与路径名匹配的目录项,它是文件系统交互的基础之一,对于文件系统的性能和稳定性有着重要影响。在Linux系统中,每个文件或目录都有一个与之对应的目录项对象,即dentry。原创 2024-04-19 09:09:27 · 1109 阅读 · 0 评论 -
Linux内核之引用计数器:refcount_set代码实例(五十一)
本篇目的:Linux内核之引用计数器:refcount_set代码实例是 Linux 内核中用于设置引用计数值的函数之一。引用计数是一种常见的内核机制,用于跟踪内核对象的引用次数,以确保在没有任何引用时可以安全地释放对象。其中,r是一个refcount_t类型的指针,表示要设置的引用计数器,而n是要设置的值。通常,函数在初始化内核对象的引用计数时使用,或者在需要重置引用计数器值时使用。在初始化时,它可以将引用计数设置为初始值,通常为 1,表示对象的第一个引用。原创 2024-04-19 07:42:28 · 1048 阅读 · 0 评论 -
Linux内核之虚拟地址转物理页:virt_to_page实现代码实例(五十)
本篇目的:Linux内核之virt_to_page实现与用法实例是Linux内核中用于将虚拟地址转换为对应的页描述符(page descriptor)的函数。在Linux内核中,每个物理内存页都有一个对应的结构,该结构包含了页的详细信息,如页的状态、引用计数、映射信息等。当内核需要操作一个特定的虚拟地址时,它通常会使用来获取该虚拟地址对应的page结构。在Linux内核中,虚拟地址空间被划分为多个区域,如内核空间、用户空间等。每个区域内部又被划分为多个页,每页大小通常为4KB。原创 2024-04-18 10:03:20 · 1565 阅读 · 0 评论 -
Linux内核之kfree如何释放内存(四十九)
本篇目的:Linux内核之kfree实现及用法实例在Linux内核中,kfree是一个用于释放内存的函数,它用于释放通过kmallockzallocvmalloc等函数分配的内存。这些分配函数在内核空间中动态地分配内存,而kfree则用于在不再需要这些内存时将其释放回系统。当一个内核函数需要一些临时内存来存储数据时,它会调用kmalloc或kzallockzalloc是kmalloc的一个变体,它会在分配内存后将其清零)。这些函数返回一个指向分配的内存的指针。原创 2024-04-18 07:43:54 · 1676 阅读 · 0 评论 -
Linux内核之WRITE_ONCE用法实例(四十八)
本篇目的:Linux内核之WRITE_ONCE用法实例WRITE_ONCE是一个宏,它在Linux内核中用于确保对变量的写操作是原子性的,并且不会被编译器的优化重排。这个宏的主要目的是在多线程环境中提供一种安全的方式来写入共享变量,确保其他线程能够看到正确的值。WRITE_ONCE宏的实现利用了C语言的结构体和联合体的特性。首先,它定义了一个匿名联合体,其中包含一个与目标变量x类型相同的成员__val,以及一个字符数组__c。这个字符数组的大小设置为1,是为了确保联合体的大小与x的大小相同。原创 2024-04-17 06:00:00 · 969 阅读 · 0 评论 -
Linux内核之互斥锁mutex_init和自旋锁spin_lock区别及用法实例(四十六)
本篇目的:Linux内核之互斥锁mutex_init和自旋锁spin_lock区别及用法实例在Linux内核中,mutex_init和spin_lock是两种常用的同步机制,用于在多线程或多处理器环境中保护共享资源,防止并发访问造成的数据不一致问题。mutex_init用于初始化一个互斥锁(mutex),它是一种睡眠锁。当一个线程尝试获取一个已经被其他线程持有的互斥锁时,该线程会被阻塞,进入睡眠状态,直到互斥锁被释放。互斥锁适用于那些可能造成较长时间阻塞的场景,因为线程睡眠状态不会消耗CPU资源。原创 2024-04-13 06:45:00 · 2309 阅读 · 0 评论 -
Linux内核之自旋锁:自旋锁初始化之spin_lock_init用法实例(四十五)
本篇目的:Linux内核之自旋锁:spin_lock_init用法实例Linux内核是一个开源的类UNIX操作系统内核,被广泛用于各种计算机系统。在Linux内核中,同步机制是确保多线程程序正确性的关键部分。是Linux内核中用于初始化自旋锁的一个函数,它用于保护内核中的临界区,防止多个线程同时访问共享资源。自旋锁(spinlock)是一种锁,当一个线程尝试获取一个已被其他线程获取的锁时,该线程将在一个循环中不断地检查锁是否已经可用。这个过程被称为“自旋”。原创 2024-04-13 05:15:00 · 2083 阅读 · 0 评论 -
Linux内核之Binder驱动红黑树:rb_root用法实例(四十四)
本篇目的:Linux内核之Binder驱动关键结构体rb_root用法实例Binder是Android系统中实现跨进程通信(IPC)的机制,它由内核空间的Binder驱动和用户空间的Binder库组成。Binder驱动中的关键数据结构之一是rb_root,它用于管理Binder实体的高速缓存。在Binder驱动中,每个进程都有一个binder_proc结构体,用于管理该进程中的Binder实体和引用。原创 2024-04-12 06:30:00 · 1054 阅读 · 0 评论 -
Linux内核之Binder驱动关键结构体binder_ref用法实例(四十三)
本篇目的:Linux内核之Binder驱动关键结构体binder_ref用法实例Binder是Android系统中一个非常重要的组件,它负责在进程间进行通信(IPC)。Binder驱动是Binder机制的核心部分,它工作在内核空间,负责处理跨进程的通信细节。Binder驱动通过一个名为binder_ref的数据结构来管理进程间的引用关系。在Binder驱动中,每个进程都有一个对应的binder_proc结构体,该结构体包含了进程的所有Binder相关的信息。原创 2024-04-12 05:45:00 · 1889 阅读 · 0 评论 -
Linux内核之Binder驱动关键结构体binder_node用法实例(四十二)
本篇目的:Linux内核之Binder驱动关键结构体binder_node用法实例是 Android Binder 驱动中用于表示 Binder 实体的核心数据结构。Binder 实体是 Binder 通信机制中的基本单元,它可以是一个服务,也可以是一个客户端句柄。每个 Binder 实体都对应一个结构,该结构包含了实体的各种信息,如引用计数、节点 ID、用户数据等。Binder 实体在 Binder 驱动中通过来管理,它是实现进程间通信(IPC)和服务管理的基础。原创 2024-04-11 07:45:00 · 1061 阅读 · 0 评论 -
Linux内核之Binder驱动关键结构体binder_proc用法实例(四十一)
在 Android 系统中,Binder 是一个提供进程间通信(IPC)的驱动程序。它允许一个进程(称为服务器)提供服务给其他进程(称为客户端)。struct binder_proc 是 Binder 驱动中的一个关键结构体,它代表了一个使用 Binder 机制的进程。这个结构体包含了进程的 Binder 相关的所有信息,如线程池、内存分配情况、已打开的 Binder 实体等。原创 2024-04-11 05:45:00 · 1573 阅读 · 0 评论 -
Linux内核之等待队列wait_queue_head_t数据结构用法实例(四十)
本篇目的:Linux内核之等待队列wait_queue_head_t用法实例是 Linux 内核中用于实现等待队列的基本数据结构。在 Linux 内核中,等待队列是一种常见的机制,用于让进程在某个条件不满足时进入睡眠状态,当条件满足时被唤醒继续执行。这种机制在很多内核子系统中都有应用,如进程调度、设备驱动、同步等。结构体定义了一个等待队列的头部,它包含了等待队列的基本信息和一个用于同步的锁。等待队列实际上是一个进程列表,这些进程都在等待某个条件变为真。每个等待队列都有一个对应的结构体,用于管理这个队列。原创 2024-04-10 07:15:00 · 1902 阅读 · 0 评论 -
Linux内核之原子操作atomic_t用法实例(三十九)
本篇目的:Linux内核之atomic_t用法实例Linux内核中的atomic_t是一个原子操作的计数器类型,它被广泛用于多线程环境中,确保对计数器的操作是线程安全的。在Linux内核中,许多场合需要对某些值进行原子操作,例如,进程计数、互斥锁的计数器等。atomic_t提供了对这些值进行增加、减少和获取当前值的原子操作,避免了在多线程环境中由于竞态条件引起的并发问题。atomic_t的定义在头文件中,它是一个简单的整数类型(通常是32位),并提供了以下几个主要的操作函数::初始化一个。原创 2024-04-10 05:45:00 · 1848 阅读 · 0 评论 -
Linux内核之Binder驱动内存映射实现:binder_update_page_range实例用法(三十八)
本篇目的:Linux内核之binder_update_page_range实例用法Android Binder是Android系统中用于进程间通信(IPC)的一种机制。Binder驱动程序负责实现Binder机制的核心功能,包括数据的传递、线程的管理等。在Binder驱动程序中,函数是一个重要的函数,用于处理内存映射的相关操作。函数主要处理Binder内存映射的更新。在Binder通信中,客户端与服务端通过Binder机制进行数据交换,这些数据通常存储在内核空间的内存中。原创 2024-04-09 10:27:29 · 1474 阅读 · 0 评论 -
Linux内核之get_vm_area分配虚拟内存地址,并映射到物理内存(三十七)
本篇目的:Linux内核之get_vm_area用法实例函数是 Linux 内核中用于申请内存区域的一个核心函数,它在内核内存管理子系统中发挥着重要作用。这个函数的主要职责是在内核地址空间中寻找一块足够大的连续虚拟内存区域,以满足内核或内核模块动态申请内存的需要。在详细介绍函数之前,有必要了解一些基本概念。在 Linux 操作系统中,每个进程都有其独立的虚拟地址空间,这个地址空间被分为用户空间和内核空间。原创 2024-04-09 10:09:40 · 1175 阅读 · 0 评论