来自:https://wiki.openwrt.org/doc/devel/add.new.device
添加新的设备支持
本文假设您的设备基于OpenWrt已经支持的平台。如果需要添加新平台,请参阅→ add.new.platform
一般方法
-
在设备上列出芯片的详细信息,并找到有关其支持的信息。专注于处理器,闪存,以太网和无线。一些有用的提示可以在 hw.hacking.first.steps上 找到
-
确保您有工作的串行控制台和访问引导加载程序。
-
准备和安装固件,观察bootlog的问题和错误。
-
验证闪存分区,LED和按钮。
GPIO
大多数设备都使用GPIO来控制LED和按钮。没有任何通用的GPIO编号,所以OpenWrt必须使用特定于设备的映射。这意味着我们需要在每个支持的设备上找到每个可控LED和按钮的GPIO。
GPIO LED
如果LED由GPIO控制,则必须设置方向out
,我们需要知道极性:
-
如果指示灯亮起,值为1,则其为高电平有效
-
如果LED亮起为0,则其为低电平
单个GPIO可以通过以下方式进行测试:
cd /sys/class/gpio
GPIO=3
echo $GPIO > export
echo "out" > gpio$GPIO/direction
echo 0 > gpio$GPIO/value
sleep 1s
echo 1 > gpio$GPIO/value
sleep 1s
echo $GPIO > unexport
当然,每个GPIO(从0开始)都不得不进行测试,不仅仅是上面的例子中的一个GPIO 3。
所以基本上你需要创建一个表,如:
Color | Name | GPIO | Polarity |
---|---|---|---|
Green | Power | 0 | Active high |
Blue | WLAN | 7 | Active high |
Blue | USB | 12 | Active low |
为了加快测试所有GPIO,您可以使用以下bash脚本。请注意,您必须遵循LED状态和控制台输出。如果USB LED指示灯亮起,并且最后一个控制台消息是[GPIO12]测试值0
指USB LED使用GPIO 12并且处于低电平状态。
#!/bin/sh
GPIOCHIP=0
BASE=$(cat /sys/class/gpio/gpiochip${GPIOCHIP}/base)
NGPIO=$(cat /sys/class/gpio/gpiochip${GPIOCHIP}/ngpio)
max=$(($BASE+$NGPIO))
gpio=$BASE
while [ $gpio -lt $max ] ; do
echo $gpio > /sys/class/gpio/export
[ -d /sys/class/gpio/gpio${gpio} ] && {
echo out > /sys/class/gpio/gpio$gpio/direction
echo "[GPIO$gpio] Trying value 0"
echo 0 > /sys/class/gpio/gpio$gpio/value
sleep 3s
echo "[GPIO$gpio] Trying value 1"
echo 1 > /sys/class/gpio/gpio$gpio/value
sleep 3s
echo $gpio > /sys/class/gpio/unexport
}
gpio=$((gpio+1))
done
GPIO按钮
在按钮按下GPIO控制按钮值更改的情况下。所以最好的想法是找出哪些GPIO连接到一些硬件按钮是:
-
所有GPIO的转储值
-
按下按钮并按住它
-
所有GPIO的转储值
-
找出哪些GPIO改变了它的价值
可以使用以下脚本来转储GPIO值:
#!/bin/sh
GPIOCHIP=0
BASE=$(cat /sys/class/gpio/gpiochip${GPIOCHIP}/base)
NGPIO=$(cat /sys/class/gpio/gpiochip${GPIOCHIP}/ngpio)
max=$(($BASE+$NGPIO))
gpio=$BASE
while [ $gpio -lt $max ] ; do
echo $gpio > /sys/class/gpio/export
[ -d /sys/class/gpio/gpio${gpio} ] && {
echo in > /sys/class/gpio/gpio${gpio}/direction
echo "[GPIO${gpio}] value $(cat /sys/class/gpio/gpio${gpio}/value)"
echo ${gpio} > /sys/class/gpio/unexport
}
gpio=$((gpio+1))
done
如果GPIO值从1变为0,同时按下按钮,则其为低电平。否则它是高活跃。
示例表:
Name | GPIO | Polarity |
---|---|---|
WPS | 4 | Active low |
Reset | 6 | Active low |
KSEG1ADDR()并访问NOR闪存
要获取MAC地址,EEPROM和其他校准数据,您可能需要从内核中读取闪存。在使用NOR闪存的许多Atheros芯片的情况下,使用将CGI的硬件地址转换为执行init函数的进程上下文的虚拟地址的KSEG1ADDR()宏完成。如果您正在查看初始化与您自己的主板类似的代码,并且您看到这个idium:KSEG1ADDR(0x1fff0000),那么这个数字起初似乎是魔术的,但如果你明白了两件事情,这是合乎逻辑的。首先,使用NOR闪存将Atheros SoC连接到物理地址0x1f000000(不能保证闪存将连接到您的电路板,但这是一个常见的位置)。你不能依赖引导程序中给出的地址,你可能会看到0xbf000000,但这也可能是一个虚拟地址。如果您的电路板线闪烁到这些内存位置,您可能显然使用KSEG1ADDR(0x1f000000 + OFFSET_FROM_BEGIN)访问闪存,但是如果您必须访问知道的数据将存在于闪存的最后,您可以使用一个技巧使您的代码与多种大小的闪存兼容。通常,Flash将被映射到一个完整的16MB的地址空间,无论是4MB,8MB还是16MB,所以在这种情况下,KSEG1ADDR(0x20000000 - OFFSET_FROM_END)将用于访问你知道距离闪存 当您看到KSEG1ADDR(0x1fff0000)时,在具有4MB或8MB闪存的设备上,可以猜到,
例子
Brcm63xx平台
如果您具有bcm63xx特定设备的OEM源代码,以后添加OpenWrt支持可能会有用:
-
寻找你的董事会标识
shared/opensource/boardparms/boardparms.c
-
适应
imagetag.c
创建一个不同的标签(见shared/opensource/inlude/bcm963xx/bcmTag.h
在 GPL的布局焦油) -
最后xor整个图像与'12345678'(ascii字符串,而不是十六进制)。
(来自https://forum.openwrt.org/viewtopic.php?pid=123105#p123105)
要创建您的bcm63xx设备的OpenWrt固件,可以按照以下步骤操作:
-
在 menuconfig选择正确的目标系统。
-
接下来生成所有板级参数的board_bcm963xx.c文件,执行以下命令:
make kernel_menuconfig
将板ID添加到./target/linux/brcm63xx/image/Makefile。
例
# Davolink DV2020
$(call Image/Build/CFE,$(1),DV2020,6348)
将具有参数的board-id添加到./build_dir/linux-brcm63xx/linux-2.6.37.4/arch/mips/bcm63xx/boards/board_bcm963xx.c
示例
static struct board_info __initdata board_DV2020 = {
.name = "DV2020",
.expected_cpu_id = 0x6348,
.has_uart0 = 1,
.has_pci = 1,
.has_ohci0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.enet0 = {
.has_phy = 1,
.use_internal_phy = 1,
},
.enet1 = {
.force_speed_100 = 1,
.force_duplex_full = 1,
},
};
static const struct board_info __initdat
:
:
:
&board_DV2020,
-
按照步骤的步骤完成 编译指令。
Ramips平台
只要您使用现有芯片组添加对ipsip板的支持,这是相当简单的。您需要创建一个新的电路板定义,它将为您的设备专门生成一个映像文件,并运行特定于设备的代码。然后,您可以编写各种板卡特定的黑客来初始化设备并设置正确的默认配置。
您的电路板标识符将按以下顺序传递:
(Image Generator puts it in the kernel command line)
↓
(Kernel command line is executed with BOARD=MY_BOARD)
↓
(Kernel code for ramips finds your board and loads machine-specific code)
↓
(/lib/ramips.sh:ramips_board_name() reads the board name from /proc/cpuinfo)
↓
(Several userspace scripts use ramips_board_name() for board-specific setup)
至少,您需要进行以下更改以进行基本构建,全部在target / linux / ramips /下:
-
添加新的机器映像
image/Makefile
-
arch/mips/ralink/$CHIP/mach-myboard.c
在您注册的地方创建一个新的机器文件:-
用于LED和按钮的GPIO引脚
-
设备的端口布局(vlan配置)
-
闪存配置
-
无线上网
-
USB
-
看门狗定时器
-
还有其他特定于你的董事会的事情
-
-
引用新的机器文件
arch/mips/ralink/$CHIP/{Kconfig,Makefile}
-
参考新的机器名称
files/arch/mips/include/asm/mach-ralink/machine.h
-
将您的板添加到
base-files/lib/ramips.sh
用户空间脚本以读取板名称
然后,您将根据您的电路板的功能修改其中的一些文件:
-
base-files/etc/diag.sh
设置一个在启动时OpenWRT应该闪烁的LED -
base-files/lib/upgrade/platform.sh
以允许sysupgrade在您的电路板上工作 -
base-files/etc/uci-defaults/network
配置默认网络接口设置,特别是MAC地址 -
base-files/etc/uci-defaults/leds
如果您有可配置的LED应该默认为某种行为,如WLAN活动LED -
base-files/etc/hotplug.d/firmware/10-rt2x00-eeprom
提取无线模块的固件映像 -
base-files/lib/preinit/06_set_iface_mac
设置任何其他接口的MAC地址
示例提交:
提示
添加新板后,您可以tmp
先清理文件夹。
cd trunk
rm -rf tmp
make menuconfig
如果您添加了设备配置文件,并且它没有显示在“make menuconfig”中,请尝试触摸主要目标makefile
touch target/linux/*/Makefile