openwrt添加新平台支持

来自:https://wiki.openwrt.org/doc/devel/add.new.platform

添加新的平台支持

您可以找到目前支持的所有https://dev.openwrt.org/wiki/platforms的列表。也许没有必要添加一个全新的平台,但只有一个新的设备,请参阅→ add.new.device

由于Linux的开放性以及可运行的各种平台,Linux现在是嵌入式设备最广泛的操作系统之一。许多制造商实际上在固件中使用它可以在许多设备上找到:DVB-T解码器,路由器,打印服务器,DVD播放器。大多数时候,即使使用开源软件,库存固件对消费者来说并不是真的开放。

您可能有兴趣为您的路由器运行基于Linux的固件,原因如下:扩展使用网络协议(如IPv6),具有新功能,内置新软件或出于安全考虑。完全开源固件对于这样的应用程序来说是事实上需要的,因为您想要自由使用这个或特定原因的版本,可以纠正特定的错误。很少有制造商使用样品开发套件运送他们的路由器,这将允许您创建自己的和自定义的固件,大多数时候,如果这样做,您很可能无法完成固件创建过程。

这是OpenWrt和其他固件存在的原因之一:提供独立的版本和独立于工具的固件,可以在各种平台上运行,这些平台本来就是运行Linux的。

该设备运行的是哪个操作系统?

确保您的设备运行Linux有很多方法。其中一些确实需要您的路由器被拧开和打开,有些可以通过使用其外部网络接口探测设备来完成。

操作系统指纹识别和端口扫描

Internet上存在大量工具,以便让您进行操作系统指纹,我们将在这里显示一个使用nmap的示例:

nmap -P0 -O IP address
Starting Nmap 4.20 ( http://insecure.org ) at 2007-01-08 11:05 CET
Interesting ports on 192.168.2.1:
Not shown: 1693 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
23/tcp open  telnet
53/tcp open  domain
80/tcp open  http
MAC Address: 00:13:xx:xx:xx:xx (Cisco-Linksys)
Device type: broadband router
Running: Linksys embedded
OS details: Linksys WRT54GS v4 running OpenWrt w/Linux kernel 2.4.30
Network Distance: 1 hop

nmap的工具是能够报告您的设备是否使用Linux TCP / IP协议栈,如果有的话,会告诉你哪个Linux内核版本可能是运行。本报告相当可靠,可以区分BSD和Linux TCP / IP协议栈等。

使用相同的工具,您还可以进行端口扫描和服务版本发现。例如,以下命令将报告在设备上运行哪些基于IP的服务,以及正在使用哪个版本的服务:

nmap -P0 -sV IP address
Starting Nmap 4.20 ( http://insecure.org ) at 2007-01-08 11:06 CET  
Interesting ports on 192.168.2.1:  
Not shown: 1693 closed ports  
PORT   STATE SERVICE VERSION  
22/tcp open  ssh     Dropbear sshd 0.48 (protocol 2.0)  
23/tcp open  telnet  Busybox telnetd  
53/tcp open  domain  ISC Bind dnsmasq-2.35  
80/tcp open  http    OpenWrt BusyBox httpd  
MAC Address: 00:13:xx:xx:xx:xx (Cisco-Linksys)  
Service Info: Device: WAP

Web服务器版本(如果已标识)可以在知道操作系统时确定。例如,BOA Web服务器通常来自运行开源Unix或类Unix的设备。

无线通信指纹识别

虽然这种方法不是真正的知道和广泛使用,使用无线扫描器来发现您的路由器或接入点运行可以使用哪个操作系统。我们没有一个明确的例子说明如何实现这一点,但是您必须监控原始的802.11帧并将其与运行基于Linux的固件的类似设备进行比较。

Web服务器安全漏洞

Linksys WRT54G最初被使用在网络界面中发现的“ping bug”被黑客入侵。Linksys尚未修复此提示,允许人们通过Web界面启用“boot_wait”帮助程序。在固件中使用的许多Web服务器都是开源Web服务器,因此可以对代码进行审计以找到漏洞。一旦您知道在设备上运行的Web服务器版本,通过使用nmap -sV等等,您可能有兴趣使用漏洞利用设备上的shell访问。

本地Telnet / SSH访问

一些固件可能会受到限制或无限制的Telnet / SSH访问,如果是,请尝试使用Web界面登录/密码登录,看看是否可以输入一些命令。实际上这是一些基于Broadcom BCM963xx的固件,例如Neuf / Cegetel ISP路由器,Club-Internet ISP CI-Box等许多固件。一些命令,如猫可能会留在这里,并用于确定Linux内核版本。

分析二进制固件镜像

您很可能在制造商网站上找到固件二进制镜像,即使您的设备运行专有操作系统。如果是这样,您可以下载它,并使用十六进制编辑器查找可打印的单词,如vmlinux,linux,ramdisk,mtd等。

某些Unix工具喜欢hexdumpstrings可以用于分析固件。下面是一个在互联网上找到的二进制固件的例子:

hexdump -C <binary image.extension> | less 
00000000  46 49 52 45 32 2e 35 2e  30 00 00 00 00 00 00 00  |FIRE2.5.0.......|  
00000010  00 00 00 00 31 2e 30 2e  30 00 00 00 00 00 00 00  |....1.0.0.......|  
00000020  00 00 00 00 00 00 00 38  00 43 36 29 00 0a e6 dc  |.......8.C6)..??|  
00000030  54 49 44 45 92 89 54 66  1f 8b 08 08 f8 10 68 42  |TIDE..Tf....?.hB|  
00000040  02 03 72 61 6d 64 69 73  6b 00 ec 7d 09 bc d5 d3  |..ramdisk.?}.???|  
00000050  da ff f3 9b f7 39 7b ef  73 f6 19 3b 53 67 ea 44  |???.?9{?s?.;Sg?D|

滚动固件以查找可以显示的可打印字词。

闪存量

一旦您打开设备并找到闪存芯片,Linux就无法安装在2MB闪存设备中,试图在Internet上查找其特性。如果您的闪存芯片是2MB或更少的设备,您的设备最有可能运行专有操作系统,如WindRiver VxWorks或Zyxel ZynOS等定制制造商操作系统

OpenWrt目​​前不在具有2MB或更少闪存的设备上运行。这个限制可能不会被解决,因为这些设备大多数时候是微路由器,或无线接入点,这不是主要的OpenWrt目​​标。

插入串口

通过使用串行端口和电平转换器,您可以到设备显示的控制台进行调试或闪烁。通过分析此设备的输出,您可以轻松注意到设备是否使用Linux内核或其他不同的内容。

查找并使用制造商SDK

一旦确定您的设备运行基于Linux的固件,您就可以开始对其进行黑客入侵。如果制造商遵守GPL,它将发布一个样品开发套件与该设备。

GPL违规

一些制造商确实发布了一个基于Linux的二进制固件,根本没有源代码。做任何事情之前的第一步是阅读您的设备随附的许可证,然后写下这些缺乏开源代码。如果制造商回答您,他们不必发布包含开源软件的SDK,那么我们建议您与gpl-violations.org社区保持联系。

您可以在下面找到可以发送给制造商的样品信件:

Miss, Mister,

I am using a device name, and I cannot find neither on your website nor on the CD-ROM 
the open source software used to build or modify the firmware.

In conformance to the GPL license, you have to release the following sources:

 * complete toolchain that made the kernel and applications be compiled (gcc, binutils, libc)
 * tools to build a custom firmware (mksquashfs, mkcramfs …)
 * kernel sources with patches to make it run on this specific hardware, this does not include binary drivers

Thank you very much in advance for your answer.

Best regards, Your Name

使用SDK

一旦SDK可用,您很可能无法使用它构建完整的或功能完整的固件,但其部分内容(如内核)或只有根文件系统。大多数制造商并不关心发布每次解压缩并使用它的工具。

您应该能够使用以下组件:

  • 具有或多或少功能补丁的内核源代码
  • 链接的二进制驱动程序或与发送的内核版本链接
  • 用于编译整个固件的工具链软件包:gcc,binutils,libc或uClibc
  • 二进制工具创建有效的固件镜像

您的工作可分为以下任务:

  • 创建一个干净的补丁的硬件特定部分的Linux内核
  • 潜在的内核 GPL违规,特别是在网络堆栈和USB堆栈的东西
  • 使二进制驱动程序工作,直到有开源驱动程序
  • 使用标准的GNU工具链来创建可执行文件
  • 了解和编写开源工具来生成有效的固件镜像

创建硬件特定的内核补丁

大多数时候,与SDK一起提供的内核源代码并不是很干净,而且不是标准的Linux版本,它还具有从内核开发树的CVS或git仓库返回的架构特定修复。无论如何,一些零件可以很容易地隔离,并作为一个好的开始,使一个香草内核工作你的硬件。

一些目录很可能需要进行本地修改,以便在Linux下识别和使用您的硬件。首先,您需要找出硬件使用的linux内核版本,这可以通过编辑linux / Makefile文件来找到。

head -5 linux-2.x.x/Makefile  
VERSION = 2  
PATCHLEVEL = x  
SUBLEVEL = y  
EXTRAVERSION = z  
NAME=A fancy name

所以现在,你知道你必须在kernel.org下下载一个与硬件使用的版本相匹配的标准内核tarball。

然后,您可以在两个树之间创建一个diff文件,特别是对于以下目录:

diff -urN linux-2.x.x/arch/sub architecture linux-2.x.x-modified/arch/sub architecture > 01-architecture.patch  
diff -urN linux-2.x.x/include/ linux-2.x.x-modified/include > 02-includes.patch  
diff -urN linux-2.x.x/drivers/ linux-2.x.x-modified/drivers > 03-drivers.patch

这将构成一组基本的三个补丁,这些补丁很有可能包含任何需要修改的内存,用于在您的特定设备上运行库存的Linux内核。当然,diff -urN产生的内容可能并不总是相关的,所以你必须清理这些补丁,只允许“必须”代码。

第一个补丁将包含板子在启动时初始化所需的所有代码,以及处理器检测和其他引导时间特定的修复。

第二个补丁将包含该板的所有有用的定义:地址,内核粒度,重新定义,处理器系列和功能...

第三个补丁可能包含以下驱动程序:串行控制台,以太网网卡,无线网卡,USB网卡...大部分时间此补丁程序除了添加的“胶”代码之外,还可以使二进制驱动程序与Linux内核一起使用。如果您计划从头开始为此硬件编写驱动程序,则此代码可能无用。

使用设备引导加载程序

引导程序是正确的启动您的设备已通电后的第一个项目。这个程序可以是或多或少的复杂,有些做让网络启动,USB大容量存储启动...引导加载程序是设备和架构特定的,一些引导程序被设计为通用的,如RedBoot或Das U-Boot,以便您可以在完全不同的平台上满足这些装载机,并期望它们的行为方式相同。

如果您的设备运行专有的操作系​​统,那么您很有可能会处理专有的启动加载程序。这可能并不总是限制,一些专有的启动程序甚至可以提供源代码(即:Broadcom CFE)。

根据引导加载程序的功能,设备上的黑客将或多或少更容易。引导加载程序(甚至异乎寻常的,罕见的)很有可能在Internet上有一个文档。为了知道您的引导程序和您将要窃取设备的方式是什么,请查看以下功能:

  • 引导程序是否允许通过网络引导  BOOTP/PXE/DHCP/NFS or TFTP?
  • bootloader是否接受加载   ELF  二进制文件?
  • 引导程序是否具有内核/固件大小限制?
  • 引导程序是否希望将某些魔术值作为固件的一部分,或要加密的固件?
  • 引导程序是否期望固件格式加载?
  • 是从RAM或闪存执行的加载文件?

网络引导是非常方便的,因为您只需要在开发站上设置网络启动服务器,并将原始固件保留在设备上,直到您确定可以替换它。这也可以防止您的设备闪烁,并且每次您想要测试内核/文件系统上的修改时,都可能会发生破裂。

如果您的设备需要在每次加载固件时闪烁,则Bootlader可能只接受要加载的特定固件格式,以便您也必须了解固件格式。

使二进制驱动器工作

正如我们之前解释的,制造商在GPL压缩包中发布二进制驱动程序。当这些驱动程序静态链接到内核时,它们也成为GPL,幸运的是,不幸的是,大多数驱动程序没有静态链接。这样可以让您有机会将驱动程序与当前的内核版本进行动态链接,并尝试让它们一起工作。

这是完全开放源码项目中最棘手和灰色的部分之一。一些驱动程序需要很少的修改才能使用自定义内核,因为它们与较早的内核配合使用,对这些版本之间的内核进行了很少的修改。例如,与Broadcom BCM43xx无线芯片组的二进制驱动程序相比,网络接口结构几乎没有区别。

无论使用哪个内核版本以使二进制驱动程序与您的自定义内核一起工作,也可以应用一些一般原则:

  • 打开内核调试功能,如:
    • CONFIG_DEBUG_KERNEL
    • CONFIG_DETECT_SOFTLOCKUP
    • CONFIG_DEBUG_KOBJECT
    • CONFIG_KALLSYMS
    • CONFIG_KALLSYMS_ALL
  • 链接二进制驱动程序可能到当前内核版本
  • 尝试加载这些二进制驱动程序
  • 抓住锁定并了解他们

大多数情况下,加载二进制驱动将失败,并生成一个内核哎呀。您可以知道二进制驱动程序尝试使用的最后一个符号,并在内核头文件中查看,如果您不必在该符号之前或之后移动一些结构字段,以便与二进制驱动程序和库存内核保持兼容驱动程序。

了解固件格式

您可能希望了解固件格式,即使您尚未能够在设备上运行自定义固件,因为这有时是闪烁过程的阻挡部分。

固件格式大部分时间由以下字段组成:

  • 标题,包含固件版本和其他字段:供应商,硬件版本...
  • 在整个文件或只是其一部分的CRC32校验和
  • 二进制和/或压缩的内核映像
  • 二进制和/或压缩的根文件系统映像
  • 潜在的垃圾

一旦知道固件格式如何分区,您将必须编写自己的工具来生成有效的固件二进制文件。这里要非常小心的一点是产生二进制固件的机器和使用这个二进制固件闪存的设备的字节顺序。

编写Flash映射驱动程序

闪存映射驱动程序在使您的自定义固件工作时起着重要的作用,因为它负责将正确的闪存区域和相关权限映射到系统的特定部分,例如:bootloader,内核,用户文件系统。

编写自己的闪存映射驱动程序一旦知道固件映像和闪存的结构如何,就不是一件艰巨的任务。您将在下面找到一个注释示例,其中涵盖了引导程序可以将其分区计划传递给内核的设备的情况。

首先,您需要在内核配置选项中使您的Flash映射驱动程序可见,这可以通过编辑文件来完成 linux/drivers/mtd/maps/Kconfig

config MTD_DEVICE_FLASH  
        tristate "Device Flash device"  
        depends on ARCHITECTURE && DEVICE  
        help  
         Flash memory access on DEVICE boards. Currently only works with  
         Bootloader Foo and Bootloader Bar.
然后将您的源文件添加到linux / drivers / mtd / maps / Makefile中,以便与内核一起编译。
obj-$(CONFIG_MTD_DEVICE_FLASH)      += device-flash.o
然后,您可以通过创建 linux/drivers/mtd/maps/device-flash.cC源文件来编写内核驱动程序。
// Includes that are required for the flash map driver to know of the prototypes:  
#include <asm/io.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/vmalloc.h>
 
// Put some flash map definitions here:  
#define WINDOW_ADDR 0x1FC00000	/* Real address of the flash */
#define WINDOW_SIZE 0x400000	/* Size of flash */
#define BUSWIDTH 2		/* Buswidth */
 
static void __exit device_mtd_cleanup(void);
 
static struct mtd_info *device_mtd_info;
 
static struct map_info devicd_map = {
	.name = "device",
	.size = WINDOW_SIZE,
	.bankwidth = BUSWIDTH,
	.phys = WINDOW_ADDR,
};
 
static int __init device_mtd_init(void)
{
	// Display that we found a flash map device  
	printk("device: 0x\%08x at 0x\%08x\n", WINDOW_SIZE, WINDOW_ADDR);
 
	// Remap the device address to a kernel address  
	device_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
 
	// If impossible to remap, exit with the EIO error  
	if (!device_map.virt) {
		printk("device: Failed to ioremap\n");
		return -EIO;
	}
	// Initialize the device map  
	simple_map_init(&device_map);
 
	/* MTD informations are closely linked to the flash map device  
	   you might also use "jedec_probe" "amd_probe" or "intel_probe" */
	device_mtd_info = do_map_probe("cfi_probe", &device_map);
 
	if (device_mtd_info) {
		device_mtd_info->owner = THIS_MODULE;
 
		int parsed_nr_parts = 0;
 
		// We try here to use the partition schema provided by the bootloader specific code  
		if (parsed_nr_parts == 0) {
			int ret =
			    parse_bootloader_partitions(device_mtd_info,
							&parsed_parts, 0);
			if (ret > 0) {
				part_type = "BootLoader";
				parsed_nr_parts = ret;
			}
		}
 
		add_mtd_partitions(devicd_mtd_info, parsed_parts,
				   parsed_nr_parts);
 
		return 0;
	}
	iounmap(device_map.virt);
 
	return -ENXIO;
}
 
// This function will make the driver clean up the MTD device mapping  
static void __exit device_mtd_cleanup(void)
{
	// If we found a MTD device before  
	if (device_mtd_info) {
		// Delete every partitions  
		del_mtd_partitions(device_mtd_info);
		// Delete the associated map  
		map_destroy(device_mtd_info);
	}
 
	// If the virtual address is already in use  
	if (device_map.virt) {
		// Unmap the physical address to a kernel space address  
		iounmap(device_map.virt);
 
		// Reset the structure field  
		device_map.virt = 0;
	}
}
 
// Macros that indicate which function is called on loading/unloading the module  
module_init(device_mtd_init);
module_exit(device_mtd_cleanup);
 
// Macros defining license and author, parameters can be defined here too.  
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Me, myself and I <memyselfandi@domain.tld>");


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值