自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(21)
  • 收藏
  • 关注

原创 通透!LINUX内核源码完全剖析-UDP套接字发送数据从系统调用到驱动(基于linux6.14-rc2)

这里是做数据转换的发送 socket 数据之前会做安全校验,通过了才会去发送,来看看这个校验函数可以看到这是一个 hook 调用,会有一个安全校验的调用链安全校验完了之后就会调用sock_sendmsg_nosec 去发送数据了,这里如果是用的 ipv4 地址的话就会调用inet_sendmsg如果前面有挂起的数据包没有处理就跳转到挂起数据包的处理逻辑做一下数据校验将控制信息保存在 ipc 结构体中如果没有配置 ip 选项的话就会去 inet 中获取。

2025-02-13 22:32:37 889

原创 wpa_supplicant二层包收发

这里面就是初始化一个 PF_PACKET socket 文件描述符,然后向 eloop 注册读事件,在 bind 时绑定了 wlan 接口地址,因此可以使用这个 socket 文件描述符对指定 wlan 接口收发二层数据包。添加 wlan 接口时会调用wpa_supplicant_init_iface。

2025-03-20 21:12:37 341

原创 wpa_supplicant驱动初始化源码分析

初始化 bss,这里主要是创建 bss 相关的与内核通信的文件描述符,在发起关联请求的时候就会用到这该文件描述符,并且会使用 precess_bss_event 这个回调来处理内核发来的 bss 相关事件。在 wpa_supplicant 加载时会调用 select_driver 函数,这里会调用驱动的global_init,对应上面驱动 ops 结构体的 nl80211_global_init 函数。来看看wpa_driver_nl80211_init_nl_global 中注册的接收事件的回调。

2025-03-20 21:00:04 367

原创 WIFI p2p连接总结

listen state:p2p device 将随机选择在 1/6/11 频段中的一个频段来监听 probe request 帧,选定的信道成为 listen channel,整个 discovery 阶段都不会更改,listen 状态的持续时间 是 100TU 的随机整数倍(默认在 1 到 3 之间,厂商可以修改),随机是为了避免两个设备同时进入 listen 和 search 导致始终无法发现对方。设备发现后就可以进行 组协商了,主要作用是决定哪个设备当 GO,整个协商过程包括三次握手。

2025-03-20 20:21:31 738

原创 wpa_supplicant源码剖析-main.c解析

通知 wpa_supplicant 初始化了,这里主要是对 binder 进行初始化,以便于后续进行 rpc,通常手机厂商会在这里将 binder 去掉,加入 hidl 和 aidl 的初始化,一般通过 hidl 接口去调用 wpa_supplicant 的功能。这里面主要是进行驱动初始化及 wpa_supplicant 上下文初始化,后续作者会更新驱动初始化的内容。将输入的参数处理完之后,使用参数对 wpa_supplicant 进行初始化。回到wpa_supplicant_add_iface。

2025-02-28 21:03:33 721

原创 Linux系统编程

注意,c语言没有函数重载,这里是通过可变参数实现的,mode不指定的话会用umask去默认创建,这里creat功能可以直接在open中。针对文件描述符执行操作,主要是操作文件描述符的flag,如O_APPEND,NONBLOK等。注意,非阻塞io在数据没准备好时会返回EAGAIN,所以这时候不能认为这是个错误。修改文件权限,两个函数不同是一个根据文件路径,一个根据传入文件描述符去修改。判断某个文件是否有某个权限,或者判断文件是否存在。用来操作文件描述符对应的偏移量,也就是去。实现,不必使用creat。

2025-02-24 22:56:46 639

原创 Linux设备驱动开发-中断

设备树匹配后,在 probe 函数中使用platform_get_resource 可以获得中断资源,i2c 和 spi 驱动也是在 probe 函数中取出中断信息,调用的函数稍有不同,中断信息会保存在 i2c_client 和 spi_device 结构体中。触发类型:1 表示上升沿触发 ,2 表示下降沿触发,3 表示高电平触发,4 表示低电平触发,多种触发按位或即可。3.网卡这样耗时的中断可以分成上半部和下半部(使用内核线程处理,下半部可以被其他中断打断)在设备树声明中断,中断会发到父亲中断控制器。

2025-02-24 22:53:33 676

原创 Linux设备驱动开发-I2C子系统

来看看数据传输,这里 调用i2c_transfer 传输所有的 msg,对于读取数据的传输,在传输完后还需要把得到的数据拷贝回用户空间,这里i2c_transfer 就是和 adapter 打交道了。地址是通过unlocked_ioctl 来进行也就是i2cdev_ioctl,I2C_SLAVE/I2C_SLAVE_FORCE 设置 client 的地址。在 open 设备节点的时候调用i2cdev_open,这里会通过次设备号获取到 adapter(i2c 控制器)来看看内核中的 i2c 控制器驱动。

2025-02-23 22:46:34 252

原创 Linux设备驱动开发-UART驱动

UART 有三条线,分别是 Rx,Tx 和 GND数据发送接收步骤:1.双方约定波特率2.拉低(从高电平) Tx 引脚维持 1bit 时间3.接收端在低电平开始处计时4.发送端根据数据驱动 Tx 引脚电平5.接收端 1.5bit 时间后读取引脚状态(前面有一个开始位)6.bit8 是可选的校验位(可分为奇校验和偶校验)7.发送停止位(可以约定停止位占据多少时间)

2025-02-23 14:24:49 943

原创 Linux设备驱动开发-GPIO子系统使用详解

可以通过gpiod_direction_output 设置引脚方向,这里设置的是逻辑值,如果引脚被设置为GPIO_ACTIVE_HIGH 那么 1 就是设置高电平,如果是GPIO_ACTIVE_LOW 的话 1 就是低电平。这里使用前缀获取,0 表示是第 0 个引脚也就是gpio3 RK_PC5 这个引脚,这里在设备树中用逗号隔开写多个引脚。在使用 GPIO 子系统之前可以通过 Pinctrl 子系统将引脚配置为 GPIO 模式。可以使用 gpiod_get_index 获取引脚。以下面设备树代码为例。

2025-02-23 12:31:17 358

原创 Linux设备驱动开发-Pinctrl子系统使用详解

以这个段设备树代码为例,这里有normal 和idle 两种模式,normal 对应pinctrl-0,idle 对应pinctrl-1。一般引脚前面会有 IOMUX 连接各种功能,通过IOMUX 来指定引脚具体连接什么功能。来看一个引脚控制,可以看到这里配置了引脚功能为 gpio,并且进行了下拉。当设备切换状态时系统就会根据设备树去切换引脚状态。这段设备树片段称为 controller。Pinctrl 就是用来控制引脚的。写代码时可以通过这些函数来控制状态。pinctl 通过状态来控制引脚。

2025-02-23 11:33:49 490

原创 Linux多进程编程

信号是 Linux 进程间通信的最古老的方式之一,是事件发生时对进程的通知机制,有时也称之为软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。信号可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件。发往进程的诸多信号,通常都是源于内核。引发内核为进程产生信号的各类事件如下:1.对于前台进程,用户可以通过输入特殊的终端字符来给它发送信号。比如输入Ctrl+C 通常会给进程发送一个中断信号。

2025-02-23 10:34:27 633

原创 Linux设备驱动开发-PCI/PCIE

PCI 地址线和数据线是复用的,通过 frame 引脚电平区分,frame 信号为低的话第一个时钟传输地址,后续传输数据,一开始的时候通过 IDSEL(与 AD 引脚连接) 引脚区分设备,选中设备的IDSEL 就可以配置设备了,设备的访问是通过桥来实现的。首先需要 HOST 驱动(识别 pci_dev,pci_dev 可能是桥,桥下面也会有pci_dev),针对 EP 也就是pci_dev 我们需要提供驱动程序并向内核注册,注册之后会在 pci 总线上匹配,报文的配置是通过寄存器来进行的。

2025-02-23 10:17:42 1122 1

原创 Linux设备驱动开发-SPI驱动开发详解(包含设备树处理详细过程)

引脚:MISO(master 输入,slave 输出),MOSI(master 输出,slave 输入),片选引脚,SCK(时钟)控制寄存器:可以设置这CPOL 和 CPHA两个参数,CPOL 代表 SCK 初始电平,CPHA 代表相位(第一/第二个时钟沿采集数据),SPI 状态寄存器:分辨数据是否发送完了,使能中断波特率寄存器:设置 SCK 频率数据寄存器:连接移位器收发数据。

2025-02-22 20:50:08 1418

原创 蓝牙协议-HCI协议详解

在 host 层和 controller 层都有 hci 协议,蓝牙芯片中也有HCI协议代码,烧到Bluetooth chip中,所以我们发送的data可以被正确的parse,执行相应的动作后再准确的回送给我们response可以看到 hci 支持单模和双模hci 的架构。

2025-02-13 22:48:13 1241

原创 全网唯一!打开蓝牙-从蓝牙协议栈HCI层到蓝牙驱动源码剖析(Broadcom驱动)

hci_uart 结构体是在drivers\bluetooth\hci_ldisc.c 中的hci_uart_tty_open 构建的,写任务函数也是在这里绑定的。来到\net\bluetooth\hci_core.c 中的hci_recv_frame,可以看到其插入消息到读链表,然后调度读任务。在hci_ldisc.c 中的hci_uart_register_dev给hdev 分配内存时会调用hci_alloc_dev。其后面调用hci_uart_tx_wakeup,可以看到其调度写任务。

2025-02-12 20:27:13 1071

原创 通透!Transport-H4协议及安卓蓝牙协议栈代码详解

这时候只读一个字节,更新包的 type,另外的 hci raw data 还没读,所以等会还会继续触发这个函数(这个hci_packet_type_ 默认是HCI_PACKET_TYPE_UNKNOWN。可以看到会在HCI_PREAMBLE 和HCI_PAYLOAD 之间切换去读取数据,当数据读完之后会恢复HCI_PREAMBLE 状态,然后调用传进来的回调。看看使能蓝牙时 h4 的用法,可以看到,其会监听打开的 socket 文件描述符,有数据时就会调用 h4 协议的 OnDataReady 方法。

2025-02-12 20:06:36 457

原创 全网唯一!安卓WIFI连接源码剖析(从WifiManager到DHCP结束)

后续就是 wpa_supplicant 中先进行 select,找到匹配的网络后就会进行认证和关联和4WAY_HANDSHAKE,关联分为三个阶段(ASSOCIATING,ASSOCIATED,COMPLETED),4WAY_HANDSHAKE协商会话密钥,如果使用 WPA/PSK 的话 wifi 密码错误就会导致 4WAY_HANDSHAKE 失败,后续作者会继续更新 wpa_supplicant 中的源码分析。发送CMD_CONNECT_NETWORK 消息给状态机。

2025-02-11 22:10:38 992

原创 安卓WIFI连接三层网络配置源码剖析(DHCP)

这里转到DhcpRequestingState,这个类依旧是 PacketRetransmittingState 的子类,调用其 enter 方法发送 dhcp request。PacketRetransmittingState 的子类 DhcpInitState 实现了这个发送方法,发送 dhcp Discover 报文到dhcp 服务器。ClearingIpAddressesState 的 enter 方法发送CMD_ADDRESSES_CLEARED 由自己处理。

2025-02-11 21:50:50 687

原创 安卓15-frameworks层次状态机源码剖析

总结:这里主要是构造初始状态栈,以临时栈的方式保证初始状态位于状态栈栈顶,这里都是操作数组下标,真正的数组大小为计算出的最大深度,状态栈中保存当前状态及其父亲及祖先状态,退出状态即弹出栈,那么其父亲状态就位于栈顶了。分析HandlerThread的线程函数可以发现HandlerThread的looper是在线程函数中构建的,线程函数持有这个looper引用,前面传递到SmHandler的looper正是这个looper。获取一个消息,后续发送到looper的消息队列,插入到链表中。

2025-02-10 22:02:16 465

原创 安卓15 wifi 打开源码分析-从上层到wifi驱动及wpa_supplicant启动

以高通 wifi 驱动为例,insmod 的时候会调用 hdd_driver 的 init 函数,其会调用对外的字符设备驱动提供的 write 函数wlan_hdd_state_ctrl_param_write。一般在 boot 阶段 wifi 驱动已经安装了,这里主要是调用字符设备驱动写接口告诉 hdd_driver wifi 打开了。wifi 设置获取到 WifiManager 这个代理调用setWifiEnabled 打开 wifi。向状态机发送CMD_WIFI_TOGGLED 消息。

2025-02-10 20:38:10 986 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除