openwrt无线初始化脚本mac80211.sh详解

脚本概述

mac80211.sh 是 OpenWrt 中用于配置和管理基于 mac80211 驱动程序的无线接口的脚本。它位于 package/network/config/wifi-scripts/files/lib/wifi/ 目录下,负责刷写固件后首次启动时处理无线网络接口的初始化、配置和启动。

脚本功能

该脚本的主要功能是刷写固件后首次启动时初始化无线网络接口、配置无线网络参数

关键函数解析

脚本中一些关键函数的作用和实现方式,如 check_mac80211_deviceget_band_defaultscheck_devidx 等。这些函数负责具体的无线网络接口管理任务。

部分函数详解
  • check_mac80211_device函数
#该函数是 OpenWrt 无线设备自动配置的核心校验逻辑,通过 ​​双重匹配机制(路径+MAC)​​ 确保:
#避免重复配置已存在的设备
#兼容不同硬件识别方式(内核命名 vs 板级 JSON 定义)
#处理多 PHY 设备的复杂场景
check_mac80211_device() {
	local device="$1"  # UCI 配置中的设备节点名(如 "radio0")
	local path="$2"    # 待检查的物理设备路径(来自 /sys/class/ieee80211)
	local macaddr="$3" # 待检查的 MAC 地址(来自硬件)

	[ -n "$found" ] && return 0 # 已找到设备时直接退出,快速终止已匹配成功的后续检查

	phy_path=  # 清空物理路径变量
	config_get phy "$device" phy  # 从 UCI 读取设备的 phy 字段,若 device=radio0,可能读取到 phy=phy0
	json_select wlan  # 进入 /etc/board.json 的 wlan 配置段
	[ -n "$phy" ] && case "$phy" in
		phy*)   # PHY 是内核命名(如 phy0)
			[ -d /sys/class/ieee80211/$phy ] && \
				phy_path="$(iwinfo nl80211 path "$dev")"   # 通过工具获取路径
		;;
		*)  # PHY 是 JSON 对象
			if json_is_a "$phy" object; then  # 完整对象(如 "phy0")
				json_select "$phy"
				json_get_var phy_path path   # 提取 path 字段
				json_select ..
			elif json_is_a "${phy%.*}" object; then  # 子对象(如 "phy0.1")
				json_select "${phy%.*}"  # 提取父对象(phy0)
				json_get_var phy_path path  # 获取父路径
				json_select ..
				phy_path="$phy_path+${phy##*.}"  # 拼接子路径(phy0+1)
			fi
		;;
	esac
	json_select ..  # 退出 JSON 的 wlan 段
	[ -n "$phy_path" ] || config_get phy_path "$device" path  # 后备读取 path
	[ -n "$path" -a "$phy_path" = "$path" ] && {  # 路径比对
		found=1  # 标记已找到
		return 0 # 优先通过路径匹配退出
	}

	config_get dev_macaddr "$device" macaddr  # 从 UCI 读取 MAC

	[ -n "$macaddr" -a "$dev_macaddr" = "$macaddr" ] && found=1   
	# MAC比对:上面的路径匹配失败时,通过 MAC 地址二次验证

	return 0
}

  • get_band_defaults函数
# 这个函数的主要功能是 ​​为指定的无线设备(phy)确定默认的频段、信道和工作模式
get_band_defaults() {
    # 定义函数,接收一个参数phy(物理无线设备)
	local phy="$1"
	
	# 遍历调用__get_band_defaults函数获取的列表,每个元素用c表示
	for c in $(__get_band_defaults "$phy"); do
		# 分割c的值,格式为 band:channel:mode
		local band="${c%%:*}" # 提取第一个字段(频段编号)
		c="${c#*:}"           # 剩余部分(移除第一个字段)
		local chan="${c%%:*}" # 提取第二个字段(信道)
		c="${c#*:}"           # 剩余部分(移除第二个字段)
		local mode="${c%%:*}" # 提取第三个字段(模式,如HT40)


		# 将频段编号转换为可读名称
		case "$band" in
			1) band=2g;;  # 1对应2.4GHz
			2) band=5g;;  # 2对应5GHz
			3) band=60g;; # 3对应60GHz(较少见)
			4) band=6g;;  # 4对应6GHz(Wi-Fi 6E)
			*) band="";;  # 其他值视为无效
		esac
		 # 跳过无效频段
		[ -n "$band" ] || continue
		# 若已存在mode_band且当前是6GHz频段,则直接返回,优先处理6GHZ
		[ -n "$mode_band" -a "$band" = "6g" ] && return

		# 设置当前频段的默认参数
		mode_band="$band" # 频段名称(如6g)
		channel="$chan"   # 默认信道
		htmode="$mode"    # 带宽模式
	done
}

使用例子

  • 设置默认的无线名称,信道以及工作模式
detect_mac80211() {
	devidx=0
	config_load wireless
	config_foreach check_devidx wifi-device

	json_load_file /etc/board.json

	for _dev in /sys/class/ieee80211/*; do
		[ -e "$_dev" ] || continue

		dev="${_dev##*/}"

		mode_band=""
		channel=""
		htmode=""
		ht_capab=""

		get_band_defaults "$dev"

		path="$(iwinfo nl80211 path "$dev")"
		macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)"

		# work around phy rename related race condition
		[ -n "$path" -o -n "$macaddr" ] || continue

		board_dev=
		fallback_board_dev=
		json_for_each_item check_board_phy wlan
		[ -n "$board_dev" ] || board_dev="$fallback_board_dev"
		[ -n "$board_dev" ] && dev="$board_dev"

		found=
		config_foreach check_mac80211_device wifi-device "$path" "$macaddr"
		[ -n "$found" ] && continue

		name="radio${devidx}"
		devidx=$(($devidx + 1))
		case "$dev" in
			phy*)
				if [ -n "$path" ]; then
					dev_id="set wireless.${name}.path='$path'"
				else
					dev_id="set wireless.${name}.macaddr='$macaddr'"
				fi
				;;
			*)
				dev_id="set wireless.${name}.phy='$dev'"
				;;
		esac
		
		# set wireless.default_${name}.ssid=$(echo $mode_band | grep -q '2g' && echo 'ceshi' || echo 'ceshi-5G')   
		# 这行代码设置了无线2.4G和5G的默认ssid
		# set wireless.default_${name}.encryption=psk+ccmp 
		# 这行代码设置了默认工作模式为psk+ccmp
		# set wireless.default_${name}.key='12345678'
		# 这行代码设置了无线的默认密码为12345678
		uci -q batch <<-EOF
		      	set wireless.${name}=wifi-device
		      	set wireless.${name}.type=mac80211
		      	${dev_id}
		      	set wireless.${name}.channel=${channel:-auto}                 
		      	set wireless.${name}.band=${mode_band}                        
		      	set wireless.${name}.htmode=$htmode                          
		     	set wireless.${name}.cell_density=0
		     	set wireless.${name}.legacy_rates=1
		     	set wireless.default_${name}=wifi-iface
		      	set wireless.default_${name}.device=${name}
		     	set wireless.default_${name}.network=lan
		      	set wireless.default_${name}.mode=ap
		     	set wireless.default_${name}.ssid=$(echo $mode_band | grep -q '2g' && echo 'ceshi' || echo 'ceshi-5G')   
		      	set wireless.default_${name}.encryption=psk+ccmp            
		      	set wireless.default_${name}.key='12345678'                  
EOF
		uci -q commit wireless
	done
}

ps:有注释的那几行就是修改了的代码,其他代码未修改。

总结:修改完成后运行make V=99重新编译固件重新刷机选择不保存配置即可设置默认的ssid、工作模式以及wifi秘钥。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忘帆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值