DD-WRT 设置全区(#a)

博通芯片的无线路由器刷 DD-WRT 之后,无线设置的区域中没有全区。若用nvram set手动设置 ccode 和 regrev,重启后设置会被 DD-WRT 复原,使用wl country可以改变区域,但无法将区域改为 #a 或 #r。

通过查看源码发现,这个限制位于内核模块 wl.ko 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static int
wlc_cntry_external_to_internal(char *buf, int buflen)
{
int err = BCME_OK;

/* Translate ALL or RDR to internal 2 char country codes. */
if (!strncmp(buf, "ALL", sizeof("ALL") - 1)) {
strncpy(buf, "#a", buflen);
} else if (!strncmp(buf, "RDR", sizeof("RDR") - 1)) {
strncpy(buf, "#r", buflen);
}
#if !defined(BCMDBG) && !defined(WLTEST)
/* Don't allow ALL or RDR in production. */
if ((!strncmp(buf, "#a", sizeof("#a") - 1)) || (!strncmp(buf, "#r", sizeof("#r") - 1))) {
err = BCME_BADARG;
}

#endif /* !defined(BCMDBG) && !defined(WLTEST) */
return err;
}

因此用 IDA 打开 wl.ko,搜索 “#a”,找到和源码匹配的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
; =============== S U B R O U T I N E =======================================

; Attributes: bp-based frame

_2394 ; CODE XREF: _2369+A4↑p
; _2393+154↓p ...
MOV R12, SP
STMFD SP!, {R4,R5,R11,R12,LR,PC}
SUB R11, R12, #4
MOV R5, R1
MOV R1, #:lower16:_994_14 ; "ALL"
MOV R2, #3 ; size_t
MOVT R1, #:upper16:_994_14 ; "ALL"
MOV R4, R0
BL strncmp
CMP R0, #0
BNE loc_1C5CE0
MOV R1, #:lower16:_1048_10 ; "#a"
MOV R2, R5 ; size_t
MOVT R1, #:upper16:_1048_10 ; "#a"
MOV R0, R4 ; char *
BL strncpy
B loc_1C5D10
; ---------------------------------------------------------------------------

loc_1C5CE0 ; CODE XREF: _2394+28↑j
MOV R1, #:lower16:_1059_8 ; "RDR"
MOV R2, #3 ; size_t
MOVT R1, #:upper16:_1059_8 ; "RDR"
MOV R0, R4 ; char *
BL strncmp
CMP R0, #0
BNE loc_1C5D10
MOV R1, #:lower16:_1070_8 ; "#r"
MOV R2, R5 ; size_t
MOVT R1, #:upper16:_1070_8 ; "#r"
MOV R0, R4 ; char *
BL strncpy

loc_1C5D10 ; CODE XREF: _2394+40↑j
; _2394+5C↑j
MOV R1, #:lower16:_1048_10 ; "#a"
MOV R2, #2 ; size_t
MOVT R1, #:upper16:_1048_10 ; "#a"
MOV R0, R4 ; char *
BL strncmp
CMP R0, #0
BEQ loc_1C5D48
MOV R1, #:lower16:_1070_8 ; "#r"
MOV R0, R4 ; char *
MOVT R1, #:upper16:_1070_8 ; "#r"
MOV R2, #2 ; size_t
BL strncmp
CMP R0, #0
BNE loc_1C5D50

loc_1C5D48 ; CODE XREF: _2394+8C↑j
MOV R0, #0xFFFFFFFE
LDMFD SP, {R4,R5,R11,SP,PC}
; ---------------------------------------------------------------------------

loc_1C5D50 ; CODE XREF: _2394+A8↑j
MOV R0, #0
LDMFD SP, {R4,R5,R11,SP,PC}
; End of function _2394

MOV R0, #0xFFFFFFFE(01 00 E0 E3)改成MOV R0, #0x0(00 00 A0 E3)即可。
最后使用 firmware-mod-kit 替换 wl.ko,重新打包并刷入,使用wl country ALL即可设置成全区

更新:如果修改 wl.ko 后执行wl country ALL仍然提示wl: Bad Argument,则说明无线网卡在固件层面有限制,这种情况可以尝试使用旧版无线固件,或改到最大允许发射功率较大的地区(2.4G:wl country AU/30; 5G:wl country US/0)。