ramips: Add support for Beeline SmartBox TURBO+ (#8161)

* ramips: add support for Beeline(Sercomm) U-Boot

- Add recipe for several Beeline/Sercomm devices (e.g., Beeline SmartBox
  GIGA, Beeline SmartBox Turbo+, Sercomm S3) that appends special header
  to a kernel.

- Add device variables KERNEL_LOADADDR, LZMA_TEXT_START. It's also
  necessary for the devices mentioned above.

Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>
(cherry picked from commit 6240da24f4c1442b0f750f06be512f630b0bc6c8)
Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>

* ramips: Add support for Beeline SmartBox TURBO+

This PR adds support for router Beeline Smart Box TURBO+.
OEM/ODM Serсomm. Almost identical to Serсomm S3.

Specification
-------------
SoC Type: MediaTek MT7621AT (880 MHz, 2 cores)
RAM (Nanya NT5CC64M16GP): 128 MiB
Flash (Macronix MX30LF1G18AC): 128 MiB
Wireless 2.4 GHz (MT7603EN): b/g/n, 2x2
Wireless 5 GHz (MT7615N): a/n/ac, 4x4
Ethernet: 5 ports - 5×GbE (WAN, LAN1-4)
USB ports: 1xUSB3.0
Buttons: 2 button (reset, wps)
LEDs: Red, Green, Blue
Zigbee (EFR32MG1B232GG): 3.0
Stock bootloader: U-Boot 1.1.3
Power: 12 VDC, 1.5 A

Installation
------------
Attach serial console, then boot the initramfs image via TFTP.
Once inside OpenWrt, run sysupgrade -n with the sysupgrade file.

Signed-off-by: Maximilian Weinmann <x1@disroot.org>
(cherry picked from commit d1f294521bd8bc462c76e09c57a5c8b0600170cd)
(factory recipe from a2cfe339995467308c9126c3d0f70d2a28aeb073)
(big NAND from e6e5837a625ba09e286a5bde05f2ce581cfbeab7)
(removed nvmem cells, fixed conflicts)
Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>

* ramips: add Sercomm partition map parser

This adds an MTD partition parser for the Sercomm partition table that
is used in some Netgear routers.

This is essentially the same code as proposed in the pull request for
Netgear R6350 support by NOGUCHI Hiroshi <drvlabo@gmail.com>:
https://github.com/openwrt/openwrt/pull/1318

It was originally rejected as it did not seem to work correctly.
However, this was only due the NAND driver transparently shifting pages
to hide bad blocks, which was fixed in commit
527832e54bf3bc4d699a145ae66f34230246f0a9.

Signed-off-by: Jan Hoffmann <jan@3e8.eu>
[x1@disroot.org: correction from checkpatch.pl]
Signed-off-by: Maximilian Weinmann <x1@disroot.org>
(cherry picked from commit 65e772105f8d5e98a999b836fed794b7415f2741)
Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>

* ramips: Improve Beeline Smartbox Turbo+ support in lede

Changed switch configuration and a few minor changes.

Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>

Co-authored-by: Maximilian Weinmann <x1@disroot.org>
Co-authored-by: Jan Hoffmann <jan@3e8.eu>
This commit is contained in:
csharper2005 2021-11-03 07:16:32 +03:00 committed by GitHub
parent 8d9e14b6ee
commit 7c0b920f18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 660 additions and 3 deletions

View File

@ -28,6 +28,10 @@ ampedwireless,ally-00x19k|\
ampedwireless,ally-r1900k)
ubootenv_add_uci_config "/dev/mtd1" "0x0" "0x1000" "0x20000" "4"
;;
beeline,smartbox-giga|\
beeline,smartbox-turbo-plus)
ubootenv_add_uci_config "/dev/mtd0" "0x80000" "0x1000" "0x20000"
;;
buffalo,wsr-1166dhp|\
buffalo,wsr-600dhp|\
mediatek,linkit-smart-7688|\

122
scripts/sercomm-kernel.sh Executable file
View File

@ -0,0 +1,122 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (c) 2021 Mikhail Zhilkin <csharper2005@gmail.com>
#
###
### sercomm-kernel.sh - calculates and appends a special kernel header.
### Intended for some Sercomm devices (e.g., Beeline
### SmartBox GIGA, Beeline SmartBox Turbo+, Sercomm
### S3).
#
# Credits to @kar200 for the header description. More details are here:
# https://forum.openwrt.org/t/add-support-for-sercomm-s3-on-stock-uboot
#
if [ $# -ne 3 ]; then
echo "SYNTAX: $0 <kernel> <kernel_offset> <rootfs_offset>"
exit 1
fi
FILE_TMP=$1.shdr
KERNEL_IMG=$1
KERNEL_OFFSET=$2
ROOTFS_OFFSET=$3
# Sercomm HDR (0x53657200), 0xffffffff for hdr crc32 calc
hdr_sign_offs=0x0
hdr_sign_val=0x53657200
# Absoulte lenght for Sercomm footer
hdr_footer_size_offs=0x4
hdr_footer_size_val=
# Header checksum. 0xffffffff for hdr crc32 calc
hdr_head_chksum_offs=0x8
hdr_head_chksum_val=
# Magic constant (0x2ffffff)
hdr_int04_offs=0xc
hdr_int04_val=0x2ffffff
# Kernel flash offset
hdr_kern_offs_offs=0x10
hdr_kern_offs_val=$KERNEL_OFFSET
# Kernel lenght
hdr_kern_len_offs=0x14
hdr_kern_len_val=
# Kernel checksum
hdr_kern_chksum_offs=0x18
hdr_kern_chksum_val=
# Magic constant (0x0)
hdr_int08_offs=0x1c
hdr_int08_val=0x0
# Rootfs flash offset
hdr_rootfs_offs_offs=0x28
hdr_rootfs_offs_val=$ROOTFS_OFFSET
# Rootfs flash lenght. We're checking only first 4 bytes
hdr_rootfs_len_offs=0x2c
hdr_rootfs_len_val=0x4
# Rootfs checksum. Checksum is a constant for UBI (first 4 bytes)
hdr_rootfs_chksum_offs=0x30
hdr_rootfs_chksum_val=0x1cfc552d
# Magic constant (0x0)
hdr_int10_offs=0x34
hdr_int10_val=0x0
pad_zeros () {
awk '{ printf "%8s\n", $0 }' | sed 's/ /0/g'
}
# Remove leading 0x
trim_hx () {
printf "%x\n" $1 | pad_zeros
}
# Change endian
swap_hx () {
pad_zeros | awk '{for (i=7;i>=1;i=i-2) printf "%s%s", \
substr($1,i,2), (i>1?"":"\n")}'
}
# Check file size
fsize () {
printf "%x\n" `stat -c "%s" $1`
}
# Calculate checksum
chksum () {
dd if=$1 2>/dev/null | gzip -c | tail -c 8 | od -An -tx4 -N4 \
--endian=big | tr -d ' \n' | pad_zeros
}
# Write 4 bytes in the header by offset
write_hdr () {
echo -ne "$(echo $1 | sed 's/../\\x&/g')" | dd of=$FILE_TMP bs=1 \
seek=$(($2)) count=4 conv=notrunc status=none 2>/dev/null
}
# Pad a new header with 0xff
dd if=/dev/zero ibs=1 count=256 status=none | tr "\000" "\377" > \
$FILE_TMP 2>/dev/null
# Write constants
write_hdr $(trim_hx $hdr_int04_val) $hdr_int04_offs
write_hdr $(trim_hx $hdr_int08_val) $hdr_int08_offs
write_hdr $(trim_hx $hdr_int10_val) $hdr_int10_offs
# Write footer data
hdr_footer_size_val=$(($hdr_rootfs_offs_val + $hdr_rootfs_len_val))
write_hdr $(trim_hx $hdr_footer_size_val | swap_hx) $hdr_footer_size_offs
# Write kernel data
write_hdr $(trim_hx $hdr_kern_offs_val | swap_hx) $hdr_kern_offs_offs
hdr_kern_len_val=$(fsize $KERNEL_IMG | pad_zeros)
write_hdr $(echo $hdr_kern_len_val | swap_hx) $hdr_kern_len_offs
hdr_kern_chksum_val=$(chksum $KERNEL_IMG)
write_hdr $hdr_kern_chksum_val $hdr_kern_chksum_offs
# Write rootfs data
write_hdr $(trim_hx $hdr_rootfs_offs_val | swap_hx) $hdr_rootfs_offs_offs
write_hdr $(trim_hx $hdr_rootfs_len_val | swap_hx) $hdr_rootfs_len_offs
write_hdr $(trim_hx $hdr_rootfs_chksum_val) $hdr_rootfs_chksum_offs
# Write header checksum
hdr_head_chksum_val=$(chksum $FILE_TMP)
write_hdr $hdr_head_chksum_val $hdr_head_chksum_offs
# Place Sercomm signature
write_hdr $(trim_hx $hdr_sign_val) $hdr_sign_offs
dd if=$KERNEL_IMG >> $FILE_TMP
mv $FILE_TMP $KERNEL_IMG

View File

@ -0,0 +1,189 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "mt7621.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
compatible = "beeline,smartbox-turbo-plus", "mediatek,mt7621-soc";
model = "Beeline SmartBox TURBO+";
aliases {
led-boot = &led_status_green;
led-failsafe = &led_status_red;
led-running = &led_status_green;
led-upgrade = &led_status_red;
label-mac-device = &ethernet;
};
leds {
compatible = "gpio-leds";
led_status_blue: status_blue {
label = "blue:status";
gpios = <&gpio 13 GPIO_ACTIVE_HIGH>;
};
led_status_green: status_green {
label = "green:status";
gpios = <&gpio 15 GPIO_ACTIVE_HIGH>;
};
led_status_red: status_red {
label = "red:status";
gpios = <&gpio 16 GPIO_ACTIVE_HIGH>;
};
};
keys {
compatible = "gpio-keys";
wps {
label = "wps";
gpios = <&gpio 11 GPIO_ACTIVE_LOW>;
linux,code = <KEY_WPS_BUTTON>;
};
reset {
label = "reset";
gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
linux,code = <KEY_RESTART>;
};
};
ubi-concat {
compatible = "mtd-concat";
devices = <&ubiconcat0 &ubiconcat1 &ubiconcat2>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "ubi";
reg = <0x0 0x4f80000>;
};
};
};
};
&nand {
status = "okay";
partitions {
compatible = "sercomm,sc-partitions", "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "u-boot";
reg = <0x0 0x100000>;
scpart-id = <0>;
read-only;
};
partition@100000 {
label = "part_map";
reg = <0x100000 0x100000>;
scpart-id = <1>;
read-only;
};
factory: partition@200000 {
label = "factory";
reg = <0x200000 0x100000>;
scpart-id = <2>;
read-only;
};
partition@300000 {
label = "dual-flag";
reg = <0x300000 0x100000>;
scpart-id = <3>;
};
partition@400000 {
label = "kernel";
reg = <0x400000 0x600000>;
scpart-id = <4>;
};
partition@a00000 {
label = "uImage2";
reg = <0xa00000 0x600000>;
scpart-id = <5>;
read-only;
};
ubiconcat0: partition@1000000 {
label = "ubiconcat0";
reg = <0x1000000 0x2000000>;
scpart-id = <6>;
};
partition@3000000 {
label = "rootfs2";
reg = <0x3000000 0x2000000>;
scpart-id = <7>;
read-only;
};
ubiconcat1: partition@5000000 {
label = "ubiconcat1";
reg = <0x5000000 0x1400000>;
scpart-id = <8>;
};
ubiconcat2: partition@6400000 {
label = "ubiconcat2";
reg = <0x6400000 0x1b80000>;
scpart-id = <9>;
};
};
};
&pcie {
status = "okay";
};
&pcie0 {
wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x8000>;
ieee80211-freq-limit = <5000000 6000000>;
};
};
&pcie1 {
wifi@0,0 {
compatible = "mediatek,mt76";
reg = <0x0000 0 0 0 0>;
mediatek,mtd-eeprom = <&factory 0x0>;
ieee80211-freq-limit = <2400000 2500000>;
};
};
&ethernet {
compatible = "mediatek,ralink-mt7621-eth";
mediatek,switch = <&gsw>;
mtd-mac-address = <&factory 0x21000>;
};
&switch0 {
/delete-property/ compatible;
phy-mode = "rgmii";
};
&gsw {
compatible = "mediatek,ralink-mt7621-gsw";
};
&state_default {
gpio {
groups = "jtag", "uart2";
function = "gpio";
};
};

View File

@ -0,0 +1,243 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/*
* Sercomm/Netgear FLASH partition table.
*/
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/module.h>
#define MOD_NAME "scpart"
static const char sc_part_magic[] = {
'S', 'C', 'F', 'L', 'M', 'A', 'P', 'O', 'K', '\0',
};
#define PART_MAGIC_LEN sizeof(sc_part_magic)
/* assumes that all fields are set by CPU native endian */
struct sc_part_desc {
uint32_t part_id;
uint32_t part_offs;
uint32_t part_bytes;
};
#define ID_ALREADY_FOUND (0xFFFFFFFFUL)
#define MAP_OFFS_IN_BLK (0x800)
#define MAP_MIRROR_NUM (2)
static int scpart_desc_is_valid(struct sc_part_desc *pdesc)
{
return !!((pdesc->part_id != 0xFFFFFFFFUL) &&
(pdesc->part_offs != 0xFFFFFFFFUL) &&
(pdesc->part_bytes != 0xFFFFFFFFUL));
}
static int scpart_scan_partmap(struct mtd_info *master, loff_t partmap_offs,
struct sc_part_desc **ppdesc)
{
uint8_t *buf;
loff_t offs;
size_t retlen;
struct sc_part_desc *pdesc = NULL;
struct sc_part_desc *tmpdesc;
int cnt = 0;
int res2;
int res = 0;
buf = kzalloc(master->erasesize, GFP_KERNEL);
if (!buf) {
res = -ENOMEM;
goto out;
}
res2 = mtd_read(master, partmap_offs, master->erasesize, &retlen, buf);
if (res2 || (retlen != master->erasesize)) {
res = -EIO;
goto free;
}
offs = MAP_OFFS_IN_BLK;
while ((offs + sizeof(*tmpdesc)) < master->erasesize) {
tmpdesc = (struct sc_part_desc *)&(buf[offs]);
if (!scpart_desc_is_valid(tmpdesc))
break;
cnt++;
offs += sizeof(*tmpdesc);
}
if (cnt > 0) {
int bytes = cnt * sizeof(*pdesc);
pdesc = kzalloc(bytes, GFP_KERNEL);
if (!pdesc) {
res = -ENOMEM;
goto free;
}
memcpy(pdesc, &(buf[MAP_OFFS_IN_BLK]), bytes);
*ppdesc = pdesc;
res = cnt;
}
free:
kfree(buf);
out:
return res;
}
static int scpart_find_partmap(struct mtd_info *master,
struct sc_part_desc **ppdesc)
{
loff_t offs;
uint8_t rdbuf[PART_MAGIC_LEN];
size_t retlen;
int magic_found = 0;
int res2;
int res = 0;
offs = 0;
while ((magic_found < MAP_MIRROR_NUM) &&
(offs < master->size) && !mtd_block_isbad(master, offs)) {
res2 = mtd_read(master, offs, PART_MAGIC_LEN, &retlen, rdbuf);
if (res2 || (retlen != PART_MAGIC_LEN)) {
res = -EIO;
goto out;
}
if (!memcmp(rdbuf, sc_part_magic, PART_MAGIC_LEN)) {
pr_debug("%s: signature found at 0x%llx\n", MOD_NAME, offs);
magic_found++;
res = scpart_scan_partmap(master, offs, ppdesc);
if (res > 0)
goto out;
}
offs += master->erasesize;
}
out:
if (res > 0)
pr_info("%s: valid 'SC PART MAP' found (%d partitions)\n", MOD_NAME, res);
else
pr_info("%s: no valid 'SC PART MAP'\n", MOD_NAME);
return res;
}
static int scpart_parse(struct mtd_info *master,
const struct mtd_partition **pparts,
struct mtd_part_parser_data *data)
{
struct sc_part_desc *scpart_map = NULL;
struct mtd_partition *parts = NULL;
struct device_node *mtd_node;
struct device_node *ofpart_node;
struct device_node *pp;
const char *partname;
int nr_scparts;
int nr_parts = 0;
int n;
int res = 0;
mtd_node = mtd_get_of_node(master);
if (!mtd_node)
goto out;
ofpart_node = of_get_child_by_name(mtd_node, "partitions");
if (!ofpart_node)
goto out;
nr_scparts = scpart_find_partmap(master, &scpart_map);
if (nr_scparts <= 0) {
res = nr_scparts;
goto free;
}
for_each_child_of_node(ofpart_node, pp) {
u32 scpart_id;
struct mtd_partition *parts_tmp;
if (of_property_read_u32(pp, "scpart-id", &scpart_id))
continue;
for (n = 0 ; n < nr_scparts ; n++)
if ((scpart_map[n].part_id != ID_ALREADY_FOUND) &&
(scpart_id == scpart_map[n].part_id))
break;
if (n >= nr_scparts)
/* not match */
continue;
/* add the partition found in OF into MTD partition array */
/* reallocate partition array */
parts_tmp = parts;
parts = kzalloc((nr_parts + 1) * sizeof(*parts), GFP_KERNEL);
if (!parts) {
kfree(parts_tmp);
res = -ENOMEM;
goto free;
}
if (parts_tmp) {
memcpy(parts, parts_tmp, nr_parts * sizeof(*parts));
kfree(parts_tmp);
}
parts[nr_parts].offset = scpart_map[n].part_offs;
parts[nr_parts].size = scpart_map[n].part_bytes;
parts[nr_parts].of_node = pp;
if (!of_property_read_string(pp, "label", &partname) ||
!of_property_read_string(pp, "name", &partname))
parts[nr_parts].name = partname;
if (of_property_read_bool(pp, "read-only"))
parts[nr_parts].mask_flags |= MTD_WRITEABLE;
if (of_property_read_bool(pp, "lock"))
parts[nr_parts].mask_flags |= MTD_POWERUP_LOCK;
/* mark as 'done' */
scpart_map[n].part_id = ID_ALREADY_FOUND;
nr_parts++;
}
if (nr_parts > 0) {
*pparts = parts;
res = nr_parts;
} else
pr_info("%s: No partition in OF matches partition ID with 'SC PART MAP'.\n",
MOD_NAME);
of_node_put(pp);
free:
kfree(scpart_map);
if (res <= 0)
kfree(parts);
out:
return res;
}
static const struct of_device_id scpart_parser_of_match_table[] = {
{ .compatible = "sercomm,sc-partitions" },
{},
};
MODULE_DEVICE_TABLE(of, scpart_parser_of_match_table);
static struct mtd_part_parser scpart_parser = {
.parse_fn = scpart_parse,
.name = "scpart",
.of_match_table = scpart_parser_of_match_table,
};
module_mtd_part_parser(scpart_parser);
/* mtd parsers will request the module by parser name */
MODULE_ALIAS("scpart");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("NOGUCHI Hiroshi <drvlabo@gmail.com>");
MODULE_DESCRIPTION("Parsing code for Sercomm/Netgear partition table");

View File

@ -5,12 +5,13 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
DEVICE_VARS += LOADER_TYPE LOADER_FLASH_OFFS
DEVICE_VARS += LOADER_TYPE LOADER_FLASH_OFFS LZMA_TEXT_START
DEVICE_VARS += NETGEAR_BOARD_ID NETGEAR_HW_ID
DEVICE_VARS += BUFFALO_TAG_PLATFORM BUFFALO_TAG_VERSION BUFFALO_TAG_MINOR
DEVICE_VARS += SEAMA_SIGNATURE SEAMA_MTDBLOCK
DEVICE_VARS += SERCOMM_HWNAME SERCOMM_HWID SERCOMM_HWVER SERCOMM_SWVER
DEVICE_VARS += SERCOMM_PAD JCG_MAXSIZE
DEVICE_VARS += SERCOMM_KERNEL_OFFSET SERCOMM_ROOTFS_OFFSET
loadaddr-y := 0x80000000
loadaddr-$(CONFIG_TARGET_ramips_rt288x) := 0x88000000
@ -22,7 +23,7 @@ ldrplatform-$(CONFIG_TARGET_ramips_mt7621) := mt7621
ldrflashstart-y := 0x1c000000
ldrflashstart-$(CONFIG_TARGET_ramips_mt7621) := 0x1fc00000
KERNEL_LOADADDR := $(loadaddr-y)
LOADADDR := $(loadaddr-y)
LOADER_PLATFORM := $(ldrplatform-y)
LOADER_FLASH_START := $(ldrflashstart-y)
@ -46,7 +47,8 @@ define Build/loader-common
PKG_BUILD_DIR="$@.src" \
TARGET_DIR="$(dir $@)" LOADER_NAME="$(notdir $@)" \
BOARD="$(BOARDNAME)" PLATFORM="$(LOADER_PLATFORM)" \
LZMA_TEXT_START=0x81800000 LOADADDR=$(KERNEL_LOADADDR) \
LZMA_TEXT_START=$(LZMA_TEXT_START) \
LOADADDR=$(LOADADDR) \
$(1) compile loader.$(LOADER_TYPE)
mv "$@.$(LOADER_TYPE)" "$@"
rm -rf $@.src
@ -117,6 +119,12 @@ define Build/sercom-footer
$(call Build/sercom-seal,-f)
endef
define Build/sercomm-kernel
$(TOPDIR)/scripts/sercomm-kernel.sh $@ \
$(SERCOMM_KERNEL_OFFSET) \
$(SERCOMM_ROOTFS_OFFSET)
endef
define Build/sercom-seal
$(STAGING_DIR_HOST)/bin/mksercommfw \
-i $@ \
@ -159,6 +167,8 @@ endef
define Device/Default
PROFILES = Default
KERNEL_LOADADDR := $(loadaddr-y)
LZMA_TEXT_START := 0x81800000
KERNEL := $(KERNEL_DTB) | uImage lzma
SOC := $(DEFAULT_SOC)
DEVICE_DTS_DIR := ../dts

View File

@ -59,6 +59,31 @@ define Build/iodata-mstc-header
)
endef
define Build/sercomm-tag-factory
$(eval magic_const=$(word 1,$(1)))
dd if=/dev/zero count=$$((0x200)) bs=1 of=$@.head 2>/dev/null
dd if=/dev/zero count=$$((0x70)) bs=1 2>/dev/null | tr '\000' '0' | \
dd of=$@.head conv=notrunc 2>/dev/null
printf $(SERCOMM_HWVER) | dd of=$@.head bs=1 conv=notrunc 2>/dev/null
printf $(SERCOMM_HWID) | dd of=$@.head bs=1 seek=$$((0x8)) conv=notrunc 2>/dev/null
printf $(SERCOMM_SWVER) | dd of=$@.head bs=1 seek=$$((0x64)) conv=notrunc \
2>/dev/null
dd if=$(IMAGE_KERNEL) skip=$$((0x100)) iflag=skip_bytes 2>/dev/null of=$@.clrkrn
dd if=$(IMAGE_KERNEL) count=$$((0x100)) iflag=count_bytes 2>/dev/null of=$@.hdrkrn0
dd if=/dev/zero count=$$((0x100)) iflag=count_bytes 2>/dev/null of=$@.hdrkrn1
wc -c < $@.clrkrn | tr -d '\n' | dd of=$@.head bs=1 seek=$$((0x70)) \
conv=notrunc 2>/dev/null
stat -c%s $@ | tr -d '\n' | dd of=$@.head bs=1 seek=$$((0x80)) \
conv=notrunc 2>/dev/null
printf $(magic_const) | dd of=$@.head bs=1 seek=$$((0x90)) conv=notrunc 2>/dev/null
cat $@.clrkrn $@ | md5sum | awk '{print $$1;}' | tr -d '\n' | dd of=$@.head bs=1 \
seek=$$((0x1e0)) conv=notrunc 2>/dev/null
cat $@.head $@.hdrkrn0 $@.hdrkrn1 $@.clrkrn $@ > $@.new
mv $@.new $@
rm $@.head $@.clrkrn
endef
define Build/ubnt-erx-factory-image
if [ -e $(KDIR)/tmp/$(KERNEL_INITRAMFS_IMAGE) -a "$$(stat -c%s $@)" -lt "$(KERNEL_SIZE)" ]; then \
echo '21001:7' > $(1).compat; \
@ -226,6 +251,35 @@ define Device/asus_rt-n56u-b1
endef
TARGET_DEVICES += asus_rt-n56u-b1
define Device/beeline_smartbox-turbo-plus
$(Device/dsa-migration)
BLOCKSIZE := 128k
PAGESIZE := 2048
UBINIZE_OPTS := -E 5
KERNEL_SIZE := 6144k
IMAGE_SIZE := 32768k
KERNEL_LOADADDR := 0x81001000
LZMA_TEXT_START := 0x82800000
SERCOMM_KERNEL_OFFSET := 0x400100
SERCOMM_ROOTFS_OFFSET := 0x1000000
KERNEL := kernel-bin | append-dtb | lzma | loader-kernel | \
lzma | uImage lzma | sercomm-kernel
KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel | \
lzma | uImage lzma
LOADER_TYPE := bin
IMAGES += factory.img
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
SERCOMM_HWID := 435152
SERCOMM_HWVER := 0001
SERCOMM_SWVER := 9999
IMAGE/factory.img := append-ubi | sercomm-tag-factory
DEVICE_VENDOR := Beeline
DEVICE_MODEL := SmartBox TURBO+
DEVICE_PACKAGES := kmod-mt7603e kmod-mt7615d luci-app-mtwifi \
-wpad-openssl kmod-usb3 uboot-envtools
endef
TARGET_DEVICES += beeline_smartbox-turbo-plus
define Device/buffalo_wsr-1166dhp
$(Device/dsa-migration)
$(Device/uimage-lzma-loader)

View File

@ -42,6 +42,11 @@ ramips_setup_interfaces()
xiaomi,mi-router-4a-gigabit)
ucidef_set_interfaces_lan_wan "lan1 lan2" "wan"
;;
beeline,smartbox-turbo-plus)
ucidef_add_switch "switch0" \
"1:lan:1" "2:lan:2" "3:lan:3" "4:lan:4" "0:wan" "6@eth0"
ucidef_set_interface_lan "eth0.1 ra0 rai0"
;;
d-team,newifi-d2|\
raisecom,msg1500-x-00)
ucidef_add_switch "switch0" \
@ -122,6 +127,9 @@ ramips_setup_macs()
wan_mac=$(mtd_get_mac_ascii u-boot-env et1macaddr)
label_mac=$(mtd_get_mac_binary factory 0x4)
;;
beeline,smartbox-turbo-plus)
wan_mac=$(macaddr_add "$(mtd_get_mac_binary factory 0x21000)" 1)
;;
buffalo,wsr-1166dhp)
local index="$(find_mtd_index "board_data")"
wan_mac="$(grep -m1 mac= "/dev/mtd${index}" | cut -d= -f2)"

View File

@ -8,6 +8,11 @@ boot() {
[ -n "$(fw_printenv bootcount bootchanged 2>/dev/null)" ] &&\
echo -e "bootcount\nbootchanged\n" | /usr/sbin/fw_setenv -s -
;;
beeline,smartbox-turbo-plus)
[[ $(hexdump -n 1 -e '/1 "%1d"' -s $((0x20001)) /dev/mtd3) == \
$((0xFF)) ]] || printf '\xff' | dd of=/dev/mtdblock3 count=1 \
bs=1 seek=$((0x20001))
;;
linksys,e5600|\
linksys,ea7300-v1|\
linksys,ea7300-v2|\

View File

@ -53,6 +53,8 @@ platform_do_upgrade() {
ampedwireless,ally-r1900k|\
asus,rt-ac65p|\
asus,rt-ac85p|\
beeline,smartbox-giga|\
beeline,smartbox-turbo-plus|\
dlink,dir-1960-a1|\
dlink,dir-2640-a1|\
dlink,dir-2660-a1|\

View File

@ -159,6 +159,7 @@ CONFIG_MTD_NAND_MT7621=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_ROUTERBOOT_PARTS=y
CONFIG_MTD_SERCOMM_PARTS=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_FIT_FW=y
CONFIG_MTD_SPLIT_MINOR_FW=y

View File

@ -0,0 +1,19 @@
--- a/drivers/mtd/parsers/Kconfig
+++ b/drivers/mtd/parsers/Kconfig
@@ -185,3 +185,9 @@ config MTD_ROUTERBOOT_PARTS
flash, some of which are fixed and some of which are located at
variable offsets. This parser handles both cases via properly
formatted DTS.
+
+config MTD_SERCOMM_PARTS
+ tristate "SERCOMM partitioning information support"
+ depends on MTD_OF_PARTS
+ help
+ This provides partition table parser for SERCOMM partition map
--- a/drivers/mtd/parsers/Makefile
+++ b/drivers/mtd/parsers/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_MTD_PARSER_TRX) += parser_
obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o
obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o
+obj-$(CONFIG_MTD_SERCOMM_PARTS) += scpart.o