Skip to content

Commit

Permalink
scripts: sync with upstream
Browse files Browse the repository at this point in the history
  • Loading branch information
coolsnowwolf committed Oct 19, 2022
1 parent 80b72c1 commit 66d86d2
Show file tree
Hide file tree
Showing 71 changed files with 4,689 additions and 4,726 deletions.
10 changes: 9 additions & 1 deletion Config.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@
mainmenu "OpenWrt Configuration"

config MODULES
option modules
modules
bool
default y

config HAVE_DOT_CONFIG
bool
default y

HOST_OS := $(shell, uname)

config HOST_OS_LINUX
def_bool $(shell, ./config/check-uname.sh Linux)

config HOST_OS_MACOS
def_bool $(shell, ./config/check-uname.sh Darwin)

source "target/Config.in"

source "config/Config-images.in"
Expand Down
21 changes: 15 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ $(if $(findstring $(space),$(TOPDIR)),$(error ERROR: The path to the OpenWrt dir

world:

DISTRO_PKG_CONFIG:=$(shell which -a pkg-config | grep '/usr' -m 1)
DISTRO_PKG_CONFIG:=$(shell $(TOPDIR)/scripts/command_all.sh pkg-config | grep '/usr' -m 1)
export PATH:=$(TOPDIR)/staging_dir/host/bin:$(PATH)

ifneq ($(OPENWRT_BUILD),1)
Expand All @@ -38,7 +38,7 @@ else
include tools/Makefile
include toolchain/Makefile

$(toolchain/stamp-compile): $(tools/stamp-compile)
$(toolchain/stamp-compile): $(tools/stamp-compile) $(if $(CONFIG_BUILDBOT),toolchain_rebuild_check)
$(target/stamp-compile): $(toolchain/stamp-compile) $(tools/stamp-compile) $(BUILD_DIR)/.prepared
$(package/stamp-compile): $(target/stamp-compile) $(package/stamp-cleanup)
$(package/stamp-install): $(package/stamp-compile)
Expand All @@ -50,14 +50,23 @@ printdb:

prepare: $(target/stamp-compile)

clean: FORCE
rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(BUILD_LOG_DIR) $(TOPDIR)/staging_dir/packages
_clean: FORCE
rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(TOPDIR)/staging_dir/packages

dirclean: clean
rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/host $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN)
clean: _clean
rm -rf $(BUILD_LOG_DIR)

targetclean: _clean
rm -rf $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN)

dirclean: targetclean clean
rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(BUILD_DIR_BASE)/host
rm -rf $(TMP_DIR)
$(MAKE) -C $(TOPDIR)/scripts/config clean

toolchain_rebuild_check:
$(SCRIPT_DIR)/check-toolchain-clean.sh

cacheclean:
ifneq ($(CONFIG_CCACHE),)
$(STAGING_DIR_HOST)/bin/ccache -C
Expand Down
1 change: 1 addition & 0 deletions config/check-uname.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ "$(uname)" = "$1" ] && echo y || echo n
27 changes: 6 additions & 21 deletions rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ ARCH_PACKAGES:=$(call qstrip,$(CONFIG_TARGET_ARCH_PACKAGES))
BOARD:=$(call qstrip,$(CONFIG_TARGET_BOARD))
SUBTARGET:=$(call qstrip,$(CONFIG_TARGET_SUBTARGET))
TARGET_OPTIMIZATION:=$(call qstrip,$(CONFIG_TARGET_OPTIMIZATION))
export EXTRA_OPTIMIZATION:=$(filter-out -fno-plt,$(call qstrip,$(CONFIG_EXTRA_OPTIMIZATION)))
TARGET_SUFFIX=$(call qstrip,$(CONFIG_TARGET_SUFFIX))
BUILD_SUFFIX:=$(call qstrip,$(CONFIG_BUILD_SUFFIX))
SUBDIR:=$(patsubst $(TOPDIR)/%,%,${CURDIR})
Expand Down Expand Up @@ -110,7 +109,7 @@ $(foreach t,$(DEFAULT_SUBDIR_TARGETS) $(1),
)
endef

DL_DIR:=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl)
DL_DIR=$(if $(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(call qstrip,$(CONFIG_DOWNLOAD_FOLDER)),$(TOPDIR)/dl)$(if $(DL_SUBDIR),/$(DL_SUBDIR))
OUTPUT_DIR:=$(if $(call qstrip,$(CONFIG_BINARY_FOLDER)),$(call qstrip,$(CONFIG_BINARY_FOLDER)),$(TOPDIR)/bin)
BIN_DIR:=$(OUTPUT_DIR)/targets/$(BOARD)/$(SUBTARGET)
INCLUDE_DIR:=$(TOPDIR)/include
Expand Down Expand Up @@ -138,11 +137,7 @@ else
endif

ifeq ($(or $(CONFIG_EXTERNAL_TOOLCHAIN),$(CONFIG_TARGET_uml)),)
ifeq ($(CONFIG_GCC_USE_IREMAP),y)
iremap = -iremap$(1):$(2)
else
iremap = -f$(if $(CONFIG_REPRODUCIBLE_DEBUG_INFO),file,macro)-prefix-map=$(1)=$(2)
endif
iremap = -f$(if $(CONFIG_REPRODUCIBLE_DEBUG_INFO),file,macro)-prefix-map=$(1)=$(2)
endif

PACKAGE_DIR:=$(BIN_DIR)/packages
Expand Down Expand Up @@ -213,7 +208,6 @@ ifndef DUMP
ifneq ($(TOOLCHAIN_LIB_DIRS),)
TARGET_LDFLAGS+= $(patsubst %,-L%,$(TOOLCHAIN_LIB_DIRS))
endif
TARGET_PATH:=$(TOOLCHAIN_DIR)/bin:$(TARGET_PATH)
endif
endif
endif
Expand Down Expand Up @@ -244,23 +238,17 @@ export PKG_CONFIG
HOSTCC:=gcc
HOSTCXX:=g++
HOST_CPPFLAGS:=-I$(STAGING_DIR_HOST)/include $(if $(IS_PACKAGE_BUILD),-I$(STAGING_DIR_HOSTPKG)/include -I$(STAGING_DIR)/host/include)
HOST_CXXFLAGS:=
HOST_CFLAGS:=-O2 $(HOST_CPPFLAGS)
HOST_LDFLAGS:=-L$(STAGING_DIR_HOST)/lib $(if $(IS_PACKAGE_BUILD),-L$(STAGING_DIR_HOSTPKG)/lib -L$(STAGING_DIR)/host/lib)

ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),)
TARGET_AR:=$(TARGET_CROSS)gcc-ar
TARGET_RANLIB:=$(TARGET_CROSS)gcc-ranlib
TARGET_NM:=$(TARGET_CROSS)gcc-nm
else
TARGET_AR:=$(TARGET_CROSS)ar
TARGET_RANLIB:=$(TARGET_CROSS)ranlib
TARGET_NM:=$(TARGET_CROSS)nm
endif

BUILD_KEY=$(TOPDIR)/key-build

FAKEROOT:=$(STAGING_DIR_HOST)/bin/fakeroot

TARGET_AR:=$(TARGET_CROSS)gcc-ar
TARGET_RANLIB:=$(TARGET_CROSS)gcc-ranlib
TARGET_NM:=$(TARGET_CROSS)gcc-nm
TARGET_CC:=$(TARGET_CROSS)gcc
TARGET_CXX:=$(TARGET_CROSS)g++
KPATCH:=$(SCRIPT_DIR)/patch-kernel.sh
Expand All @@ -269,9 +257,6 @@ ESED:=$(STAGING_DIR_HOST)/bin/sed -E -i -e
MKHASH:=$(STAGING_DIR_HOST)/bin/mkhash
# MKHASH is used in /scripts, so we export it here.
export MKHASH
# DOWNLOAD_CHECK_CERTIFICATE is used in /scripts, so we export it here.
DOWNLOAD_CHECK_CERTIFICATE:=$(CONFIG_DOWNLOAD_CHECK_CERTIFICATE)
export DOWNLOAD_CHECK_CERTIFICATE
CP:=cp -fpR
LN:=ln -sf
XARGS:=xargs -r
Expand Down
86 changes: 86 additions & 0 deletions scripts/cameo-imghdr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022 Luiz Angelo Daros de Luca <[email protected]>
#
# Cameo Image header geneator, used by some D-Link DGS-1210 switches
# and APRESIA ApresiaLightGS series
#
import argparse
import pathlib
import socket
import struct

MODEL_LEN = 20
SIGNATURE_LEN = 16
LINUXLOAD_LEN = 10
BUFSIZE = 4096

parser = argparse.ArgumentParser(description='Generate Cameo firmware header.')
parser.add_argument('source_file', type=argparse.FileType('rb'))
parser.add_argument('dest_file', type=argparse.FileType('wb'))
parser.add_argument('model')
parser.add_argument('signature')
parser.add_argument('partition', type=int, choices=range(0,10),
metavar="partition=[0-9]",help="partition id")
parser.add_argument('customer_signature', type=int, choices=range(0,10),
metavar="customer_signature=[0-9]",
help="customer signature")
parser.add_argument('board_version', type=int, choices=range(0,2**32),
metavar="board_version=[0-4294967295]",
help="board version")
parser.add_argument('linux_loadaddr', nargs='?',
help="Kernel start address in 0xFFFFFFFF format")
args = parser.parse_args()

if len(args.model) > MODEL_LEN:
raise ValueError(f"Model '{args.model}' is greater than {MODEL_LEN} bytes")

if len(args.signature) > SIGNATURE_LEN:
raise ValueError(f"Signature '{args.signature}' is greater than"
f"{SIGNATURE_LEN} bytes")

if args.signature == "os":
if args.linux_loadaddr:
if len(args.linux_loadaddr) > LINUXLOAD_LEN:
raise ValueError(f"linux_loadaddr '{args.linux_loadaddr}' is greater"
f"than {LINUXLOAD_LEN} bytes")
if (args.linux_loadaddr[0:2] != "0x"):
raise ValueError(f"linux_loadaddr '{args.linux_loadaddr}' must use"
f"the 0x789ABCDE format")
int(args.linux_loadaddr[2:],16)
else:
raise ValueError(f"linux_loadaddr is required for signature 'os'")
else:
args.linux_loadaddr = ""

checksum = 0
size = 0
while True:
buf = args.source_file.read(BUFSIZE)
if not buf:
break
checksum = sum(iter(buf),checksum) % (1<<32)
size += len(buf)

args.dest_file.write(struct.pack('!I', checksum))
args.dest_file.write(struct.pack(f'{MODEL_LEN}s',
args.model.encode("ascii")))
args.dest_file.write(struct.pack(f'{SIGNATURE_LEN}s',
args.signature.encode("ascii")))
args.dest_file.write(struct.pack('!B', args.partition))
args.dest_file.write(struct.pack('!B', 0x40)) # ??? This header size?
args.dest_file.write(struct.pack('!B', 0x00)) # ??? Encrypted?
args.dest_file.write(struct.pack('!B', args.customer_signature))
args.dest_file.write(struct.pack('!I', args.board_version))
args.dest_file.write(struct.pack('!I', size))
args.dest_file.write(struct.pack(f'{LINUXLOAD_LEN}s',
args.linux_loadaddr.encode("ascii")))
args.dest_file.write(struct.pack('!2x'))

args.source_file.seek(0)
while True:
buf = args.source_file.read(BUFSIZE)
if not buf:
break
args.dest_file.write(buf)
117 changes: 117 additions & 0 deletions scripts/cameo-tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/python3
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2022 OpenWrt.org
#
# ./cameo-tag.py <uImageFileName> <OffsetOfRootFS>
#
# CAMEO tag generator used for the D-Link DGS-1210 switches. Their U-Boot
# loader checks for the string CAMEOTAG and a checksum in the kernel and
# rootfs partitions. If not found it complains about the boot image.
# Nevertheless it will boot if the tags are available in the secondary
# boot partitions. If some day we want to overwrite the original vendor
# partition we must have the tags in place. To solve this we insert the
# tag two times into the kernel image.
#
# To understand what we do here it is helpful to explain how the original
# CAMEO tag generation/checking works. The firmware consists of two parts.
# A kernel uImage (<1.5MB) and a rootfs image (<12MB) that are written to
# their respective mtd partitions. The default generator simply checksums
# both parts and appends 16 bytes [<CAMEOTAG><0001><checksum>] to each part.
# The checksum is only an addition of all preceding bytes (b0+b1+b2+...).
# A tag does not interfere with any data in the images itself. During boot
# the loader will scan all primary/secondary partitions (2*kernel, 2*rootfs)
# until it finds the CAMEO tag. If checksums match everything is fine.
# If all 4 fail we are lost. Luckily the loader does not care about where
# the tags are located and ignores any data beyond a tag.
#
# The OpenWrt image consists of a kernel (>1.5MB) and a rootfs. There is
# no chance to add CAMEO tags at the default locations, since the kernel spans
# both the original kernel partition and the start of the rootfs partition.
# This would leave the kernel partition without a tag. So we must find suitable
# space.
#
# Location for original kernel partition is at the end of the uImage header.
# We will reuse the last bytes of the IH_NAME field. This is the tricky part
# because we have the header CRC and the CAMEO checksum that must match the
# whole header. uImage header CRC checksums all data except the CRC itself. The
# for CAMEO checksum in turn, checksums all preceding data except itself.
# Changing one of both results in a change of the other, but data trailing the
# CAMEO checksum only influences the CRC.
#
# Location for original rootfs partition is very simple. It is behind the
# OpenWrt compressed kernel image file that spans into the rootfs. So
# the tag will be written somewhere to the following rootfs partition and
# can be found by U-Boot. The CAMEO checksum calculation must start at the
# offset of the original rootfs partition and includes the "second" half of the
# "split" kernel uImage.

import argparse
import os
import zlib

READ_UNTIL_EOF = -1
UIMAGE_HEADER_SIZE = 64
UIMAGE_CRC_OFF = 4
UIMAGE_CRC_END = 8
UIMAGE_NAME_OFF = 32
UIMAGE_NAME_END = 56
UIMAGE_SUM_OFF = 56
UIMAGE_SUM_END = 60
UIMAGE_INV_OFF = 60
UIMAGE_INV_END = 64
CAMEO_TAG = bytes([0x43, 0x41, 0x4d, 0x45, 0x4f, 0x54, 0x41, 0x47, 0x00, 0x00, 0x00, 0x01])
IMAGE_NAME = bytes([0x4f, 0x70, 0x65, 0x6e, 0x57, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00])
CRC_00 = bytes([0x00] * 4)
CRC_FF = bytes([0xff] * 4)

def read_buffer(offset, count):
args.uimage_file.seek(offset)
return bytearray(args.uimage_file.read(count))

def write_buffer(whence, buf):
args.uimage_file.seek(0, whence)
args.uimage_file.write(buf)

def cameosum(buf):
return (sum(buf) & 0xffffffff).to_bytes(4, 'big')

def invertcrc(buf):
return (zlib.crc32(buf) ^ 0xffffffff).to_bytes(4, 'little')

def checksum_header(buf):
# To efficently get a combination, we will make use of the following fact:
# crc32(data + littleendian(crc32(data) ^ 0xffffffff)) = 0xffffffff
#
# After manipulation the uImage header looks like this:
# [...<ffffffff>...<OpenWrt><000000><CAMEOTAG><0001><checksum><InvCRC>]
buf[UIMAGE_NAME_OFF:UIMAGE_NAME_END] = IMAGE_NAME + CAMEO_TAG
buf[UIMAGE_CRC_OFF:UIMAGE_CRC_END] = CRC_FF
buf[UIMAGE_SUM_OFF:UIMAGE_SUM_END] = cameosum(buf[0:UIMAGE_NAME_END])
buf[UIMAGE_CRC_OFF:UIMAGE_CRC_END] = CRC_00
buf[UIMAGE_INV_OFF:UIMAGE_INV_END] = invertcrc(buf[0:UIMAGE_SUM_END])
buf[UIMAGE_CRC_OFF:UIMAGE_CRC_END] = CRC_FF
return buf

parser = argparse.ArgumentParser(description='Insert CAMEO firmware tags.')
parser.add_argument('uimage_file', type=argparse.FileType('r+b'))
parser.add_argument('rootfs_start', type=int)
args = parser.parse_args()

args.uimage_file.seek(0, os.SEEK_END)
if args.uimage_file.tell() <= args.rootfs_start:
raise ValueError(f"uImage must be larger than {args.rootfs_start} bytes")

# tag for the uImage Header of 64 bytes inside the kernel
# partition. Read and mangle it so it contains a valid CAMEO tag
# and checksum that matches perfectly to the uImage header CRC.

buf = checksum_header(read_buffer(0, UIMAGE_HEADER_SIZE))
write_buffer(os.SEEK_SET, buf)

# tag for the second part of the kernel that resides in the
# vendor rootfs partition. For this we will add the CAMEO tag
# and the checksum to the end of the image.

buf = read_buffer(args.rootfs_start, READ_UNTIL_EOF)
write_buffer(os.SEEK_END, CAMEO_TAG + cameosum(buf + CAMEO_TAG))
Loading

0 comments on commit 66d86d2

Please sign in to comment.