Initial commit
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled
This commit is contained in:
86
package/system/apk/Makefile
Normal file
86
package/system/apk/Makefile
Normal file
@@ -0,0 +1,86 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=apk
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL=https://gitlab.alpinelinux.org/alpine/apk-tools.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2024-05-23
|
||||
PKG_SOURCE_VERSION:=6052bfef57a81d82451b4cad86f78a2d01959767
|
||||
PKG_MIRROR_HASH:=bf14da82cc363ee32a956dd880343018361079018a48701dc2b05cb88c18010e
|
||||
|
||||
PKG_VERSION=3.0.0_pre$(subst -,,$(PKG_SOURCE_DATE))
|
||||
|
||||
PKG_MAINTAINER:=Paul Spooren <mail@aparcar.org>
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_INSTALL:=1
|
||||
|
||||
HOST_BUILD_PREFIX:=$(STAGING_DIR_HOST)
|
||||
HOST_BUILD_DEPENDS:=lua/host
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/meson.mk
|
||||
|
||||
define Package/apk/default
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=apk package manager
|
||||
DEPENDS:=+zlib
|
||||
URL:=$(PKG_SOURCE_URL)
|
||||
PROVIDES:=apk
|
||||
endef
|
||||
|
||||
define Package/apk-mbedtls
|
||||
$(Package/apk/default)
|
||||
TITLE += (mbedtls)
|
||||
DEPENDS +=+libmbedtls
|
||||
VARIANT:=mbedtls
|
||||
DEFAULT_VARIANT:=1
|
||||
CONFLICTS:=apk-openssl
|
||||
endef
|
||||
|
||||
define Package/apk-openssl
|
||||
$(Package/apk/default)
|
||||
TITLE += (openssl)
|
||||
DEPENDS +=+libopenssl
|
||||
VARIANT:=openssl
|
||||
endef
|
||||
|
||||
MESON_HOST_VARS+=VERSION=$(PKG_VERSION)
|
||||
MESON_VARS+=VERSION=$(PKG_VERSION)
|
||||
|
||||
MESON_HOST_ARGS += \
|
||||
-Dcompressed-help=false \
|
||||
-Ddocs=disabled \
|
||||
-Dcrypto_backend=openssl \
|
||||
-Dzstd=false
|
||||
|
||||
MESON_ARGS += \
|
||||
-Dlua_version=5.1 \
|
||||
-Dcompressed-help=false \
|
||||
-Ddocs=disabled \
|
||||
-Durl_backend=wget \
|
||||
-Dcrypto_backend=$(BUILD_VARIANT) \
|
||||
-Dzstd=false
|
||||
|
||||
HOST_LDFLAGS += \
|
||||
-Wl,-rpath $(STAGING_DIR_HOST)/lib
|
||||
|
||||
define Package/apk/default/install
|
||||
$(INSTALL_DIR) $(1)/lib/apk/db
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/apk $(1)/usr/bin/apk
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libapk.so.* $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
Package/apk-mbedtls/install = $(Package/apk/default/install)
|
||||
Package/apk-openssl/install = $(Package/apk/default/install)
|
||||
|
||||
$(eval $(call BuildPackage,apk-mbedtls))
|
||||
$(eval $(call BuildPackage,apk-openssl))
|
||||
$(eval $(call HostBuild))
|
||||
@@ -0,0 +1,21 @@
|
||||
From 9918c683fcc2f148328332d58d030ec5750a1473 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Spooren <mail@aparcar.org>
|
||||
Date: Sat, 19 Feb 2022 17:20:37 +0100
|
||||
Subject: [PATCH 1/4] openwrt: move layer db to temp folder
|
||||
|
||||
Signed-off-by: Paul Spooren <mail@aparcar.org>
|
||||
---
|
||||
src/database.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/database.c
|
||||
+++ b/src/database.c
|
||||
@@ -1643,7 +1643,7 @@ const char *apk_db_layer_name(int layer)
|
||||
{
|
||||
switch (layer) {
|
||||
case APK_DB_LAYER_ROOT: return "lib/apk/db";
|
||||
- case APK_DB_LAYER_UVOL: return "lib/apk/db-uvol";
|
||||
+ case APK_DB_LAYER_UVOL: return "tmp/run/uvol/.meta/apk";
|
||||
default:
|
||||
assert(!"invalid layer");
|
||||
return 0;
|
||||
70
package/system/ca-certificates/Makefile
Normal file
70
package/system/ca-certificates/Makefile
Normal file
@@ -0,0 +1,70 @@
|
||||
#
|
||||
# Copyright (C) 2006-2017 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ca-certificates
|
||||
PKG_VERSION:=20240203
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=
|
||||
|
||||
PKG_LICENSE:=GPL-2.0-or-later MPL-2.0
|
||||
PKG_LICENSE_FILES:=debian/copyright
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@DEBIAN/pool/main/c/ca-certificates
|
||||
PKG_HASH:=3286d3fc42c4d11b7086711a85f865b44065ce05cf1fb5376b2abed07622a9c6
|
||||
PKG_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
TAR_OPTIONS+= --strip-components 1
|
||||
TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS)
|
||||
|
||||
define Package/ca-certificates
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=System CA certificates
|
||||
PKGARCH:=all
|
||||
PROVIDES:=ca-certs
|
||||
endef
|
||||
|
||||
define Package/ca-bundle
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=System CA certificates as a bundle
|
||||
PKGARCH:=all
|
||||
PROVIDES:=ca-certs
|
||||
endef
|
||||
|
||||
define Build/Install
|
||||
mkdir -p \
|
||||
$(PKG_INSTALL_DIR)/usr/sbin \
|
||||
$(PKG_INSTALL_DIR)/usr/share/ca-certificates
|
||||
$(call Build/Install/Default,)
|
||||
endef
|
||||
|
||||
define Package/ca-certificates/install
|
||||
$(INSTALL_DIR) $(1)/etc/ssl/certs
|
||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/ca-certificates/*/*.crt $(1)/etc/ssl/certs/
|
||||
|
||||
for CERTFILE in `ls -1 $(1)/etc/ssl/certs`; do \
|
||||
HASH=`openssl x509 -hash -noout -in $(1)/etc/ssl/certs/$$$$CERTFILE` ; \
|
||||
SUFFIX=0 ; \
|
||||
while [ -h "$(1)/etc/ssl/certs/$$$$HASH.$$$$SUFFIX" ]; do \
|
||||
let "SUFFIX += 1" ; \
|
||||
done ; \
|
||||
$(LN) "$$$$CERTFILE" "$(1)/etc/ssl/certs/$$$$HASH.$$$$SUFFIX" ; \
|
||||
done
|
||||
endef
|
||||
|
||||
define Package/ca-bundle/install
|
||||
$(INSTALL_DIR) $(1)/etc/ssl/certs
|
||||
cat $(PKG_INSTALL_DIR)/usr/share/ca-certificates/*/*.crt >$(1)/etc/ssl/certs/ca-certificates.crt
|
||||
$(LN) /etc/ssl/certs/ca-certificates.crt $(1)/etc/ssl/cert.pem
|
||||
endef
|
||||
$(eval $(call BuildPackage,ca-bundle))
|
||||
$(eval $(call BuildPackage,ca-certificates))
|
||||
@@ -0,0 +1,53 @@
|
||||
From 3c51cb5ff1d0db41fb3288fb555c7e7055cf3e86 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Wed, 1 Dec 2021 14:41:31 +0100
|
||||
Subject: [PATCH] ca-certificates: fix python3-cryptography woes in
|
||||
certdata2pem.py
|
||||
|
||||
reverts the code portion of the Debian's ca-certificate
|
||||
commit 033d52259172 ("mozilla/certdata2pem.py: print a warning for expired certificates.")
|
||||
|
||||
It broke builds with the popular Ubuntu 20.04 (focal) releases.
|
||||
This was due to them shipping with an older python3-cryptography
|
||||
version which is not compatible.
|
||||
|
||||
More concerns were raised by jow- as well:
|
||||
"We don't want the build to depend on the local system time anyway."
|
||||
|
||||
Reported-by: Chen Minqiang <ptpt52@gmail.com>
|
||||
Reported-by: Shane Synan <digitalcircuit36939@gmail.com>
|
||||
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
---
|
||||
--- a/mozilla/certdata2pem.py
|
||||
+++ b/mozilla/certdata2pem.py
|
||||
@@ -21,16 +21,12 @@
|
||||
# USA.
|
||||
|
||||
import base64
|
||||
-import datetime
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
import textwrap
|
||||
import io
|
||||
|
||||
-from cryptography import x509
|
||||
-
|
||||
-
|
||||
objects = []
|
||||
|
||||
# Dirty file parser.
|
||||
@@ -121,13 +117,6 @@ for obj in objects:
|
||||
if obj['CKA_CLASS'] == 'CKO_CERTIFICATE':
|
||||
if not obj['CKA_LABEL'] in trust or not trust[obj['CKA_LABEL']]:
|
||||
continue
|
||||
-
|
||||
- cert = x509.load_der_x509_certificate(bytes(obj['CKA_VALUE']))
|
||||
- if cert.not_valid_after < datetime.datetime.utcnow():
|
||||
- print('!'*74)
|
||||
- print('Trusted but expired certificate found: %s' % obj['CKA_LABEL'])
|
||||
- print('!'*74)
|
||||
-
|
||||
bname = obj['CKA_LABEL'][1:-1].replace('/', '_')\
|
||||
.replace(' ', '_')\
|
||||
.replace('(', '=')\
|
||||
141
package/system/fstools/Makefile
Normal file
141
package/system/fstools/Makefile
Normal file
@@ -0,0 +1,141 @@
|
||||
#
|
||||
# Copyright (C) 2014-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=fstools
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/fstools.git
|
||||
PKG_MIRROR_HASH:=5f04ce2b346d9a48468180dd9601ca0fcc83896ebf5466855578e766646e14a1
|
||||
PKG_SOURCE_DATE:=2024-07-14
|
||||
PKG_SOURCE_VERSION:=408c2cc48e6694446c89da7f8121b399063e1067
|
||||
CMAKE_INSTALL:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_BUILD_FLAGS:=no-mips16
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
PKG_BUILD_DEPENDS := util-linux
|
||||
PKG_CONFIG_DEPENDS := CONFIG_NAND_SUPPORT CONFIG_FSTOOLS_UBIFS_EXTROOT
|
||||
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
CMAKE_OPTIONS += $(if $(CONFIG_FSTOOLS_UBIFS_EXTROOT),-DCMAKE_UBIFS_EXTROOT=y)
|
||||
CMAKE_OPTIONS += $(if $(CONFIG_FSTOOLS_OVL_MOUNT_FULL_ACCESS_TIME),-DCMAKE_OVL_MOUNT_FULL_ACCESS_TIME=y)
|
||||
CMAKE_OPTIONS += $(if $(CONFIG_FSTOOLS_OVL_MOUNT_COMPRESS_ZLIB),-DCMAKE_OVL_MOUNT_COMPRESS_ZLIB=y)
|
||||
|
||||
define Package/fstools
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+ubox +NAND_SUPPORT:ubi-utils
|
||||
TITLE:=OpenWrt filesystem tools
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define Package/fstools/config
|
||||
config FSTOOLS_UBIFS_EXTROOT
|
||||
depends on PACKAGE_fstools
|
||||
depends on NAND_SUPPORT
|
||||
bool "Support extroot functionality with UBIFS"
|
||||
default y
|
||||
help
|
||||
This option makes it possible to use extroot functionality if the root filesystem resides on an UBIFS partition
|
||||
|
||||
config FSTOOLS_OVL_MOUNT_FULL_ACCESS_TIME
|
||||
depends on PACKAGE_fstools
|
||||
bool "Full access time accounting"
|
||||
default n
|
||||
help
|
||||
This option enables the full access time accounting (warning: it will increase the flash writes).
|
||||
|
||||
config FSTOOLS_OVL_MOUNT_COMPRESS_ZLIB
|
||||
depends on PACKAGE_fstools
|
||||
bool "Compress using zlib"
|
||||
default n
|
||||
help
|
||||
This option enables the compression using zlib on the storage device.
|
||||
endef
|
||||
|
||||
define Package/snapshot-tool
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=rootfs snapshoting tool
|
||||
DEPENDS:=+libubox +fstools
|
||||
endef
|
||||
|
||||
define Package/block-mount/conffiles
|
||||
/etc/config/fstab
|
||||
endef
|
||||
|
||||
define Package/block-mount
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=Block device mounting and checking
|
||||
DEPENDS:=+ubox +libubox +libuci +libblobmsg-json +libjson-c
|
||||
endef
|
||||
|
||||
define Package/blockd
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=Block device automounting
|
||||
DEPENDS:=+block-mount +fstools +libubus +kmod-fs-autofs4 +libblobmsg-json +libjson-c
|
||||
endef
|
||||
|
||||
define Package/fstools/install
|
||||
$(INSTALL_DIR) $(1)/sbin $(1)/lib
|
||||
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{mount_root,jffs2reset} $(1)/sbin/
|
||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libfstools.so $(1)/lib/
|
||||
$(LN) jffs2reset $(1)/sbin/jffs2mark
|
||||
endef
|
||||
|
||||
define Package/snapshot-tool/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/snapshot_tool $(1)/sbin/
|
||||
$(INSTALL_BIN) ./files/snapshot $(1)/sbin/
|
||||
endef
|
||||
|
||||
define Package/block-mount/install
|
||||
$(INSTALL_DIR) $(1)/sbin $(1)/lib $(1)/usr/sbin $(1)/etc/hotplug.d/block $(1)/etc/init.d/ $(1)/etc/uci-defaults/
|
||||
|
||||
$(INSTALL_BIN) ./files/fstab.init $(1)/etc/init.d/fstab
|
||||
$(INSTALL_CONF) ./files/fstab.default $(1)/etc/uci-defaults/10-fstab
|
||||
$(INSTALL_CONF) ./files/mount.hotplug $(1)/etc/hotplug.d/block/10-mount
|
||||
$(INSTALL_CONF) ./files/media-change.hotplug $(1)/etc/hotplug.d/block/00-media-change
|
||||
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/block $(1)/sbin/
|
||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libblkid-tiny.so $(1)/lib/
|
||||
$(LN) ../../sbin/block $(1)/usr/sbin/swapon
|
||||
$(LN) ../../sbin/block $(1)/usr/sbin/swapoff
|
||||
|
||||
endef
|
||||
|
||||
define Package/blockd/install
|
||||
$(INSTALL_DIR) $(1)/sbin $(1)/etc/init.d/
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/blockd $(1)/sbin/
|
||||
$(INSTALL_BIN) ./files/blockd.init $(1)/etc/init.d/blockd
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/include/*.h $(1)/usr/include/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libubi-utils.a $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,fstools))
|
||||
$(eval $(call BuildPackage,snapshot-tool))
|
||||
$(eval $(call BuildPackage,block-mount))
|
||||
$(eval $(call BuildPackage,blockd))
|
||||
22
package/system/fstools/files/blockd.init
Executable file
22
package/system/fstools/files/blockd.init
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=80
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/sbin/blockd
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "fstab"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
block autofs start
|
||||
}
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command "$PROG"
|
||||
procd_set_param watch block
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
2
package/system/fstools/files/fstab.default
Normal file
2
package/system/fstools/files/fstab.default
Normal file
@@ -0,0 +1,2 @@
|
||||
[ ! -f /etc/config/fstab ] && ( block detect > /etc/config/fstab )
|
||||
exit 0
|
||||
22
package/system/fstools/files/fstab.init
Normal file
22
package/system/fstools/files/fstab.init
Normal file
@@ -0,0 +1,22 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright (C) 2013-2020 OpenWrt.org
|
||||
|
||||
START=11
|
||||
|
||||
boot() {
|
||||
/sbin/block mount
|
||||
}
|
||||
|
||||
start() {
|
||||
return 0
|
||||
}
|
||||
|
||||
restart() {
|
||||
return 0
|
||||
}
|
||||
|
||||
stop() {
|
||||
/sbin/block umount
|
||||
}
|
||||
8
package/system/fstools/files/media-change.hotplug
Normal file
8
package/system/fstools/files/media-change.hotplug
Normal file
@@ -0,0 +1,8 @@
|
||||
[ -n "$DISK_MEDIA_CHANGE" ] && /sbin/block info
|
||||
|
||||
if [ "$ACTION" = "add" -a "$DEVTYPE" = "disk" ]; then
|
||||
case "$DEVNAME" in
|
||||
mtd*) : ;;
|
||||
*) echo 2000 > /sys/block/$DEVNAME/events_poll_msecs ;;
|
||||
esac
|
||||
fi
|
||||
1
package/system/fstools/files/mount.hotplug
Normal file
1
package/system/fstools/files/mount.hotplug
Normal file
@@ -0,0 +1 @@
|
||||
[ "$ACTION" = "add" -o "$ACTION" = "remove" ] && /sbin/block hotplug
|
||||
113
package/system/fstools/files/snapshot
Normal file
113
package/system/fstools/files/snapshot
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2014 OpenWrt.org
|
||||
|
||||
|
||||
do_snapshot_unpack() {
|
||||
echo "- snapshot -"
|
||||
mkdir /tmp/snapshot
|
||||
cd /tmp/snapshot
|
||||
snapshot_tool read
|
||||
block=`ls block*.tar.gz 2> /dev/null`
|
||||
[ -z "$block" ] || for a in $block; do
|
||||
tar xzf $a -C /
|
||||
rm -f $a
|
||||
done
|
||||
}
|
||||
|
||||
do_config_unpack() {
|
||||
echo "- config -"
|
||||
snapshot_tool config_read
|
||||
[ -f /tmp/config.tar.gz ] && {
|
||||
tar xzf /tmp/config.tar.gz -C /
|
||||
rm -f /tmp/config.tar.gz
|
||||
}
|
||||
}
|
||||
|
||||
do_snapshot_push() {
|
||||
cd /volatile/upper
|
||||
tar czf /tmp/snapshot.tar.gz *
|
||||
snapshot_tool write
|
||||
reboot
|
||||
}
|
||||
|
||||
do_config_push() {
|
||||
cd /volatile/upper
|
||||
tar czf /tmp/config.tar.gz *
|
||||
snapshot_tool config_write
|
||||
}
|
||||
|
||||
do_snapshot_upgrade() {
|
||||
opkg update
|
||||
[ $? -eq 0 ] || exit 1
|
||||
|
||||
opkg list-upgradable
|
||||
[ $? -eq 0 ] || exit 2
|
||||
|
||||
UPDATES=`opkg list-upgradable | cut -d" " -f1`
|
||||
[ -z "${UPDATES}" ] && exit 0
|
||||
|
||||
opkg upgrade ${UPDATES}
|
||||
[ $? -eq 0 ] || exit 3
|
||||
|
||||
do_snapshot_push
|
||||
sleep 5
|
||||
reboot
|
||||
sleep 10
|
||||
}
|
||||
|
||||
do_convert_jffs2() {
|
||||
snapshot_tool write
|
||||
sleep 2
|
||||
reboot -f
|
||||
}
|
||||
|
||||
do_convert() {
|
||||
. /lib/functions.sh
|
||||
. /lib/upgrade/common.sh
|
||||
|
||||
cd /overlay/upper
|
||||
tar czf /tmp/snapshot.tar.gz *
|
||||
|
||||
install_bin /sbin/upgraded
|
||||
ubus call system sysupgrade "{
|
||||
\"prefix\": \"$RAM_ROOT\",
|
||||
\"path\": \"\",
|
||||
\"command\": \". /sbin/snapshot; do_convert_jffs2\"
|
||||
}"
|
||||
}
|
||||
|
||||
[ -n "$(cat /proc/mounts|grep /overlay|grep jffs2)" ] && {
|
||||
case $1 in
|
||||
convert)
|
||||
do_convert
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
[ -d /volatile/upper ] && {
|
||||
case $1 in
|
||||
push)
|
||||
do_snapshot_push
|
||||
;;
|
||||
config)
|
||||
do_config_push
|
||||
;;
|
||||
upgrade)
|
||||
do_snapshot_upgrade
|
||||
;;
|
||||
info)
|
||||
snapshot_tool info
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
[ "$SNAPSHOT" = "magic" ] && {
|
||||
case $1 in
|
||||
unpack)
|
||||
do_snapshot_unpack
|
||||
;;
|
||||
config_unpack)
|
||||
do_config_unpack
|
||||
;;
|
||||
esac
|
||||
}
|
||||
48
package/system/fwtool/Makefile
Normal file
48
package/system/fwtool/Makefile
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# Copyright (C) Felix Fietkau <nbd@nbd.name>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=fwtool
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/fwtool.git
|
||||
PKG_SOURCE_DATE:=2019-11-12
|
||||
PKG_SOURCE_VERSION:=8f7fe925ca205c8e8e2d0d1b16218c1e148d5173
|
||||
PKG_MIRROR_HASH:=fe00ac98103645d20a211732ebbbd3d46acb1e5b29392dddca2df56531e54a2e
|
||||
CMAKE_INSTALL:=1
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_MAINTAINER := Felix Fietkau <nbd@nbd.name>
|
||||
PKG_BUILD_DEPENDS := fwtool/host
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
HOST_BUILD_PREFIX:=$(STAGING_DIR_HOST)
|
||||
|
||||
define Package/fwtool
|
||||
SECTION:=utils
|
||||
CATEGORY:=Base system
|
||||
TITLE:=Utility for appending and extracting firmware metadata and signatures
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
$(INSTALL_BIN) $(HOST_BUILD_DIR)/fwtool $(1)/bin/
|
||||
endef
|
||||
|
||||
define Package/fwtool/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/fwtool $(1)/usr/bin/
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
$(eval $(call BuildPackage,fwtool))
|
||||
39
package/system/gpio-cdev/nu801/Makefile
Normal file
39
package/system/gpio-cdev/nu801/Makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=nu801
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/chunkeey/nu801.git
|
||||
PKG_SOURCE_VERSION:=f623879a393d0315f29095fe46b19cd2246d10d7
|
||||
PKG_MIRROR_HASH:=8bf2de78e078b7305178577530ff51e7373f94d39629653ea7efc8e485d0fdbd
|
||||
PKG_MAINTAINER:=Christian Lamparter <chunkeey@gmail.com>
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/nu801
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
SUBMENU:=Userspace GPIO Drivers
|
||||
DEPENDS:=@(TARGET_ath79_nand||TARGET_bcm53xx||TARGET_x86)
|
||||
KCONFIG:=CONFIG_GPIO_CDEV=y
|
||||
TITLE:=NU801 LED Driver
|
||||
endef
|
||||
|
||||
define Package/nu801/description
|
||||
This package contains a userspace driver to power the NUMEN Tech. NU801 LED Driver.
|
||||
endef
|
||||
|
||||
define Package/nu801/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/nu801 $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/nu801.init $(1)/etc/init.d/nu801
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,nu801))
|
||||
14
package/system/gpio-cdev/nu801/files/nu801.init
Executable file
14
package/system/gpio-cdev/nu801/files/nu801.init
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
START=11
|
||||
|
||||
boot() {
|
||||
. /lib/functions.sh
|
||||
/usr/sbin/nu801 "$(board_name)"
|
||||
|
||||
# Because this is a userspace driver, we need to trigger diag.sh after
|
||||
# we start the driver, but before boot is complete so we blink.
|
||||
. /etc/diag.sh
|
||||
set_state preinit_regular
|
||||
}
|
||||
63
package/system/iucode-tool/Makefile
Normal file
63
package/system/iucode-tool/Makefile
Normal file
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# Copyright (C) 2018 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=iucode-tool
|
||||
PKG_VERSION:=2.3.1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=iucode-tool_$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://gitlab.com/iucode-tool/releases/raw/latest
|
||||
PKG_HASH:=12b88efa4d0d95af08db05a50b3dcb217c0eb2bfc67b483779e33d498ddb2f95
|
||||
PKG_CPE_ID:=cpe:/a:iucode-tool_project:iucode-tool
|
||||
|
||||
PKG_BUILD_DEPENDS:=USE_UCLIBC:argp-standalone USE_MUSL:argp-standalone
|
||||
HOST_BUILD_DEPENDS:=HOST_OS_MACOS:argp-standalone/host
|
||||
|
||||
PKG_MAINTAINER:=Zoltan HERPAI <wigyori@uid0.hu>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
PKG_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
define Package/iucode-tool
|
||||
SECTION:=utils
|
||||
CATEGORY:=Base system
|
||||
URL:=$(PKG_SOURCE_URL)
|
||||
DEPENDS:=@TARGET_x86
|
||||
TITLE:=Intel microcode loader
|
||||
endef
|
||||
|
||||
define Package/iucode-tool/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/iucode_tool $(1)/usr/bin/
|
||||
endef
|
||||
|
||||
# List of build hosts with working cpuid.h
|
||||
IUT_NATIVE_HOST_OS_ARCH := \
|
||||
linux/x86_64 linux/amd64 linux/i386 linux/i686
|
||||
|
||||
IUT_HOST_OS_ARCH := $(call tolower,$(HOST_OS))/$(HOST_ARCH)
|
||||
|
||||
# Use cpuid.h compat header if build host does not have working cpuid.h
|
||||
ifeq ($(filter $(IUT_HOST_OS_ARCH),$(IUT_NATIVE_HOST_OS_ARCH)),)
|
||||
HOST_CFLAGS += \
|
||||
-I$(HOST_BUILD_DIR)/cpuid-compat
|
||||
endif
|
||||
|
||||
define Host/Install
|
||||
$(INSTALL_BIN) $(HOST_BUILD_DIR)/iucode_tool $(STAGING_DIR_HOST)/bin/iucode_tool
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
$(eval $(call BuildPackage,iucode-tool))
|
||||
@@ -0,0 +1,24 @@
|
||||
From e1137cdafc97c0a8b2a0717a771823f3c4320087 Mon Sep 17 00:00:00 2001
|
||||
From: Christian Marangi <ansuelsmth@gmail.com>
|
||||
Date: Tue, 29 Nov 2022 19:37:03 +0100
|
||||
Subject: [PATCH] iucode_tool: add missing limits.h for USE_CPUID_DEVICE
|
||||
|
||||
If USE_CPUID_DEVICE is enabled, compilation fails for missing define.
|
||||
Add the missing include to fix compilation error with USE_CPUID_DEVICE
|
||||
define.
|
||||
|
||||
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
---
|
||||
iucode_tool.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
--- a/iucode_tool.c
|
||||
+++ b/iucode_tool.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
+#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -0,0 +1,31 @@
|
||||
From a21e75da32c0016f1575ea29775565934a67660d Mon Sep 17 00:00:00 2001
|
||||
From: "Sergey V. Lobanov" <sergey@lobanov.in>
|
||||
Date: Sat, 5 Feb 2022 13:10:23 +0300
|
||||
Subject: [PATCH] Add cpuid compatibility header to build on non-x86 hosts
|
||||
|
||||
Signed-off-by: Sergey V. Lobanov <sergey@lobanov.in>
|
||||
---
|
||||
cpuid-compat/cpuid.h | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
create mode 100644 cpuid-compat/cpuid.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/cpuid-compat/cpuid.h
|
||||
@@ -0,0 +1,17 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * cpuid compatibility header to build iucode-tool on non-x86 hosts
|
||||
+ *
|
||||
+ * Copyright (C) 2022 Sergey V. Lobanov <sergey@lobanov.in>
|
||||
+ */
|
||||
+
|
||||
+#ifdef __APPLE__
|
||||
+# include <limits.h>
|
||||
+#endif
|
||||
+
|
||||
+static __inline int __get_cpuid (unsigned int leaf,
|
||||
+ unsigned int *eax, unsigned int *ebx,
|
||||
+ unsigned int *ecx, unsigned int *edx)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
52
package/system/mtd/Makefile
Normal file
52
package/system/mtd/Makefile
Normal file
@@ -0,0 +1,52 @@
|
||||
#
|
||||
# Copyright (C) 2006-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=mtd
|
||||
PKG_RELEASE:=26
|
||||
|
||||
PKG_BUILD_DIR := $(KERNEL_BUILD_DIR)/$(PKG_NAME)
|
||||
STAMP_PREPARED := $(STAMP_PREPARED)_$(call confvar,CONFIG_MTD_REDBOOT_PARTS)
|
||||
|
||||
PKG_LICENSE:=GPL-2.0+
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
PKG_BUILD_FLAGS:=lto
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/mtd
|
||||
SECTION:=utils
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+libubox
|
||||
TITLE:=Update utility for trx firmware images
|
||||
endef
|
||||
|
||||
define Package/mtd/description
|
||||
This package contains an utility useful to upgrade from other firmware or
|
||||
older OpenWrt releases.
|
||||
endef
|
||||
|
||||
target=$(firstword $(subst -, ,$(BOARD)))
|
||||
|
||||
MAKE_FLAGS += TARGET="$(target)"
|
||||
TARGET_CFLAGS += -Dtarget_$(target)=1 -Wall
|
||||
|
||||
ifdef CONFIG_MTD_REDBOOT_PARTS
|
||||
MAKE_FLAGS += FIS_SUPPORT=1
|
||||
TARGET_CFLAGS += -DFIS_SUPPORT=1
|
||||
endif
|
||||
|
||||
define Package/mtd/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mtd $(1)/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,mtd))
|
||||
31
package/system/mtd/src/Makefile
Normal file
31
package/system/mtd/src/Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
CC = gcc
|
||||
CFLAGS += -Wall
|
||||
LDFLAGS += -lubox
|
||||
|
||||
obj = mtd.o jffs2.o crc32.o md5.o
|
||||
obj.seama = seama.o md5.o
|
||||
obj.wrg = wrg.o md5.o
|
||||
obj.wrgg = wrgg.o md5.o
|
||||
obj.tpl = tpl_ramips_recoveryflag.o
|
||||
obj.ath79 = $(obj.seama) $(obj.wrgg)
|
||||
obj.gemini = $(obj.wrgg)
|
||||
obj.brcm = trx.o
|
||||
obj.bcm47xx = $(obj.brcm)
|
||||
obj.bcm53xx = $(obj.brcm) $(obj.seama)
|
||||
obj.mediatek = $(obj.brcm)
|
||||
obj.bcm63xx = imagetag.o
|
||||
obj.bmips = imagetag.o
|
||||
obj.ramips = $(obj.brcm) $(obj.seama) $(obj.tpl) $(obj.wrg) linksys_bootcount.o
|
||||
obj.mvebu = linksys_bootcount.o
|
||||
obj.kirkwood = linksys_bootcount.o
|
||||
obj.ipq806x = linksys_bootcount.o
|
||||
obj.ipq40xx = linksys_bootcount.o
|
||||
obj.qualcommax = linksys_bootcount.o
|
||||
|
||||
ifdef FIS_SUPPORT
|
||||
obj += fis.o
|
||||
endif
|
||||
|
||||
mtd: $(obj) $(obj.$(TARGET))
|
||||
clean:
|
||||
rm -f *.o jffs2
|
||||
95
package/system/mtd/src/crc32.c
Normal file
95
package/system/mtd/src/crc32.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
*
|
||||
* First, the polynomial itself and its table of feedback terms. The
|
||||
* polynomial is
|
||||
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
|
||||
*
|
||||
* Note that we take it "backwards" and put the highest-order term in
|
||||
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
|
||||
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
|
||||
* the MSB being 1
|
||||
*
|
||||
* Note that the usual hardware shift register implementation, which
|
||||
* is what we're using (we're merely optimizing it by doing eight-bit
|
||||
* chunks at a time) shifts bits into the lowest-order term. In our
|
||||
* implementation, that means shifting towards the right. Why do we
|
||||
* do it this way? Because the calculated CRC must be transmitted in
|
||||
* order from highest-order term to lowest-order term. UARTs transmit
|
||||
* characters in order from LSB to MSB. By storing the CRC this way
|
||||
* we hand it to the UART in the order low-byte to high-byte; the UART
|
||||
* sends each low-bit to hight-bit; and the result is transmission bit
|
||||
* by bit from highest- to lowest-order term without requiring any bit
|
||||
* shuffling on our part. Reception works similarly
|
||||
*
|
||||
* The feedback terms table consists of 256, 32-bit entries. Notes
|
||||
*
|
||||
* The table can be generated at runtime if desired; code to do so
|
||||
* is shown later. It might not be obvious, but the feedback
|
||||
* terms simply represent the results of eight shift/xor opera
|
||||
* tions for all combinations of data and CRC register values
|
||||
*
|
||||
* The values must be right-shifted by eight bits by the "updcrc
|
||||
* logic; the shift must be unsigned (bring in zeroes). On some
|
||||
* hardware you could probably optimize the shift in assembler by
|
||||
* using byte-swap instructions
|
||||
* polynomial $edb88320
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
const uint32_t crc32_table[256] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
26
package/system/mtd/src/crc32.h
Normal file
26
package/system/mtd/src/crc32.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef CRC32_H
|
||||
#define CRC32_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern const uint32_t crc32_table[256];
|
||||
|
||||
/* Return a 32-bit CRC of the contents of the buffer. */
|
||||
|
||||
static inline uint32_t
|
||||
crc32(uint32_t val, const void *ss, int len)
|
||||
{
|
||||
const unsigned char *s = ss;
|
||||
while (--len >= 0)
|
||||
val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8);
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline unsigned int crc32buf(char *buf, size_t len)
|
||||
{
|
||||
return crc32(0xFFFFFFFF, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
242
package/system/mtd/src/fis.c
Normal file
242
package/system/mtd/src/fis.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* FIS table updating code for mtd
|
||||
*
|
||||
* Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License v2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#include <sys/mman.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "crc32.h"
|
||||
#include "mtd.h"
|
||||
#include "fis.h"
|
||||
|
||||
struct fis_image_hdr {
|
||||
unsigned char name[16];
|
||||
uint32_t flash_base;
|
||||
uint32_t mem_base;
|
||||
uint32_t size;
|
||||
uint32_t entry_point;
|
||||
uint32_t data_length;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct fis_image_crc {
|
||||
uint32_t desc;
|
||||
uint32_t file;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct fis_image_desc {
|
||||
struct fis_image_hdr hdr;
|
||||
char _pad[256 - sizeof(struct fis_image_hdr) - sizeof(struct fis_image_crc)];
|
||||
struct fis_image_crc crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
static int fis_fd = -1;
|
||||
static struct fis_image_desc *fis_desc;
|
||||
static int fis_erasesize = 0;
|
||||
|
||||
static void
|
||||
fis_close(void)
|
||||
{
|
||||
if (fis_desc)
|
||||
munmap(fis_desc, fis_erasesize);
|
||||
|
||||
if (fis_fd >= 0)
|
||||
close(fis_fd);
|
||||
|
||||
fis_fd = -1;
|
||||
fis_desc = NULL;
|
||||
}
|
||||
|
||||
static struct fis_image_desc *
|
||||
fis_open(void)
|
||||
{
|
||||
struct fis_image_desc *desc;
|
||||
|
||||
if (fis_fd >= 0)
|
||||
fis_close();
|
||||
|
||||
fis_fd = mtd_check_open("FIS directory");
|
||||
if (fis_fd < 0)
|
||||
goto error;
|
||||
|
||||
close(fis_fd);
|
||||
fis_fd = mtd_open("FIS directory", true);
|
||||
if (fis_fd < 0)
|
||||
goto error;
|
||||
|
||||
fis_erasesize = erasesize;
|
||||
desc = mmap(NULL, erasesize, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, fis_fd, 0);
|
||||
if (desc == MAP_FAILED)
|
||||
goto error;
|
||||
|
||||
fis_desc = desc;
|
||||
return desc;
|
||||
|
||||
error:
|
||||
fis_close();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
fis_validate(struct fis_part *old, int n_old, struct fis_part *new, int n_new)
|
||||
{
|
||||
struct fis_image_desc *desc;
|
||||
void *end;
|
||||
int found = 0;
|
||||
int i;
|
||||
|
||||
desc = fis_open();
|
||||
if (!desc)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < n_new - 1; i++) {
|
||||
if (!new[i].size) {
|
||||
fprintf(stderr, "FIS error: only the last partition can detect the size automatically\n");
|
||||
i = -1;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
end = desc;
|
||||
end = (char *) end + fis_erasesize;
|
||||
while ((void *) desc < end) {
|
||||
if (!desc->hdr.name[0] || (desc->hdr.name[0] == 0xff))
|
||||
break;
|
||||
|
||||
for (i = 0; i < n_old; i++) {
|
||||
if (!strncmp((char *) desc->hdr.name, (char *) old[i].name, sizeof(desc->hdr.name))) {
|
||||
found++;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
next:
|
||||
desc++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (found == n_old)
|
||||
i = 1;
|
||||
else
|
||||
i = -1;
|
||||
|
||||
done:
|
||||
fis_close();
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new)
|
||||
{
|
||||
struct fis_image_desc *first = NULL;
|
||||
struct fis_image_desc *last = NULL;
|
||||
struct fis_image_desc *first_fb = NULL;
|
||||
struct fis_image_desc *last_fb = NULL;
|
||||
struct fis_image_desc *desc;
|
||||
struct fis_part *part;
|
||||
uint32_t offset = 0, size = 0;
|
||||
char *start, *end, *tmp;
|
||||
int i;
|
||||
|
||||
desc = fis_open();
|
||||
if (!desc)
|
||||
return -1;
|
||||
|
||||
if (!quiet)
|
||||
fprintf(stderr, "Updating FIS table... \n");
|
||||
|
||||
start = (char *) desc;
|
||||
end = (char *) desc + fis_erasesize;
|
||||
while ((char *) desc < end) {
|
||||
if (!desc->hdr.name[0] || (desc->hdr.name[0] == 0xff))
|
||||
break;
|
||||
|
||||
/* update max offset */
|
||||
if (offset < desc->hdr.flash_base)
|
||||
offset = desc->hdr.flash_base;
|
||||
|
||||
for (i = 0; i < n_old; i++) {
|
||||
if (!strncmp((char *) desc->hdr.name, (char *) old[i].name, sizeof(desc->hdr.name))) {
|
||||
last = desc;
|
||||
if (!first)
|
||||
first = desc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
desc++;
|
||||
}
|
||||
desc--;
|
||||
|
||||
first_fb = first;
|
||||
last_fb = last;
|
||||
|
||||
if (first_fb->hdr.flash_base > last_fb->hdr.flash_base) {
|
||||
first_fb = last;
|
||||
last_fb = first;
|
||||
}
|
||||
|
||||
/* determine size of available space */
|
||||
desc = (struct fis_image_desc *) start;
|
||||
while ((char *) desc < end) {
|
||||
if (!desc->hdr.name[0] || (desc->hdr.name[0] == 0xff))
|
||||
break;
|
||||
|
||||
if (desc->hdr.flash_base > last_fb->hdr.flash_base &&
|
||||
desc->hdr.flash_base < offset)
|
||||
offset = desc->hdr.flash_base;
|
||||
|
||||
desc++;
|
||||
}
|
||||
desc--;
|
||||
|
||||
size = offset - first_fb->hdr.flash_base;
|
||||
|
||||
last++;
|
||||
desc = first + n_new;
|
||||
offset = first_fb->hdr.flash_base;
|
||||
|
||||
if (desc != last) {
|
||||
if (desc > last)
|
||||
tmp = (char *) desc;
|
||||
else
|
||||
tmp = (char *) last;
|
||||
|
||||
memmove(desc, last, end - tmp);
|
||||
if (desc < last) {
|
||||
tmp = end - (last - desc) * sizeof(struct fis_image_desc);
|
||||
memset(tmp, 0xff, tmp - end);
|
||||
}
|
||||
}
|
||||
|
||||
for (part = new, desc = first; desc < first + n_new; desc++, part++) {
|
||||
memset(desc, 0, sizeof(struct fis_image_desc));
|
||||
memcpy(desc->hdr.name, part->name, sizeof(desc->hdr.name));
|
||||
desc->crc.desc = 0;
|
||||
desc->crc.file = part->crc;
|
||||
|
||||
desc->hdr.flash_base = offset;
|
||||
desc->hdr.mem_base = part->loadaddr;
|
||||
desc->hdr.entry_point = part->loadaddr;
|
||||
desc->hdr.size = (part->size > 0) ? part->size : size;
|
||||
desc->hdr.data_length = (part->length > 0) ? part->length :
|
||||
desc->hdr.size;
|
||||
offset += desc->hdr.size;
|
||||
size -= desc->hdr.size;
|
||||
}
|
||||
|
||||
msync(fis_desc, fis_erasesize, MS_SYNC|MS_INVALIDATE);
|
||||
fis_close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
16
package/system/mtd/src/fis.h
Normal file
16
package/system/mtd/src/fis.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef __FIS_H
|
||||
#define __FIS_H
|
||||
|
||||
struct fis_part {
|
||||
unsigned char name[16];
|
||||
uint32_t offset;
|
||||
uint32_t loadaddr;
|
||||
uint32_t size;
|
||||
uint32_t length;
|
||||
uint32_t crc;
|
||||
};
|
||||
|
||||
int fis_validate(struct fis_part *old, int n_old, struct fis_part *new, int n_new);
|
||||
int fis_remap(struct fis_part *old, int n_old, struct fis_part *new, int n_new);
|
||||
|
||||
#endif
|
||||
410
package/system/mtd/src/imagetag.c
Normal file
410
package/system/mtd/src/imagetag.c
Normal file
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* imagetag.c
|
||||
*
|
||||
* Copyright (C) 2005 Mike Baker
|
||||
* Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyrigth (C) 2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
|
||||
#include "mtd.h"
|
||||
#include "crc32.h"
|
||||
|
||||
#define TAGVER_LEN 4 /* Length of Tag Version */
|
||||
#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */
|
||||
#define SIG1_LEN 20 /* Company Signature 1 Length */
|
||||
#define SIG2_LEN 14 /* Company Signature 2 Length */
|
||||
#define BOARDID_LEN 16 /* Length of BoardId */
|
||||
#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
|
||||
#define CHIPID_LEN 6 /* Chip Id Length */
|
||||
#define IMAGE_LEN 10 /* Length of Length Field */
|
||||
#define ADDRESS_LEN 12 /* Length of Address field */
|
||||
#define DUALFLAG_LEN 2 /* Dual Image flag Length */
|
||||
#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */
|
||||
#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
|
||||
#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
|
||||
#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
|
||||
#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
|
||||
#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
|
||||
|
||||
#define NUM_PIRELLI 2
|
||||
#define IMAGETAG_CRC_START 0xFFFFFFFF
|
||||
|
||||
#define PIRELLI_BOARDS { \
|
||||
"AGPF-S0", \
|
||||
"DWV-S0", \
|
||||
}
|
||||
/*
|
||||
* The broadcom firmware assumes the rootfs starts the image,
|
||||
* therefore uses the rootfs start (flash_image_address)
|
||||
* to determine where to flash the image. Since we have the kernel first
|
||||
* we have to give it the kernel address, but the crc uses the length
|
||||
* associated with this address (root_length), which is added to the kernel
|
||||
* length (kernel_length) to determine the length of image to flash and thus
|
||||
* needs to be rootfs + deadcode (jffs2 EOF marker)
|
||||
*/
|
||||
|
||||
struct bcm_tag {
|
||||
/* 0-3: Version of the image tag */
|
||||
char tag_version[TAGVER_LEN];
|
||||
/* 4-23: Company Line 1 */
|
||||
char sig_1[SIG1_LEN];
|
||||
/* 24-37: Company Line 2 */
|
||||
char sig_2[SIG2_LEN];
|
||||
/* 38-43: Chip this image is for */
|
||||
char chip_id[CHIPID_LEN];
|
||||
/* 44-59: Board name */
|
||||
char board_id[BOARDID_LEN];
|
||||
/* 60-61: Map endianness -- 1 BE 0 LE */
|
||||
char big_endian[ENDIANFLAG_LEN];
|
||||
/* 62-71: Total length of image */
|
||||
char total_length[IMAGE_LEN];
|
||||
/* 72-83: Address in memory of CFE */
|
||||
char cfe__address[ADDRESS_LEN];
|
||||
/* 84-93: Size of CFE */
|
||||
char cfe_length[IMAGE_LEN];
|
||||
/* 94-105: Address in memory of image start
|
||||
* (kernel for OpenWRT, rootfs for stock firmware)
|
||||
*/
|
||||
char flash_image_start[ADDRESS_LEN];
|
||||
/* 106-115: Size of rootfs */
|
||||
char root_length[IMAGE_LEN];
|
||||
/* 116-127: Address in memory of kernel */
|
||||
char kernel_address[ADDRESS_LEN];
|
||||
/* 128-137: Size of kernel */
|
||||
char kernel_length[IMAGE_LEN];
|
||||
/* 138-139: Unused at the moment */
|
||||
char dual_image[DUALFLAG_LEN];
|
||||
/* 140-141: Unused at the moment */
|
||||
char inactive_flag[INACTIVEFLAG_LEN];
|
||||
/* 142-161: RSA Signature (not used; some vendors may use this) */
|
||||
char rsa_signature[RSASIG_LEN];
|
||||
/* 162-191: Compilation and related information (not used in OpenWrt) */
|
||||
char information1[TAGINFO1_LEN];
|
||||
/* 192-195: Version flash layout */
|
||||
char flash_layout_ver[FLASHLAYOUTVER_LEN];
|
||||
/* 196-199: kernel+rootfs CRC32 */
|
||||
__u32 fskernel_crc;
|
||||
/* 200-215: Unused except on Alice Gate where is is information */
|
||||
char information2[TAGINFO2_LEN];
|
||||
/* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
|
||||
__u32 image_crc;
|
||||
/* 220-223: CRC32 of rootfs partition */
|
||||
__u32 rootfs_crc;
|
||||
/* 224-227: CRC32 of kernel partition */
|
||||
__u32 kernel_crc;
|
||||
/* 228-231: Image sequence number */
|
||||
char image_sequence[4];
|
||||
/* 222-235: Openwrt: real rootfs length */
|
||||
__u32 real_rootfs_length;
|
||||
/* 236-239: CRC32 of header excluding last 20 bytes */
|
||||
__u32 header_crc;
|
||||
/* 240-255: Unused at present */
|
||||
char reserved2[16];
|
||||
};
|
||||
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
|
||||
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
|
||||
|
||||
#define CRC_START 0xFFFFFFFF
|
||||
|
||||
static uint32_t strntoul(char *str, char **endptr, int base, size_t len) {
|
||||
char *newstr;
|
||||
uint32_t res = 0;
|
||||
|
||||
newstr = calloc(len + 1, sizeof(char));
|
||||
if (newstr) {
|
||||
strncpy(newstr, str, len);
|
||||
res = strtoul(newstr, endptr, base);
|
||||
free(newstr);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t compute_crc32(uint32_t crc, off_t start, size_t compute_len, int fd)
|
||||
{
|
||||
uint8_t readbuf[1024];
|
||||
ssize_t res;
|
||||
off_t offset = start;
|
||||
|
||||
/* Read a buffer's worth of bytes */
|
||||
while (fd && (compute_len >= sizeof(readbuf))) {
|
||||
res = pread(fd, readbuf, sizeof(readbuf), offset);
|
||||
crc = crc32(crc, readbuf, res);
|
||||
compute_len = compute_len - res;
|
||||
offset += res;
|
||||
}
|
||||
|
||||
/* Less than buffer-size bytes remains, read compute_len bytes */
|
||||
if (fd && (compute_len > 0)) {
|
||||
res = pread(fd, readbuf, compute_len, offset);
|
||||
crc = crc32(crc, readbuf, res);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
int
|
||||
trx_fixup(int fd, const char *name)
|
||||
{
|
||||
struct mtd_info_user mtdInfo;
|
||||
unsigned long len;
|
||||
void *ptr, *scan;
|
||||
int bfd;
|
||||
struct bcm_tag *tag;
|
||||
ssize_t res;
|
||||
uint32_t cfelen, imagelen, imagestart, rootfslen;
|
||||
uint32_t imagecrc, rootfscrc, headercrc;
|
||||
uint32_t offset = 0;
|
||||
cfelen = imagelen = imagestart = imagecrc = rootfscrc = headercrc = rootfslen = 0;
|
||||
|
||||
|
||||
if (ioctl(fd, MEMGETINFO, &mtdInfo) < 0) {
|
||||
fprintf(stderr, "Failed to get mtd info\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
len = mtdInfo.size;
|
||||
if (mtdInfo.size <= 0) {
|
||||
fprintf(stderr, "Invalid MTD device size\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
bfd = mtd_open(name, true);
|
||||
ptr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, bfd, 0);
|
||||
if (!ptr || (ptr == (void *) -1)) {
|
||||
perror("mmap");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
tag = (struct bcm_tag *) (ptr);
|
||||
|
||||
cfelen = strntoul(&tag->cfe_length[0], NULL, 10, IMAGE_LEN);
|
||||
if (cfelen) {
|
||||
fprintf(stderr, "Non-zero CFE length. This is currently unsupported.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
headercrc = compute_crc32(CRC_START, offset, offsetof(struct bcm_tag, header_crc), fd);
|
||||
if (headercrc != *(uint32_t *)(&tag->header_crc)) {
|
||||
fprintf(stderr, "Tag verify failed. This may not be a valid image.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sprintf(&tag->root_length[0], "%u", 0);
|
||||
strncpy(&tag->total_length[0], &tag->kernel_length[0], IMAGE_LEN);
|
||||
|
||||
imagestart = sizeof(tag);
|
||||
memcpy(&tag->image_crc, &tag->kernel_crc, sizeof(uint32_t));
|
||||
memcpy(&tag->fskernel_crc, &tag->kernel_crc, sizeof(uint32_t));
|
||||
rootfscrc = CRC_START;
|
||||
memcpy(&tag->rootfs_crc, &rootfscrc, sizeof(uint32_t));
|
||||
headercrc = crc32(CRC_START, tag, offsetof(struct bcm_tag, header_crc));
|
||||
memcpy(&tag->header_crc, &headercrc, sizeof(uint32_t));
|
||||
|
||||
msync(ptr, sizeof(struct bcm_tag), MS_SYNC|MS_INVALIDATE);
|
||||
munmap(ptr, len);
|
||||
close(bfd);
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
close(bfd);
|
||||
err:
|
||||
fprintf(stderr, "Error fixing up imagetag header\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
trx_check(int imagefd, const char *mtd, char *buf, int *len)
|
||||
{
|
||||
struct bcm_tag *tag = (const struct bcm_tag *) buf;
|
||||
int fd;
|
||||
uint32_t headerCRC;
|
||||
uint32_t imageLen;
|
||||
|
||||
if (strcmp(mtd, "linux") != 0)
|
||||
return 1;
|
||||
|
||||
*len = read(imagefd, buf, sizeof(struct bcm_tag));
|
||||
if (*len < sizeof(struct bcm_tag)) {
|
||||
fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", *len);
|
||||
return 0;
|
||||
}
|
||||
headerCRC = crc32buf(buf, offsetof(struct bcm_tag, header_crc));
|
||||
if (*(uint32_t *)(&tag->header_crc) != headerCRC) {
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "Bad header CRC got %08x, calculated %08x\n",
|
||||
*(uint32_t *)(&tag->header_crc), headerCRC);
|
||||
fprintf(stderr, "This is not the correct file format; refusing to flash.\n"
|
||||
"Please specify the correct file or use -f to force.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if image fits to mtd device */
|
||||
fd = mtd_check_open(mtd);
|
||||
if(fd < 0) {
|
||||
fprintf(stderr, "Could not open mtd device: %s\n", mtd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
imageLen = strntoul(&tag->total_length[0], NULL, 10, IMAGE_LEN);
|
||||
|
||||
if(mtdsize < imageLen) {
|
||||
fprintf(stderr, "Image too big for partition: %s\n", mtd);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
|
||||
{
|
||||
int fd;
|
||||
struct bcm_tag *tag;
|
||||
char *buf;
|
||||
ssize_t res;
|
||||
size_t block_offset;
|
||||
uint32_t cfelen, imagelen, imagestart, rootfslen;
|
||||
uint32_t imagecrc, rootfscrc, headercrc;
|
||||
cfelen = imagelen = imagestart = imagecrc = rootfscrc = headercrc = rootfslen = 0;
|
||||
|
||||
if (data_size)
|
||||
fprintf(stderr, "Specifying data size in unsupported for imagetag\n");
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Trying to fix trx header in %s at 0x%x...\n", mtd, offset);
|
||||
|
||||
block_offset = offset & ~(erasesize - 1);
|
||||
offset -= block_offset;
|
||||
|
||||
fd = mtd_check_open(mtd);
|
||||
if(fd < 0) {
|
||||
fprintf(stderr, "Could not open mtd device: %s\n", mtd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (block_offset + erasesize > mtdsize) {
|
||||
fprintf(stderr, "Offset too large, device size 0x%x\n", mtdsize);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
buf = malloc(erasesize);
|
||||
if (!buf) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
res = pread(fd, buf, erasesize, block_offset);
|
||||
if (res != erasesize) {
|
||||
perror("pread");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tag = (struct bcm_tag *) (buf + offset);
|
||||
|
||||
cfelen = strntoul(tag->cfe_length, NULL, 10, IMAGE_LEN);
|
||||
if (cfelen) {
|
||||
fprintf(stderr, "Non-zero CFE length. This is currently unsupported.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "Verifying we actually have an imagetag.\n");
|
||||
}
|
||||
|
||||
headercrc = compute_crc32(CRC_START, offset, offsetof(struct bcm_tag, header_crc), fd);
|
||||
if (headercrc != *(uint32_t *)(&tag->header_crc)) {
|
||||
fprintf(stderr, "Tag verify failed. This may not be a valid image.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "Checking current fixed status.\n");
|
||||
}
|
||||
|
||||
rootfslen = strntoul(&tag->root_length[0], NULL, 10, IMAGE_LEN);
|
||||
if (rootfslen == 0) {
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Header already fixed, exiting\n");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "Setting root length to 0.\n");
|
||||
}
|
||||
|
||||
sprintf(&tag->root_length[0], "%u", 0);
|
||||
strncpy(&tag->total_length[0], &tag->kernel_length[0], IMAGE_LEN);
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "Recalculating CRCs.\n");
|
||||
}
|
||||
|
||||
imagestart = sizeof(tag);
|
||||
memcpy(&tag->image_crc, &tag->kernel_crc, sizeof(uint32_t));
|
||||
memcpy(&tag->fskernel_crc, &tag->kernel_crc, sizeof(uint32_t));
|
||||
rootfscrc = CRC_START;
|
||||
memcpy(&tag->rootfs_crc, &rootfscrc, sizeof(uint32_t));
|
||||
headercrc = crc32(CRC_START, tag, offsetof(struct bcm_tag, header_crc));
|
||||
memcpy(&tag->header_crc, &headercrc, sizeof(uint32_t));
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "Erasing imagetag block\n");
|
||||
}
|
||||
|
||||
if (mtd_erase_block(fd, block_offset)) {
|
||||
fprintf(stderr, "Can't erase block at 0x%x (%s)\n", block_offset, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "New image crc32: 0x%x, rewriting block\n",
|
||||
*(uint32_t *)(&tag->image_crc));
|
||||
fprintf(stderr, "New header crc32: 0x%x, rewriting block\n", headercrc);
|
||||
}
|
||||
|
||||
if (pwrite(fd, buf, erasesize, block_offset) != erasesize) {
|
||||
fprintf(stderr, "Error writing block (%s)\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Done.\n");
|
||||
|
||||
close (fd);
|
||||
sync();
|
||||
return 0;
|
||||
|
||||
}
|
||||
366
package/system/mtd/src/jffs2.c
Normal file
366
package/system/mtd/src/jffs2.c
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* jffs2 on-disk structure generator for mtd
|
||||
*
|
||||
* Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License v2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* Based on:
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
* Copyright © 2001-2007 Red Hat, Inc.
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <endian.h>
|
||||
#include "jffs2.h"
|
||||
#include "crc32.h"
|
||||
#include "mtd.h"
|
||||
|
||||
#define PAD(x) (((x)+3)&~3)
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
# define CLEANMARKER "\x19\x85\x20\x03\x00\x00\x00\x0c\xf0\x60\xdc\x98"
|
||||
#else
|
||||
# define CLEANMARKER "\x85\x19\x03\x20\x0c\x00\x00\x00\xb1\xb0\x1e\xe4"
|
||||
#endif
|
||||
|
||||
static int last_ino = 0;
|
||||
static int last_version = 0;
|
||||
static char *buf = NULL;
|
||||
static int ofs = 0;
|
||||
static int outfd = -1;
|
||||
static int mtdofs = 0;
|
||||
static int target_ino = 0;
|
||||
|
||||
static void prep_eraseblock(void);
|
||||
|
||||
static void pad(int size)
|
||||
{
|
||||
if ((ofs % size == 0) && (ofs < erasesize))
|
||||
return;
|
||||
|
||||
if (ofs < erasesize) {
|
||||
memset(buf + ofs, 0xff, (size - (ofs % size)));
|
||||
ofs += (size - (ofs % size));
|
||||
}
|
||||
ofs = ofs % erasesize;
|
||||
if (ofs == 0) {
|
||||
while (mtd_block_is_bad(outfd, mtdofs) && (mtdofs < mtdsize)) {
|
||||
if (!quiet)
|
||||
fprintf(stderr, "\nSkipping bad block at 0x%08x ", mtdofs);
|
||||
|
||||
mtdofs += erasesize;
|
||||
|
||||
/* Move the file pointer along over the bad block. */
|
||||
lseek(outfd, erasesize, SEEK_CUR);
|
||||
}
|
||||
mtd_erase_block(outfd, mtdofs);
|
||||
write(outfd, buf, erasesize);
|
||||
mtdofs += erasesize;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int rbytes(void)
|
||||
{
|
||||
return erasesize - (ofs % erasesize);
|
||||
}
|
||||
|
||||
static inline void add_data(char *ptr, int len)
|
||||
{
|
||||
if (ofs + len > erasesize) {
|
||||
pad(erasesize);
|
||||
prep_eraseblock();
|
||||
}
|
||||
memcpy(buf + ofs, ptr, len);
|
||||
ofs += len;
|
||||
}
|
||||
|
||||
static void prep_eraseblock(void)
|
||||
{
|
||||
if (ofs > 0)
|
||||
return;
|
||||
|
||||
add_data(CLEANMARKER, sizeof(CLEANMARKER) - 1);
|
||||
}
|
||||
|
||||
static int add_dirent(const char *name, const char type, int parent)
|
||||
{
|
||||
struct jffs2_raw_dirent *de;
|
||||
|
||||
if (ofs - erasesize < sizeof(struct jffs2_raw_dirent) + strlen(name))
|
||||
pad(erasesize);
|
||||
|
||||
prep_eraseblock();
|
||||
last_ino++;
|
||||
memset(buf + ofs, 0, sizeof(struct jffs2_raw_dirent));
|
||||
de = (struct jffs2_raw_dirent *) (buf + ofs);
|
||||
|
||||
de->magic = JFFS2_MAGIC_BITMASK;
|
||||
de->nodetype = JFFS2_NODETYPE_DIRENT;
|
||||
de->type = type;
|
||||
de->name_crc = crc32(0, name, strlen(name));
|
||||
de->ino = last_ino++;
|
||||
de->pino = parent;
|
||||
de->totlen = sizeof(*de) + strlen(name);
|
||||
de->hdr_crc = crc32(0, (void *) de, sizeof(struct jffs2_unknown_node) - 4);
|
||||
de->version = last_version++;
|
||||
de->mctime = 0;
|
||||
de->nsize = strlen(name);
|
||||
de->node_crc = crc32(0, (void *) de, sizeof(*de) - 8);
|
||||
memcpy(de->name, name, strlen(name));
|
||||
|
||||
ofs += sizeof(struct jffs2_raw_dirent) + de->nsize;
|
||||
pad(4);
|
||||
|
||||
return de->ino;
|
||||
}
|
||||
|
||||
static int add_dir(const char *name, int parent)
|
||||
{
|
||||
struct jffs2_raw_inode ri;
|
||||
int inode;
|
||||
|
||||
inode = add_dirent(name, IFTODT(S_IFDIR), parent);
|
||||
|
||||
if (rbytes() < sizeof(ri))
|
||||
pad(erasesize);
|
||||
prep_eraseblock();
|
||||
|
||||
memset(&ri, 0, sizeof(ri));
|
||||
ri.magic = JFFS2_MAGIC_BITMASK;
|
||||
ri.nodetype = JFFS2_NODETYPE_INODE;
|
||||
ri.totlen = sizeof(ri);
|
||||
ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node) - 4);
|
||||
|
||||
ri.ino = inode;
|
||||
ri.mode = S_IFDIR | 0755;
|
||||
ri.uid = ri.gid = 0;
|
||||
ri.atime = ri.ctime = ri.mtime = 0;
|
||||
ri.isize = ri.csize = ri.dsize = 0;
|
||||
ri.version = 1;
|
||||
ri.node_crc = crc32(0, &ri, sizeof(ri) - 8);
|
||||
ri.data_crc = 0;
|
||||
|
||||
add_data((char *) &ri, sizeof(ri));
|
||||
pad(4);
|
||||
return inode;
|
||||
}
|
||||
|
||||
static void add_file(const char *name, int parent)
|
||||
{
|
||||
int inode, f_offset = 0, fd;
|
||||
struct jffs2_raw_inode ri;
|
||||
struct stat st;
|
||||
char wbuf[4096];
|
||||
const char *fname;
|
||||
|
||||
if (stat(name, &st)) {
|
||||
fprintf(stderr, "File %s does not exist\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
fname = strrchr(name, '/');
|
||||
if (fname)
|
||||
fname++;
|
||||
else
|
||||
fname = name;
|
||||
|
||||
inode = add_dirent(fname, IFTODT(S_IFREG), parent);
|
||||
memset(&ri, 0, sizeof(ri));
|
||||
ri.magic = JFFS2_MAGIC_BITMASK;
|
||||
ri.nodetype = JFFS2_NODETYPE_INODE;
|
||||
|
||||
ri.ino = inode;
|
||||
ri.mode = st.st_mode;
|
||||
ri.uid = ri.gid = 0;
|
||||
ri.atime = st.st_atime;
|
||||
ri.ctime = st.st_ctime;
|
||||
ri.mtime = st.st_mtime;
|
||||
ri.isize = st.st_size;
|
||||
ri.compr = 0;
|
||||
ri.usercompr = 0;
|
||||
|
||||
fd = open(name, 0);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "File %s does not exist\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int len = 0;
|
||||
|
||||
for (;;) {
|
||||
len = rbytes() - sizeof(ri);
|
||||
if (len > 128)
|
||||
break;
|
||||
|
||||
pad(erasesize);
|
||||
prep_eraseblock();
|
||||
}
|
||||
|
||||
if (len > sizeof(wbuf))
|
||||
len = sizeof(wbuf);
|
||||
|
||||
len = read(fd, wbuf, len);
|
||||
if (len <= 0)
|
||||
break;
|
||||
|
||||
ri.totlen = sizeof(ri) + len;
|
||||
ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node) - 4);
|
||||
ri.version = ++last_version;
|
||||
ri.offset = f_offset;
|
||||
ri.csize = ri.dsize = len;
|
||||
ri.node_crc = crc32(0, &ri, sizeof(ri) - 8);
|
||||
ri.data_crc = crc32(0, wbuf, len);
|
||||
f_offset += len;
|
||||
add_data((char *) &ri, sizeof(ri));
|
||||
add_data(wbuf, len);
|
||||
pad(4);
|
||||
prep_eraseblock();
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int mtd_replace_jffs2(const char *mtd, int fd, int ofs, const char *filename)
|
||||
{
|
||||
outfd = fd;
|
||||
mtdofs = ofs;
|
||||
|
||||
buf = malloc(erasesize);
|
||||
target_ino = 1;
|
||||
if (!last_ino)
|
||||
last_ino = 1;
|
||||
add_file(filename, target_ino);
|
||||
pad(erasesize);
|
||||
|
||||
/* add eof marker, pad to eraseblock size and write the data */
|
||||
add_data(JFFS2_EOF, sizeof(JFFS2_EOF) - 1);
|
||||
pad(erasesize);
|
||||
free(buf);
|
||||
|
||||
return (mtdofs - ofs);
|
||||
}
|
||||
|
||||
void mtd_parse_jffs2data(const char *buf, const char *dir)
|
||||
{
|
||||
struct jffs2_unknown_node *node = (struct jffs2_unknown_node *) buf;
|
||||
unsigned int ofs = 0;
|
||||
|
||||
while (ofs < erasesize) {
|
||||
node = (struct jffs2_unknown_node *) (buf + ofs);
|
||||
if (node->magic != 0x1985)
|
||||
break;
|
||||
|
||||
ofs += PAD(node->totlen);
|
||||
if (node->nodetype == JFFS2_NODETYPE_DIRENT) {
|
||||
struct jffs2_raw_dirent *de = (struct jffs2_raw_dirent *) node;
|
||||
|
||||
/* is this the right directory name and is it a subdirectory of / */
|
||||
if (*dir && (de->pino == 1) && !strncmp((char *) de->name, dir, de->nsize))
|
||||
target_ino = de->ino;
|
||||
|
||||
/* store the last inode and version numbers for adding extra files */
|
||||
if (last_ino < de->ino)
|
||||
last_ino = de->ino;
|
||||
if (last_version < de->version)
|
||||
last_version = de->version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int mtd_write_jffs2(const char *mtd, const char *filename, const char *dir)
|
||||
{
|
||||
int err = -1, fdeof = 0;
|
||||
|
||||
outfd = mtd_check_open(mtd);
|
||||
if (outfd < 0)
|
||||
return -1;
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Appending %s to jffs2 partition %s\n", filename, mtd);
|
||||
|
||||
buf = malloc(erasesize);
|
||||
if (!buf) {
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!*dir)
|
||||
target_ino = 1;
|
||||
|
||||
/* parse the structure of the jffs2 first
|
||||
* locate the directory that the file is going to be placed in */
|
||||
for(;;) {
|
||||
struct jffs2_unknown_node *node = (struct jffs2_unknown_node *) buf;
|
||||
|
||||
if (read(outfd, buf, erasesize) != erasesize) {
|
||||
fdeof = 1;
|
||||
break;
|
||||
}
|
||||
mtdofs += erasesize;
|
||||
|
||||
if (node->magic == 0x8519) {
|
||||
fprintf(stderr, "Error: wrong endianness filesystem\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* assume no magic == end of filesystem
|
||||
* the filesystem will probably end with be32(0xdeadc0de) */
|
||||
if (node->magic != 0x1985)
|
||||
break;
|
||||
|
||||
mtd_parse_jffs2data(buf, dir);
|
||||
}
|
||||
|
||||
if (fdeof) {
|
||||
fprintf(stderr, "Error: No room for additional data\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* jump back one eraseblock */
|
||||
mtdofs -= erasesize;
|
||||
lseek(outfd, mtdofs, SEEK_SET);
|
||||
|
||||
ofs = 0;
|
||||
|
||||
if (!last_ino)
|
||||
last_ino = 1;
|
||||
|
||||
if (!target_ino)
|
||||
target_ino = add_dir(dir, 1);
|
||||
|
||||
add_file(filename, target_ino);
|
||||
pad(erasesize);
|
||||
|
||||
/* add eof marker, pad to eraseblock size and write the data */
|
||||
add_data(JFFS2_EOF, sizeof(JFFS2_EOF) - 1);
|
||||
pad(erasesize);
|
||||
|
||||
err = 0;
|
||||
|
||||
if (trx_fixup) {
|
||||
trx_fixup(outfd, mtd);
|
||||
}
|
||||
|
||||
done:
|
||||
close(outfd);
|
||||
if (buf)
|
||||
free(buf);
|
||||
|
||||
return err;
|
||||
}
|
||||
216
package/system/mtd/src/jffs2.h
Normal file
216
package/system/mtd/src/jffs2.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* JFFS2 -- Journalling Flash File System, Version 2.
|
||||
*
|
||||
* Copyright (C) 2001-2003 Red Hat, Inc.
|
||||
*
|
||||
* Created by David Woodhouse <dwmw2@infradead.org>
|
||||
*
|
||||
* For licensing information, see the file 'LICENCE' in the
|
||||
* jffs2 directory.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_JFFS2_H__
|
||||
#define __LINUX_JFFS2_H__
|
||||
|
||||
#define JFFS2_SUPER_MAGIC 0x72b6
|
||||
|
||||
/* You must include something which defines the C99 uintXX_t types.
|
||||
We don't do it from here because this file is used in too many
|
||||
different environments. */
|
||||
|
||||
/* Values we may expect to find in the 'magic' field */
|
||||
#define JFFS2_OLD_MAGIC_BITMASK 0x1984
|
||||
#define JFFS2_MAGIC_BITMASK 0x1985
|
||||
#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */
|
||||
#define JFFS2_EMPTY_BITMASK 0xffff
|
||||
#define JFFS2_DIRTY_BITMASK 0x0000
|
||||
|
||||
/* Summary node MAGIC marker */
|
||||
#define JFFS2_SUM_MAGIC 0x02851885
|
||||
|
||||
/* We only allow a single char for length, and 0xFF is empty flash so
|
||||
we don't want it confused with a real length. Hence max 254.
|
||||
*/
|
||||
#define JFFS2_MAX_NAME_LEN 254
|
||||
|
||||
/* How small can we sensibly write nodes? */
|
||||
#define JFFS2_MIN_DATA_LEN 128
|
||||
|
||||
#define JFFS2_COMPR_NONE 0x00
|
||||
#define JFFS2_COMPR_ZERO 0x01
|
||||
#define JFFS2_COMPR_RTIME 0x02
|
||||
#define JFFS2_COMPR_RUBINMIPS 0x03
|
||||
#define JFFS2_COMPR_COPY 0x04
|
||||
#define JFFS2_COMPR_DYNRUBIN 0x05
|
||||
#define JFFS2_COMPR_ZLIB 0x06
|
||||
/* Compatibility flags. */
|
||||
#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
|
||||
#define JFFS2_NODE_ACCURATE 0x2000
|
||||
/* INCOMPAT: Fail to mount the filesystem */
|
||||
#define JFFS2_FEATURE_INCOMPAT 0xc000
|
||||
/* ROCOMPAT: Mount read-only */
|
||||
#define JFFS2_FEATURE_ROCOMPAT 0x8000
|
||||
/* RWCOMPAT_COPY: Mount read/write, and copy the node when it's GC'd */
|
||||
#define JFFS2_FEATURE_RWCOMPAT_COPY 0x4000
|
||||
/* RWCOMPAT_DELETE: Mount read/write, and delete the node when it's GC'd */
|
||||
#define JFFS2_FEATURE_RWCOMPAT_DELETE 0x0000
|
||||
|
||||
#define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1)
|
||||
#define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2)
|
||||
#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
|
||||
#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)
|
||||
|
||||
#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6)
|
||||
|
||||
#define JFFS2_NODETYPE_XATTR (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 8)
|
||||
#define JFFS2_NODETYPE_XREF (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 9)
|
||||
|
||||
/* XATTR Related */
|
||||
#define JFFS2_XPREFIX_USER 1 /* for "user." */
|
||||
#define JFFS2_XPREFIX_SECURITY 2 /* for "security." */
|
||||
#define JFFS2_XPREFIX_ACL_ACCESS 3 /* for "system.posix_acl_access" */
|
||||
#define JFFS2_XPREFIX_ACL_DEFAULT 4 /* for "system.posix_acl_default" */
|
||||
#define JFFS2_XPREFIX_TRUSTED 5 /* for "trusted.*" */
|
||||
|
||||
#define JFFS2_ACL_VERSION 0x0001
|
||||
|
||||
// Maybe later...
|
||||
//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
|
||||
//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
|
||||
|
||||
|
||||
#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
|
||||
mount time, don't wait for it to
|
||||
happen later */
|
||||
#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific
|
||||
compression type */
|
||||
|
||||
|
||||
/* These can go once we've made sure we've caught all uses without
|
||||
byteswapping */
|
||||
|
||||
typedef uint32_t jint32_t;
|
||||
|
||||
typedef uint32_t jmode_t;
|
||||
|
||||
typedef uint16_t jint16_t;
|
||||
|
||||
struct jffs2_unknown_node
|
||||
{
|
||||
/* All start like this */
|
||||
jint16_t magic;
|
||||
jint16_t nodetype;
|
||||
jint32_t totlen; /* So we can skip over nodes we don't grok */
|
||||
jint32_t hdr_crc;
|
||||
};
|
||||
|
||||
struct jffs2_raw_dirent
|
||||
{
|
||||
jint16_t magic;
|
||||
jint16_t nodetype; /* == JFFS2_NODETYPE_DIRENT */
|
||||
jint32_t totlen;
|
||||
jint32_t hdr_crc;
|
||||
jint32_t pino;
|
||||
jint32_t version;
|
||||
jint32_t ino; /* == zero for unlink */
|
||||
jint32_t mctime;
|
||||
uint8_t nsize;
|
||||
uint8_t type;
|
||||
uint8_t unused[2];
|
||||
jint32_t node_crc;
|
||||
jint32_t name_crc;
|
||||
uint8_t name[0];
|
||||
};
|
||||
|
||||
/* The JFFS2 raw inode structure: Used for storage on physical media. */
|
||||
/* The uid, gid, atime, mtime and ctime members could be longer, but
|
||||
are left like this for space efficiency. If and when people decide
|
||||
they really need them extended, it's simple enough to add support for
|
||||
a new type of raw node.
|
||||
*/
|
||||
struct jffs2_raw_inode
|
||||
{
|
||||
jint16_t magic; /* A constant magic number. */
|
||||
jint16_t nodetype; /* == JFFS2_NODETYPE_INODE */
|
||||
jint32_t totlen; /* Total length of this node (inc data, etc.) */
|
||||
jint32_t hdr_crc;
|
||||
jint32_t ino; /* Inode number. */
|
||||
jint32_t version; /* Version number. */
|
||||
jmode_t mode; /* The file's type or mode. */
|
||||
jint16_t uid; /* The file's owner. */
|
||||
jint16_t gid; /* The file's group. */
|
||||
jint32_t isize; /* Total resultant size of this inode (used for truncations) */
|
||||
jint32_t atime; /* Last access time. */
|
||||
jint32_t mtime; /* Last modification time. */
|
||||
jint32_t ctime; /* Change time. */
|
||||
jint32_t offset; /* Where to begin to write. */
|
||||
jint32_t csize; /* (Compressed) data size */
|
||||
jint32_t dsize; /* Size of the node's data. (after decompression) */
|
||||
uint8_t compr; /* Compression algorithm used */
|
||||
uint8_t usercompr; /* Compression algorithm requested by the user */
|
||||
jint16_t flags; /* See JFFS2_INO_FLAG_* */
|
||||
jint32_t data_crc; /* CRC for the (compressed) data. */
|
||||
jint32_t node_crc; /* CRC for the raw inode (excluding data) */
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
struct jffs2_raw_xattr {
|
||||
jint16_t magic;
|
||||
jint16_t nodetype; /* = JFFS2_NODETYPE_XATTR */
|
||||
jint32_t totlen;
|
||||
jint32_t hdr_crc;
|
||||
jint32_t xid; /* XATTR identifier number */
|
||||
jint32_t version;
|
||||
uint8_t xprefix;
|
||||
uint8_t name_len;
|
||||
jint16_t value_len;
|
||||
jint32_t data_crc;
|
||||
jint32_t node_crc;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct jffs2_raw_xref
|
||||
{
|
||||
jint16_t magic;
|
||||
jint16_t nodetype; /* = JFFS2_NODETYPE_XREF */
|
||||
jint32_t totlen;
|
||||
jint32_t hdr_crc;
|
||||
jint32_t ino; /* inode number */
|
||||
jint32_t xid; /* XATTR identifier number */
|
||||
jint32_t xseqno; /* xref sequencial number */
|
||||
jint32_t node_crc;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct jffs2_raw_summary
|
||||
{
|
||||
jint16_t magic;
|
||||
jint16_t nodetype; /* = JFFS2_NODETYPE_SUMMARY */
|
||||
jint32_t totlen;
|
||||
jint32_t hdr_crc;
|
||||
jint32_t sum_num; /* number of sum entries*/
|
||||
jint32_t cln_mkr; /* clean marker size, 0 = no cleanmarker */
|
||||
jint32_t padded; /* sum of the size of padding nodes */
|
||||
jint32_t sum_crc; /* summary information crc */
|
||||
jint32_t node_crc; /* node crc */
|
||||
jint32_t sum[0]; /* inode summary info */
|
||||
};
|
||||
|
||||
union jffs2_node_union
|
||||
{
|
||||
struct jffs2_raw_inode i;
|
||||
struct jffs2_raw_dirent d;
|
||||
struct jffs2_raw_xattr x;
|
||||
struct jffs2_raw_xref r;
|
||||
struct jffs2_raw_summary s;
|
||||
struct jffs2_unknown_node u;
|
||||
};
|
||||
|
||||
/* Data payload for device nodes. */
|
||||
union jffs2_device_node {
|
||||
jint16_t old;
|
||||
jint32_t new;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_JFFS2_H__ */
|
||||
187
package/system/mtd/src/linksys_bootcount.c
Normal file
187
package/system/mtd/src/linksys_bootcount.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Linksys boot counter reset code for mtd
|
||||
*
|
||||
* Copyright (C) 2013 Jonas Gorski <jogo@openwrt.org>
|
||||
* Portions Copyright (c) 2019, Jeff Kletsky
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License v2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <endian.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
|
||||
#include "mtd.h"
|
||||
|
||||
#define BOOTCOUNT_MAGIC 0x20110811
|
||||
|
||||
/*
|
||||
* EA6350v3, and potentially other NOR-boot devices,
|
||||
* use an offset increment of 16 between records,
|
||||
* not mtd_info_user.writesize (often 1 on NOR devices).
|
||||
*/
|
||||
|
||||
#define BC_OFFSET_INCREMENT_MIN 16
|
||||
|
||||
|
||||
|
||||
#define DLOG_OPEN()
|
||||
|
||||
#define DLOG_ERR(...) do { \
|
||||
fprintf(stderr, "ERROR: " __VA_ARGS__); fprintf(stderr, "\n"); \
|
||||
} while (0)
|
||||
|
||||
#define DLOG_NOTICE(...) do { \
|
||||
fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); \
|
||||
} while (0)
|
||||
|
||||
#define DLOG_DEBUG(...)
|
||||
|
||||
|
||||
|
||||
struct bootcounter {
|
||||
uint32_t magic;
|
||||
uint32_t count;
|
||||
uint32_t checksum;
|
||||
};
|
||||
|
||||
static char page[2048];
|
||||
|
||||
int mtd_resetbc(const char *mtd)
|
||||
{
|
||||
struct mtd_info_user mtd_info;
|
||||
struct bootcounter *curr = (struct bootcounter *)page;
|
||||
unsigned int i;
|
||||
unsigned int bc_offset_increment;
|
||||
int last_count = 0;
|
||||
int num_bc;
|
||||
int fd;
|
||||
int ret;
|
||||
int retval = 0;
|
||||
|
||||
DLOG_OPEN();
|
||||
|
||||
fd = mtd_check_open(mtd);
|
||||
|
||||
if (ioctl(fd, MEMGETINFO, &mtd_info) < 0) {
|
||||
DLOG_ERR("Unable to obtain mtd_info for given partition name.");
|
||||
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
/* Detect need to override increment (for EA6350v3) */
|
||||
|
||||
if (mtd_info.writesize < BC_OFFSET_INCREMENT_MIN) {
|
||||
|
||||
bc_offset_increment = BC_OFFSET_INCREMENT_MIN;
|
||||
DLOG_DEBUG("Offset increment set to %i for writesize of %i",
|
||||
bc_offset_increment, mtd_info.writesize);
|
||||
} else {
|
||||
|
||||
bc_offset_increment = mtd_info.writesize;
|
||||
}
|
||||
|
||||
num_bc = mtd_info.size / bc_offset_increment;
|
||||
|
||||
for (i = 0; i < num_bc; i++) {
|
||||
pread(fd, curr, sizeof(*curr), i * bc_offset_increment);
|
||||
|
||||
/* Existing code assumes erase is to 0xff; left as-is (2019) */
|
||||
|
||||
if (curr->magic != BOOTCOUNT_MAGIC &&
|
||||
curr->magic != 0xffffffff) {
|
||||
DLOG_ERR("Unexpected magic %08x at offset %08x; aborting.",
|
||||
curr->magic, i * bc_offset_increment);
|
||||
|
||||
retval = -2;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (curr->magic == 0xffffffff)
|
||||
break;
|
||||
|
||||
last_count = curr->count;
|
||||
}
|
||||
|
||||
|
||||
if (last_count == 0) { /* bootcount is already 0 */
|
||||
|
||||
retval = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
if (i == num_bc) {
|
||||
DLOG_NOTICE("Boot-count log full with %i entries; erasing (expected occasionally).",
|
||||
i);
|
||||
|
||||
struct erase_info_user erase_info;
|
||||
erase_info.start = 0;
|
||||
erase_info.length = mtd_info.size;
|
||||
|
||||
ret = ioctl(fd, MEMERASE, &erase_info);
|
||||
if (ret < 0) {
|
||||
DLOG_ERR("Failed to erase boot-count log MTD; ioctl() MEMERASE returned %i",
|
||||
ret);
|
||||
|
||||
retval = -3;
|
||||
goto out;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
}
|
||||
|
||||
memset(curr, 0xff, bc_offset_increment);
|
||||
|
||||
curr->magic = BOOTCOUNT_MAGIC;
|
||||
curr->count = 0;
|
||||
curr->checksum = BOOTCOUNT_MAGIC;
|
||||
|
||||
/* Assumes bc_offset_increment is a multiple of mtd_info.writesize */
|
||||
|
||||
ret = pwrite(fd, curr, bc_offset_increment, i * bc_offset_increment);
|
||||
if (ret < 0) {
|
||||
DLOG_ERR("Failed to write boot-count log entry; pwrite() returned %i",
|
||||
errno);
|
||||
retval = -4;
|
||||
goto out;
|
||||
|
||||
} else {
|
||||
sync();
|
||||
|
||||
DLOG_NOTICE("Boot count sucessfully reset to zero.");
|
||||
|
||||
retval = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
close(fd);
|
||||
return retval;
|
||||
}
|
||||
307
package/system/mtd/src/md5.c
Normal file
307
package/system/mtd/src/md5.c
Normal file
@@ -0,0 +1,307 @@
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** md5.c -- the source code for MD5 routines **
|
||||
** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
|
||||
** Created: 2/17/90 RLR **
|
||||
** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
|
||||
** **
|
||||
** License to copy and use this software is granted provided that **
|
||||
** it is identified as the "RSA Data Security, Inc. MD5 Message- **
|
||||
** Digest Algorithm" in all material mentioning or referencing this **
|
||||
** software or this function. **
|
||||
** **
|
||||
** License is also granted to make and use derivative works **
|
||||
** provided that such works are identified as "derived from the RSA **
|
||||
** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
|
||||
** material mentioning or referencing the derived work. **
|
||||
** **
|
||||
** RSA Data Security, Inc. makes no representations concerning **
|
||||
** either the merchantability of this software or the suitability **
|
||||
** of this software for any particular purpose. It is provided "as **
|
||||
** is" without express or implied warranty of any kind. **
|
||||
** **
|
||||
** These notices must be retained in any copies of any part of this **
|
||||
** documentation and/or software. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "md5.h"
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Message-digest routines: **
|
||||
** To form the message digest for a message M **
|
||||
** (1) Initialize a context buffer mdContext using MD5_Init **
|
||||
** (2) Call MD5_Update on mdContext and M **
|
||||
** (3) Call MD5_Final on mdContext **
|
||||
** The message digest is now in mdContext->digest[0...15] **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/* forward declaration */
|
||||
static void Transform ();
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* F, G, H and I are basic MD5 functions */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
#define FF(a, b, c, d, x, s, ac) \
|
||||
{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) \
|
||||
{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) \
|
||||
{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) \
|
||||
{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
#ifdef __STDC__
|
||||
#define UL(x) x##U
|
||||
#else
|
||||
#define UL(x) x
|
||||
#endif
|
||||
|
||||
/* The routine MD5_Init initializes the message-digest context
|
||||
mdContext. All fields are set to zero.
|
||||
*/
|
||||
void MD5_Init (mdContext)
|
||||
MD5_CTX *mdContext;
|
||||
{
|
||||
mdContext->i[0] = mdContext->i[1] = (UINT4)0;
|
||||
|
||||
/* Load magic initialization constants.
|
||||
*/
|
||||
mdContext->buf[0] = (UINT4)0x67452301;
|
||||
mdContext->buf[1] = (UINT4)0xefcdab89;
|
||||
mdContext->buf[2] = (UINT4)0x98badcfe;
|
||||
mdContext->buf[3] = (UINT4)0x10325476;
|
||||
}
|
||||
|
||||
/* The routine MD5Update updates the message-digest context to
|
||||
account for the presence of each of the characters inBuf[0..inLen-1]
|
||||
in the message whose digest is being computed.
|
||||
*/
|
||||
void MD5_Update (mdContext, inBuf, inLen)
|
||||
MD5_CTX *mdContext;
|
||||
unsigned char *inBuf;
|
||||
unsigned int inLen;
|
||||
{
|
||||
UINT4 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
|
||||
|
||||
/* update number of bits */
|
||||
if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
|
||||
mdContext->i[1]++;
|
||||
mdContext->i[0] += ((UINT4)inLen << 3);
|
||||
mdContext->i[1] += ((UINT4)inLen >> 29);
|
||||
|
||||
while (inLen--) {
|
||||
/* add new character to buffer, increment mdi */
|
||||
mdContext->in[mdi++] = *inBuf++;
|
||||
|
||||
/* transform if necessary */
|
||||
if (mdi == 0x40) {
|
||||
for (i = 0, ii = 0; i < 16; i++, ii += 4)
|
||||
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
|
||||
(((UINT4)mdContext->in[ii+2]) << 16) |
|
||||
(((UINT4)mdContext->in[ii+1]) << 8) |
|
||||
((UINT4)mdContext->in[ii]);
|
||||
Transform (mdContext->buf, in);
|
||||
mdi = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The routine MD5Final terminates the message-digest computation and
|
||||
ends with the desired message digest in mdContext->digest[0...15].
|
||||
*/
|
||||
void MD5_Final (hash, mdContext)
|
||||
unsigned char hash[];
|
||||
MD5_CTX *mdContext;
|
||||
{
|
||||
UINT4 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
unsigned int padLen;
|
||||
|
||||
/* save number of bits */
|
||||
in[14] = mdContext->i[0];
|
||||
in[15] = mdContext->i[1];
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
|
||||
|
||||
/* pad out to 56 mod 64 */
|
||||
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
|
||||
MD5_Update (mdContext, PADDING, padLen);
|
||||
|
||||
/* append length in bits and transform */
|
||||
for (i = 0, ii = 0; i < 14; i++, ii += 4)
|
||||
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
|
||||
(((UINT4)mdContext->in[ii+2]) << 16) |
|
||||
(((UINT4)mdContext->in[ii+1]) << 8) |
|
||||
((UINT4)mdContext->in[ii]);
|
||||
Transform (mdContext->buf, in);
|
||||
|
||||
/* store buffer in digest */
|
||||
for (i = 0, ii = 0; i < 4; i++, ii += 4) {
|
||||
mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
|
||||
mdContext->digest[ii+1] =
|
||||
(unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
|
||||
mdContext->digest[ii+2] =
|
||||
(unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
|
||||
mdContext->digest[ii+3] =
|
||||
(unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
|
||||
}
|
||||
memcpy(hash, mdContext->digest, 16);
|
||||
}
|
||||
|
||||
/* Basic MD5 step. Transforms buf based on in.
|
||||
*/
|
||||
static void Transform (buf, in)
|
||||
UINT4 *buf;
|
||||
UINT4 *in;
|
||||
{
|
||||
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
|
||||
|
||||
/* Round 1 */
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
FF ( a, b, c, d, in[ 0], S11, UL(3614090360)); /* 1 */
|
||||
FF ( d, a, b, c, in[ 1], S12, UL(3905402710)); /* 2 */
|
||||
FF ( c, d, a, b, in[ 2], S13, UL( 606105819)); /* 3 */
|
||||
FF ( b, c, d, a, in[ 3], S14, UL(3250441966)); /* 4 */
|
||||
FF ( a, b, c, d, in[ 4], S11, UL(4118548399)); /* 5 */
|
||||
FF ( d, a, b, c, in[ 5], S12, UL(1200080426)); /* 6 */
|
||||
FF ( c, d, a, b, in[ 6], S13, UL(2821735955)); /* 7 */
|
||||
FF ( b, c, d, a, in[ 7], S14, UL(4249261313)); /* 8 */
|
||||
FF ( a, b, c, d, in[ 8], S11, UL(1770035416)); /* 9 */
|
||||
FF ( d, a, b, c, in[ 9], S12, UL(2336552879)); /* 10 */
|
||||
FF ( c, d, a, b, in[10], S13, UL(4294925233)); /* 11 */
|
||||
FF ( b, c, d, a, in[11], S14, UL(2304563134)); /* 12 */
|
||||
FF ( a, b, c, d, in[12], S11, UL(1804603682)); /* 13 */
|
||||
FF ( d, a, b, c, in[13], S12, UL(4254626195)); /* 14 */
|
||||
FF ( c, d, a, b, in[14], S13, UL(2792965006)); /* 15 */
|
||||
FF ( b, c, d, a, in[15], S14, UL(1236535329)); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
GG ( a, b, c, d, in[ 1], S21, UL(4129170786)); /* 17 */
|
||||
GG ( d, a, b, c, in[ 6], S22, UL(3225465664)); /* 18 */
|
||||
GG ( c, d, a, b, in[11], S23, UL( 643717713)); /* 19 */
|
||||
GG ( b, c, d, a, in[ 0], S24, UL(3921069994)); /* 20 */
|
||||
GG ( a, b, c, d, in[ 5], S21, UL(3593408605)); /* 21 */
|
||||
GG ( d, a, b, c, in[10], S22, UL( 38016083)); /* 22 */
|
||||
GG ( c, d, a, b, in[15], S23, UL(3634488961)); /* 23 */
|
||||
GG ( b, c, d, a, in[ 4], S24, UL(3889429448)); /* 24 */
|
||||
GG ( a, b, c, d, in[ 9], S21, UL( 568446438)); /* 25 */
|
||||
GG ( d, a, b, c, in[14], S22, UL(3275163606)); /* 26 */
|
||||
GG ( c, d, a, b, in[ 3], S23, UL(4107603335)); /* 27 */
|
||||
GG ( b, c, d, a, in[ 8], S24, UL(1163531501)); /* 28 */
|
||||
GG ( a, b, c, d, in[13], S21, UL(2850285829)); /* 29 */
|
||||
GG ( d, a, b, c, in[ 2], S22, UL(4243563512)); /* 30 */
|
||||
GG ( c, d, a, b, in[ 7], S23, UL(1735328473)); /* 31 */
|
||||
GG ( b, c, d, a, in[12], S24, UL(2368359562)); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
HH ( a, b, c, d, in[ 5], S31, UL(4294588738)); /* 33 */
|
||||
HH ( d, a, b, c, in[ 8], S32, UL(2272392833)); /* 34 */
|
||||
HH ( c, d, a, b, in[11], S33, UL(1839030562)); /* 35 */
|
||||
HH ( b, c, d, a, in[14], S34, UL(4259657740)); /* 36 */
|
||||
HH ( a, b, c, d, in[ 1], S31, UL(2763975236)); /* 37 */
|
||||
HH ( d, a, b, c, in[ 4], S32, UL(1272893353)); /* 38 */
|
||||
HH ( c, d, a, b, in[ 7], S33, UL(4139469664)); /* 39 */
|
||||
HH ( b, c, d, a, in[10], S34, UL(3200236656)); /* 40 */
|
||||
HH ( a, b, c, d, in[13], S31, UL( 681279174)); /* 41 */
|
||||
HH ( d, a, b, c, in[ 0], S32, UL(3936430074)); /* 42 */
|
||||
HH ( c, d, a, b, in[ 3], S33, UL(3572445317)); /* 43 */
|
||||
HH ( b, c, d, a, in[ 6], S34, UL( 76029189)); /* 44 */
|
||||
HH ( a, b, c, d, in[ 9], S31, UL(3654602809)); /* 45 */
|
||||
HH ( d, a, b, c, in[12], S32, UL(3873151461)); /* 46 */
|
||||
HH ( c, d, a, b, in[15], S33, UL( 530742520)); /* 47 */
|
||||
HH ( b, c, d, a, in[ 2], S34, UL(3299628645)); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
II ( a, b, c, d, in[ 0], S41, UL(4096336452)); /* 49 */
|
||||
II ( d, a, b, c, in[ 7], S42, UL(1126891415)); /* 50 */
|
||||
II ( c, d, a, b, in[14], S43, UL(2878612391)); /* 51 */
|
||||
II ( b, c, d, a, in[ 5], S44, UL(4237533241)); /* 52 */
|
||||
II ( a, b, c, d, in[12], S41, UL(1700485571)); /* 53 */
|
||||
II ( d, a, b, c, in[ 3], S42, UL(2399980690)); /* 54 */
|
||||
II ( c, d, a, b, in[10], S43, UL(4293915773)); /* 55 */
|
||||
II ( b, c, d, a, in[ 1], S44, UL(2240044497)); /* 56 */
|
||||
II ( a, b, c, d, in[ 8], S41, UL(1873313359)); /* 57 */
|
||||
II ( d, a, b, c, in[15], S42, UL(4264355552)); /* 58 */
|
||||
II ( c, d, a, b, in[ 6], S43, UL(2734768916)); /* 59 */
|
||||
II ( b, c, d, a, in[13], S44, UL(1309151649)); /* 60 */
|
||||
II ( a, b, c, d, in[ 4], S41, UL(4149444226)); /* 61 */
|
||||
II ( d, a, b, c, in[11], S42, UL(3174756917)); /* 62 */
|
||||
II ( c, d, a, b, in[ 2], S43, UL( 718787259)); /* 63 */
|
||||
II ( b, c, d, a, in[ 9], S44, UL(3951481745)); /* 64 */
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** End of md5.c **
|
||||
******************************** (cut) ********************************
|
||||
*/
|
||||
65
package/system/mtd/src/md5.h
Normal file
65
package/system/mtd/src/md5.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
***********************************************************************
|
||||
** md5.h -- header file for implementation of MD5 **
|
||||
** RSA Data Security, Inc. MD5 Message-Digest Algorithm **
|
||||
** Created: 2/17/90 RLR **
|
||||
** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version **
|
||||
** Revised (for MD5): RLR 4/27/91 **
|
||||
** -- G modified to have y&~z instead of y&z **
|
||||
** -- FF, GG, HH modified to add in last register done **
|
||||
** -- Access pattern: round 2 works mod 5, round 3 works mod 3 **
|
||||
** -- distinct additive constant for each step **
|
||||
** -- round 4 added, working mod 7 **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
|
||||
** **
|
||||
** License to copy and use this software is granted provided that **
|
||||
** it is identified as the "RSA Data Security, Inc. MD5 Message- **
|
||||
** Digest Algorithm" in all material mentioning or referencing this **
|
||||
** software or this function. **
|
||||
** **
|
||||
** License is also granted to make and use derivative works **
|
||||
** provided that such works are identified as "derived from the RSA **
|
||||
** Data Security, Inc. MD5 Message-Digest Algorithm" in all **
|
||||
** material mentioning or referencing the derived work. **
|
||||
** **
|
||||
** RSA Data Security, Inc. makes no representations concerning **
|
||||
** either the merchantability of this software or the suitability **
|
||||
** of this software for any particular purpose. It is provided "as **
|
||||
** is" without express or implied warranty of any kind. **
|
||||
** **
|
||||
** These notices must be retained in any copies of any part of this **
|
||||
** documentation and/or software. **
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __MD5_INCLUDE__
|
||||
|
||||
/* typedef a 32-bit type */
|
||||
#ifdef _LP64
|
||||
typedef unsigned int UINT4;
|
||||
typedef int INT4;
|
||||
#else
|
||||
typedef unsigned long UINT4;
|
||||
typedef long INT4;
|
||||
#endif
|
||||
#define _UINT4_T
|
||||
|
||||
/* Data structure for MD5 (Message-Digest) computation */
|
||||
typedef struct {
|
||||
UINT4 i[2]; /* number of _bits_ handled mod 2^64 */
|
||||
UINT4 buf[4]; /* scratch buffer */
|
||||
unsigned char in[64]; /* input buffer */
|
||||
unsigned char digest[16]; /* actual digest after MD5Final call */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5_Init ();
|
||||
void MD5_Update ();
|
||||
void MD5_Final ();
|
||||
|
||||
#define __MD5_INCLUDE__
|
||||
#endif /* __MD5_INCLUDE__ */
|
||||
1109
package/system/mtd/src/mtd.c
Normal file
1109
package/system/mtd/src/mtd.c
Normal file
File diff suppressed because it is too large
Load Diff
36
package/system/mtd/src/mtd.h
Normal file
36
package/system/mtd/src/mtd.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef __mtd_h
|
||||
#define __mtd_h
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(target_bcm47xx) || defined(target_bcm53xx)
|
||||
#define target_brcm 1
|
||||
#endif
|
||||
|
||||
#define JFFS2_EOF "\xde\xad\xc0\xde"
|
||||
|
||||
extern int quiet;
|
||||
extern int mtdsize;
|
||||
extern int erasesize;
|
||||
extern uint32_t opt_trxmagic;
|
||||
|
||||
extern int mtd_open(const char *mtd, bool block);
|
||||
extern int mtd_check_open(const char *mtd);
|
||||
extern int mtd_block_is_bad(int fd, int offset);
|
||||
extern int mtd_erase_block(int fd, int offset);
|
||||
extern int mtd_write_buffer(int fd, const char *buf, int offset, int length);
|
||||
extern int mtd_write_jffs2(const char *mtd, const char *filename, const char *dir);
|
||||
extern int mtd_replace_jffs2(const char *mtd, int fd, int ofs, const char *filename);
|
||||
extern void mtd_parse_jffs2data(const char *buf, const char *dir);
|
||||
|
||||
/* target specific functions */
|
||||
extern int trx_fixup(int fd, const char *name) __attribute__ ((weak));
|
||||
extern int trx_check(int imagefd, const char *mtd, char *buf, int *len) __attribute__ ((weak));
|
||||
extern int mtd_fixtrx(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak));
|
||||
extern int mtd_fixseama(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak));
|
||||
extern int mtd_fixwrg(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak));
|
||||
extern int mtd_fixwrgg(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak));
|
||||
extern int mtd_resetbc(const char *mtd) __attribute__ ((weak));
|
||||
extern int mtd_tpl_recoverflag_write(const char *mtd, const bool recovery_active) __attribute__ ((weak));
|
||||
#endif /* __mtd_h */
|
||||
188
package/system/mtd/src/seama.c
Normal file
188
package/system/mtd/src/seama.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* seama.c
|
||||
*
|
||||
* Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
|
||||
*
|
||||
* Based on the trx fixup code:
|
||||
* Copyright (C) 2005 Mike Baker
|
||||
* Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
#include "mtd.h"
|
||||
#include "seama.h"
|
||||
#include "md5.h"
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define STORE32_LE(X) (X)
|
||||
#else
|
||||
#error unknown endianness!
|
||||
#endif
|
||||
|
||||
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
|
||||
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
|
||||
|
||||
int
|
||||
seama_fix_md5(struct seama_entity_header *shdr, int fd, size_t data_offset, size_t data_size)
|
||||
{
|
||||
char *buf;
|
||||
ssize_t res;
|
||||
MD5_CTX ctx;
|
||||
unsigned char digest[16];
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
buf = malloc(data_size);
|
||||
if (!buf) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
res = pread(fd, buf, data_size, data_offset);
|
||||
if (res != data_size) {
|
||||
perror("pread");
|
||||
err = -EIO;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, buf, data_size);
|
||||
MD5_Final(digest, &ctx);
|
||||
|
||||
if (!memcmp(digest, shdr->md5, sizeof(digest))) {
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "the header is fixed already\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "new size:%u, new MD5: ", data_size);
|
||||
for (i = 0; i < sizeof(digest); i++)
|
||||
fprintf(stderr, "%02x", digest[i]);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/* update the size in the image */
|
||||
shdr->size = htonl(data_size);
|
||||
|
||||
/* update the checksum in the image */
|
||||
memcpy(shdr->md5, digest, sizeof(digest));
|
||||
|
||||
err_free:
|
||||
free(buf);
|
||||
err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
mtd_fixseama(const char *mtd, size_t offset, size_t data_size)
|
||||
{
|
||||
int fd;
|
||||
char *first_block;
|
||||
ssize_t res;
|
||||
size_t block_offset;
|
||||
size_t data_offset;
|
||||
struct seama_entity_header *shdr;
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Trying to fix SEAMA header in %s at 0x%x...\n",
|
||||
mtd, offset);
|
||||
|
||||
block_offset = offset & ~(erasesize - 1);
|
||||
offset -= block_offset;
|
||||
|
||||
fd = mtd_check_open(mtd);
|
||||
if(fd < 0) {
|
||||
fprintf(stderr, "Could not open mtd device: %s\n", mtd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (block_offset + erasesize > mtdsize) {
|
||||
fprintf(stderr, "Offset too large, device size 0x%x\n",
|
||||
mtdsize);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
first_block = malloc(erasesize);
|
||||
if (!first_block) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
res = pread(fd, first_block, erasesize, block_offset);
|
||||
if (res != erasesize) {
|
||||
perror("pread");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
shdr = (struct seama_entity_header *)(first_block + offset);
|
||||
if (shdr->magic != htonl(SEAMA_MAGIC)) {
|
||||
fprintf(stderr, "No SEAMA header found\n");
|
||||
exit(1);
|
||||
} else if (!ntohl(shdr->size)) {
|
||||
fprintf(stderr, "Seama entity with empty image\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
data_offset = offset + sizeof(struct seama_entity_header) + ntohs(shdr->metasize);
|
||||
if (!data_size)
|
||||
data_size = mtdsize - data_offset;
|
||||
if (data_size > ntohl(shdr->size))
|
||||
data_size = ntohl(shdr->size);
|
||||
if (seama_fix_md5(shdr, fd, data_offset, data_size))
|
||||
goto out;
|
||||
|
||||
if (mtd_erase_block(fd, block_offset)) {
|
||||
fprintf(stderr, "Can't erease block at 0x%x (%s)\n",
|
||||
block_offset, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Rewriting block at 0x%x\n", block_offset);
|
||||
|
||||
if (pwrite(fd, first_block, erasesize, block_offset) != erasesize) {
|
||||
fprintf(stderr, "Error writing block (%s)\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Done.\n");
|
||||
|
||||
out:
|
||||
close (fd);
|
||||
sync();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
108
package/system/mtd/src/seama.h
Normal file
108
package/system/mtd/src/seama.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* (SEA)ttle i(MA)ge is the image which used in project seattle.
|
||||
*
|
||||
* Created by David Hsieh <david_hsieh@alphanetworks.com>
|
||||
* Copyright (C) 2008-2009 Alpha Networks, Inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either'
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* The GNU C Library is distributed in the hope that it will be useful,'
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with the GNU C Library; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#ifndef __SEAMA_HEADER_FILE__
|
||||
#define __SEAMA_HEADER_FILE__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SEAMA_MAGIC 0x5EA3A417
|
||||
|
||||
/*
|
||||
* SEAMA looks like the following map.
|
||||
* All the data of the header should be in network byte order.
|
||||
*
|
||||
* +-------------+-------------+------------
|
||||
* | SEAMA magic | ^
|
||||
* +-------------+-------------+ |
|
||||
* | reserved | meta size | |
|
||||
* +-------------+-------------+ header
|
||||
* | image size (0 bytes) | |
|
||||
* +-------------+-------------+ |
|
||||
* ~ Meta data ~ v
|
||||
* +-------------+-------------+------------
|
||||
* | SEAMA magic | ^ ^
|
||||
* +-------------+-------------+ | |
|
||||
* | reserved | meta size | | |
|
||||
* +-------------+-------------+ | |
|
||||
* | image size | | |
|
||||
* +-------------+-------------+ header |
|
||||
* | | | |
|
||||
* | 16 bytes of MD5 digest | | |
|
||||
* | | | |
|
||||
* | | | |
|
||||
* +-------------+-------------+ | |
|
||||
* ~ Meta data ~ v |
|
||||
* +-------------+-------------+------- |
|
||||
* | | |
|
||||
* | Image of the 1st entity | |
|
||||
* ~ ~ 1st entity
|
||||
* | | |
|
||||
* | | v
|
||||
* +-------------+-------------+-------------
|
||||
* | SEAMA magic | ^ ^
|
||||
* +-------------+-------------+ | |
|
||||
* | reserved | meta size | | |
|
||||
* +-------------+-------------+ | |
|
||||
* | image size | | |
|
||||
* +-------------+-------------+ header |
|
||||
* | | | |
|
||||
* | 16 bytes of MD5 digest | | |
|
||||
* | | | |
|
||||
* | | | |
|
||||
* +-------------+-------------+ | |
|
||||
* ~ Meta data ~ v |
|
||||
* +-------------+-------------+------- |
|
||||
* | | |
|
||||
* | Image of the 2nd entity | |
|
||||
* ~ ~ 2nd entity
|
||||
* | | |
|
||||
* | | v
|
||||
* +-------------+-------------+-------------
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* SEAMA header
|
||||
*
|
||||
* |<-------- 32 bits -------->|
|
||||
* +-------------+-------------+
|
||||
* | SEAMA magic |
|
||||
* +-------------+-------------+
|
||||
* | reserved | meta size |
|
||||
* +-------------+-------------+
|
||||
* | image size |
|
||||
* +-------------+-------------+
|
||||
*/
|
||||
|
||||
/* seama header */
|
||||
struct seama_entity_header {
|
||||
uint32_t magic; /* should always be SEAMA_MAGIC. */
|
||||
uint16_t reserved; /* reserved for */
|
||||
uint16_t metasize; /* size of the META data */
|
||||
uint32_t size; /* size of the image */
|
||||
uint8_t md5[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
#endif
|
||||
94
package/system/mtd/src/tpl_ramips_recoveryflag.c
Normal file
94
package/system/mtd/src/tpl_ramips_recoveryflag.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* TP-Link recovery flag set and unset code for ramips target
|
||||
*
|
||||
* Copyright (C) 2018 David Bauer <mail@david-bauer.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License v2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <mtd/mtd-user.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "mtd.h"
|
||||
|
||||
|
||||
#define TPL_RECOVER_MAGIC 0x89abcdef
|
||||
#define TPL_NO_RECOVER_MAGIC 0x00000000
|
||||
|
||||
|
||||
struct uboot_args {
|
||||
uint32_t magic;
|
||||
};
|
||||
|
||||
int mtd_tpl_recoverflag_write(const char *mtd, const bool recovery_active)
|
||||
{
|
||||
struct erase_info_user erase_info;
|
||||
struct uboot_args *args;
|
||||
uint32_t magic;
|
||||
int ret = 0;
|
||||
int fd;
|
||||
|
||||
args = malloc(erasesize);
|
||||
if (!args) {
|
||||
fprintf(stderr, "Could not allocate memory!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = mtd_check_open(mtd);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Could not open mtd device: %s\n", mtd);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* read first block (containing the magic) */
|
||||
pread(fd, args, erasesize, 0);
|
||||
|
||||
/* set magic to desired value */
|
||||
magic = TPL_RECOVER_MAGIC;
|
||||
if (!recovery_active)
|
||||
magic = TPL_NO_RECOVER_MAGIC;
|
||||
|
||||
/* no need to write when magic is already set correctly */
|
||||
if (magic == args->magic)
|
||||
goto out;
|
||||
|
||||
/* erase first block (containing the magic) */
|
||||
erase_info.start = 0;
|
||||
erase_info.length = erasesize;
|
||||
|
||||
ret = ioctl(fd, MEMERASE, &erase_info);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to erase block: %i\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* write magic to flash */
|
||||
args->magic = magic;
|
||||
|
||||
ret = pwrite(fd, args, erasesize, 0);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "failed to write: %i\n", ret);
|
||||
|
||||
sync();
|
||||
out:
|
||||
free(args);
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
269
package/system/mtd/src/trx.c
Normal file
269
package/system/mtd/src/trx.c
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* trx.c
|
||||
*
|
||||
* Copyright (C) 2005 Mike Baker
|
||||
* Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <endian.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
#include "mtd.h"
|
||||
#include "crc32.h"
|
||||
|
||||
#define TRX_CRC32_DATA_OFFSET 12 /* First 12 bytes are not covered by CRC32 */
|
||||
#define TRX_CRC32_DATA_SIZE 16
|
||||
struct trx_header {
|
||||
uint32_t magic; /* "HDR0" */
|
||||
uint32_t len; /* Length of file including header */
|
||||
uint32_t crc32; /* 32-bit CRC from flag_version to end of file */
|
||||
uint32_t flag_version; /* 0:15 flags, 16:31 version */
|
||||
uint32_t offsets[3]; /* Offsets of partitions from start of header */
|
||||
};
|
||||
|
||||
#define min(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x < _y ? _x : _y; })
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define STORE32_LE(X) (X)
|
||||
#else
|
||||
#error unknown endianness!
|
||||
#endif
|
||||
|
||||
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
|
||||
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
|
||||
|
||||
int
|
||||
trx_fixup(int fd, const char *name)
|
||||
{
|
||||
struct mtd_info_user mtdInfo;
|
||||
unsigned long len;
|
||||
struct trx_header *trx;
|
||||
void *ptr, *scan;
|
||||
int bfd;
|
||||
|
||||
if (ioctl(fd, MEMGETINFO, &mtdInfo) < 0) {
|
||||
fprintf(stderr, "Failed to get mtd info\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
len = mtdInfo.size;
|
||||
if (mtdInfo.size <= 0) {
|
||||
fprintf(stderr, "Invalid MTD device size\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
bfd = mtd_open(name, true);
|
||||
ptr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, bfd, 0);
|
||||
if (!ptr || (ptr == (void *) -1)) {
|
||||
perror("mmap");
|
||||
fprintf(stderr, "Mapping the TRX header failed\n");
|
||||
goto err1;
|
||||
}
|
||||
|
||||
trx = ptr;
|
||||
if (ntohl(trx->magic) != opt_trxmagic) {
|
||||
fprintf(stderr, "TRX header not found\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
scan = ptr + offsetof(struct trx_header, flag_version);
|
||||
trx->crc32 = crc32buf(scan, trx->len - (scan - ptr));
|
||||
msync(ptr, sizeof(struct trx_header), MS_SYNC|MS_INVALIDATE);
|
||||
munmap(ptr, len);
|
||||
close(bfd);
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
close(bfd);
|
||||
err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
trx_check(int imagefd, const char *mtd, char *buf, int *len)
|
||||
{
|
||||
const struct trx_header *trx = (const struct trx_header *) buf;
|
||||
int fd;
|
||||
|
||||
if (strcmp(mtd, "firmware") != 0)
|
||||
return 1;
|
||||
|
||||
if (*len < 32) {
|
||||
*len += read(imagefd, buf + *len, 32 - *len);
|
||||
if (*len < 32) {
|
||||
fprintf(stdout, "Could not get image header, file too small (%d bytes)\n", *len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ntohl(trx->magic) != opt_trxmagic ||
|
||||
trx->len < sizeof(struct trx_header)) {
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "Bad trx header\n");
|
||||
fprintf(stderr, "This is not the correct file format; refusing to flash.\n"
|
||||
"Please specify the correct file or use -f to force.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if image fits to mtd device */
|
||||
fd = mtd_check_open(mtd);
|
||||
if(fd < 0) {
|
||||
fprintf(stderr, "Could not open mtd device: %s\n", mtd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(mtdsize < trx->len) {
|
||||
fprintf(stderr, "Image too big for partition: %s\n", mtd);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
|
||||
{
|
||||
size_t data_offset;
|
||||
int fd;
|
||||
struct trx_header *trx;
|
||||
char *first_block;
|
||||
char *buf, *to;
|
||||
ssize_t res;
|
||||
size_t block_offset;
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Trying to fix trx header in %s at 0x%zx...\n", mtd, offset);
|
||||
|
||||
fd = mtd_check_open(mtd);
|
||||
if(fd < 0) {
|
||||
fprintf(stderr, "Could not open mtd device: %s\n", mtd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
data_offset = offset + TRX_CRC32_DATA_OFFSET;
|
||||
if (data_size)
|
||||
data_size += TRX_CRC32_DATA_SIZE;
|
||||
else
|
||||
data_size = erasesize - TRX_CRC32_DATA_OFFSET;
|
||||
|
||||
block_offset = offset & ~(erasesize - 1);
|
||||
offset -= block_offset;
|
||||
|
||||
if (data_offset + data_size > mtdsize) {
|
||||
fprintf(stderr, "Offset too large, device size 0x%x\n", mtdsize);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
first_block = malloc(erasesize);
|
||||
if (!first_block) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
res = pread(fd, first_block, erasesize, block_offset);
|
||||
if (res != erasesize) {
|
||||
perror("pread");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
trx = (struct trx_header *)(first_block + offset);
|
||||
if (ntohl(trx->magic) != opt_trxmagic) {
|
||||
fprintf(stderr, "No trx magic found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
buf = malloc(data_size);
|
||||
if (!buf) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
to = buf;
|
||||
while (data_size) {
|
||||
size_t read_block_offset = data_offset & ~(erasesize - 1);
|
||||
size_t read_chunk;
|
||||
|
||||
read_chunk = erasesize - (data_offset & (erasesize - 1));
|
||||
read_chunk = min(read_chunk, data_size);
|
||||
|
||||
/* Read from good blocks only to match CFE behavior */
|
||||
if (!mtd_block_is_bad(fd, read_block_offset)) {
|
||||
res = pread(fd, to, read_chunk, data_offset);
|
||||
if (res != read_chunk) {
|
||||
perror("pread");
|
||||
exit(1);
|
||||
}
|
||||
to += read_chunk;
|
||||
}
|
||||
|
||||
data_offset += read_chunk;
|
||||
data_size -= read_chunk;
|
||||
}
|
||||
data_size = to - buf;
|
||||
|
||||
if (trx->len == STORE32_LE(data_size + TRX_CRC32_DATA_OFFSET) &&
|
||||
trx->crc32 == STORE32_LE(crc32buf(buf, data_size))) {
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Header already fixed, exiting\n");
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
trx->len = STORE32_LE(data_size + offsetof(struct trx_header, flag_version));
|
||||
|
||||
trx->crc32 = STORE32_LE(crc32buf(buf, data_size));
|
||||
if (mtd_erase_block(fd, block_offset)) {
|
||||
fprintf(stderr, "Can't erease block at 0x%zx (%s)\n", block_offset, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "New crc32: 0x%x, rewriting block\n", trx->crc32);
|
||||
|
||||
if (pwrite(fd, first_block, erasesize, block_offset) != erasesize) {
|
||||
fprintf(stderr, "Error writing block (%s)\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Done.\n");
|
||||
|
||||
close (fd);
|
||||
sync();
|
||||
return 0;
|
||||
|
||||
}
|
||||
208
package/system/mtd/src/wrg.c
Normal file
208
package/system/mtd/src/wrg.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* wrg.c
|
||||
*
|
||||
* Copyright (C) 2005 Mike Baker
|
||||
* Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2016 Stijn Tintel <stijn@linux-ipv6.be>
|
||||
* Copyright (C) 2017 George Hopkins <george-hopkins@null.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
#include "mtd.h"
|
||||
#include "md5.h"
|
||||
|
||||
#if !defined(__BYTE_ORDER)
|
||||
#error "Unknown byte order"
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define cpu_to_le32(x) bswap_32(x)
|
||||
#define le32_to_cpu(x) bswap_32(x)
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define cpu_to_le32(x) (x)
|
||||
#define le32_to_cpu(x) (x)
|
||||
#else
|
||||
#error "Unsupported endianness"
|
||||
#endif
|
||||
|
||||
#define WRG_MAGIC 0x20040220
|
||||
|
||||
struct wrg_header {
|
||||
char signature[32];
|
||||
uint32_t magic1;
|
||||
uint32_t magic2;
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
char devname[32];
|
||||
char digest[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
|
||||
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
|
||||
|
||||
int
|
||||
wrg_fix_md5(struct wrg_header *shdr, int fd, size_t data_offset, size_t data_size)
|
||||
{
|
||||
char *buf;
|
||||
ssize_t res;
|
||||
MD5_CTX ctx;
|
||||
unsigned char digest[16];
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
buf = malloc(data_size);
|
||||
if (!buf) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
res = pread(fd, buf, data_size, data_offset);
|
||||
if (res != data_size) {
|
||||
perror("pread");
|
||||
err = -EIO;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, (char *)&shdr->offset, sizeof(shdr->offset));
|
||||
MD5_Update(&ctx, (char *)&shdr->devname, sizeof(shdr->devname));
|
||||
MD5_Update(&ctx, buf, data_size);
|
||||
MD5_Final(digest, &ctx);
|
||||
|
||||
if (!memcmp(digest, shdr->digest, sizeof(digest))) {
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "the header is fixed already\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "new size: %u, new MD5: ", data_size);
|
||||
for (i = 0; i < sizeof(digest); i++)
|
||||
fprintf(stderr, "%02x", digest[i]);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/* update the size in the image */
|
||||
shdr->size = cpu_to_le32(data_size);
|
||||
|
||||
/* update the checksum in the image */
|
||||
memcpy(shdr->digest, digest, sizeof(digest));
|
||||
|
||||
err_free:
|
||||
free(buf);
|
||||
err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
mtd_fixwrg(const char *mtd, size_t offset, size_t data_size)
|
||||
{
|
||||
int fd;
|
||||
char *first_block;
|
||||
ssize_t res;
|
||||
size_t block_offset;
|
||||
size_t data_offset;
|
||||
struct wrg_header *shdr;
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Trying to fix WRG header in %s at 0x%x...\n",
|
||||
mtd, offset);
|
||||
|
||||
block_offset = offset & ~(erasesize - 1);
|
||||
offset -= block_offset;
|
||||
|
||||
fd = mtd_check_open(mtd);
|
||||
if(fd < 0) {
|
||||
fprintf(stderr, "Could not open mtd device: %s\n", mtd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (block_offset + erasesize > mtdsize) {
|
||||
fprintf(stderr, "Offset too large, device size 0x%x\n",
|
||||
mtdsize);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
first_block = malloc(erasesize);
|
||||
if (!first_block) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
res = pread(fd, first_block, erasesize, block_offset);
|
||||
if (res != erasesize) {
|
||||
perror("pread");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
shdr = (struct wrg_header *)(first_block + offset);
|
||||
if (le32_to_cpu(shdr->magic1) != WRG_MAGIC) {
|
||||
fprintf(stderr, "No WRG header found (%08x != %08x)\n",
|
||||
le32_to_cpu(shdr->magic1), WRG_MAGIC);
|
||||
exit(1);
|
||||
} else if (!le32_to_cpu(shdr->size)) {
|
||||
fprintf(stderr, "WRG entity with empty image\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
data_offset = offset + sizeof(struct wrg_header);
|
||||
if (!data_size)
|
||||
data_size = mtdsize - data_offset;
|
||||
if (data_size > le32_to_cpu(shdr->size))
|
||||
data_size = le32_to_cpu(shdr->size);
|
||||
if (wrg_fix_md5(shdr, fd, data_offset, data_size))
|
||||
goto out;
|
||||
|
||||
if (mtd_erase_block(fd, block_offset)) {
|
||||
fprintf(stderr, "Can't erease block at 0x%x (%s)\n",
|
||||
block_offset, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Rewriting block at 0x%x\n", block_offset);
|
||||
|
||||
if (pwrite(fd, first_block, erasesize, block_offset) != erasesize) {
|
||||
fprintf(stderr, "Error writing block (%s)\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Done.\n");
|
||||
|
||||
out:
|
||||
close (fd);
|
||||
sync();
|
||||
|
||||
return 0;
|
||||
}
|
||||
189
package/system/mtd/src/wrgg.c
Normal file
189
package/system/mtd/src/wrgg.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* wrgg.c
|
||||
*
|
||||
* Copyright (C) 2005 Mike Baker
|
||||
* Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2016 Stijn Tintel <stijn@linux-ipv6.be>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
#include "mtd.h"
|
||||
#include "wrgg.h"
|
||||
#include "md5.h"
|
||||
|
||||
static inline uint32_t le32_to_cpu(uint8_t *buf)
|
||||
{
|
||||
return buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24;
|
||||
}
|
||||
|
||||
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
|
||||
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
|
||||
|
||||
int
|
||||
wrgg_fix_md5(struct wrgg03_header *shdr, int fd, size_t data_offset, size_t data_size)
|
||||
{
|
||||
char *buf;
|
||||
ssize_t res;
|
||||
MD5_CTX ctx;
|
||||
unsigned char digest[16];
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
buf = malloc(data_size);
|
||||
if (!buf) {
|
||||
err = -ENOMEM;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
res = pread(fd, buf, data_size, data_offset);
|
||||
if (res != data_size) {
|
||||
perror("pread");
|
||||
err = -EIO;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
MD5_Init(&ctx);
|
||||
MD5_Update(&ctx, (char *)&shdr->offset, sizeof(shdr->offset));
|
||||
MD5_Update(&ctx, (char *)&shdr->dev_name, sizeof(shdr->dev_name));
|
||||
MD5_Update(&ctx, buf, data_size);
|
||||
MD5_Final(digest, &ctx);
|
||||
|
||||
if (!memcmp(digest, shdr->digest, sizeof(digest))) {
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "the header is fixed already\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (quiet < 2) {
|
||||
fprintf(stderr, "new size:%u, new MD5: ", data_size);
|
||||
for (i = 0; i < sizeof(digest); i++)
|
||||
fprintf(stderr, "%02x", digest[i]);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/* update the size in the image */
|
||||
shdr->size = data_size;
|
||||
|
||||
/* update the checksum in the image */
|
||||
memcpy(shdr->digest, digest, sizeof(digest));
|
||||
|
||||
err_free:
|
||||
free(buf);
|
||||
err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
mtd_fixwrgg(const char *mtd, size_t offset, size_t data_size)
|
||||
{
|
||||
int fd;
|
||||
char *first_block;
|
||||
ssize_t res;
|
||||
size_t block_offset;
|
||||
size_t data_offset;
|
||||
struct wrgg03_header *shdr;
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Trying to fix WRGG header in %s at 0x%x...\n",
|
||||
mtd, offset);
|
||||
|
||||
block_offset = offset & ~(erasesize - 1);
|
||||
offset -= block_offset;
|
||||
|
||||
fd = mtd_check_open(mtd);
|
||||
if(fd < 0) {
|
||||
fprintf(stderr, "Could not open mtd device: %s\n", mtd);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (block_offset + erasesize > mtdsize) {
|
||||
fprintf(stderr, "Offset too large, device size 0x%x\n",
|
||||
mtdsize);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
first_block = malloc(erasesize);
|
||||
if (!first_block) {
|
||||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
res = pread(fd, first_block, erasesize, block_offset);
|
||||
if (res != erasesize) {
|
||||
perror("pread");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
shdr = (struct wrgg03_header *)(first_block + offset);
|
||||
|
||||
/* The magic is always stored in little-endian byte order */
|
||||
if (le32_to_cpu((uint8_t *)&shdr->magic1) != WRGG03_MAGIC) {
|
||||
fprintf(stderr, "magic1 = %x\n", shdr->magic1);
|
||||
fprintf(stderr, "WRGG03_MAGIC = %x\n", WRGG03_MAGIC);
|
||||
fprintf(stderr, "No WRGG header found\n");
|
||||
exit(1);
|
||||
} else if (!shdr->size) {
|
||||
fprintf(stderr, "WRGG entity with empty image\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
data_offset = offset + sizeof(struct wrgg03_header);
|
||||
if (!data_size)
|
||||
data_size = mtdsize - data_offset;
|
||||
if (data_size > shdr->size)
|
||||
data_size = shdr->size;
|
||||
if (wrgg_fix_md5(shdr, fd, data_offset, data_size))
|
||||
goto out;
|
||||
|
||||
if (mtd_erase_block(fd, block_offset)) {
|
||||
fprintf(stderr, "Can't erease block at 0x%x (%s)\n",
|
||||
block_offset, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Rewriting block at 0x%x\n", block_offset);
|
||||
|
||||
if (pwrite(fd, first_block, erasesize, block_offset) != erasesize) {
|
||||
fprintf(stderr, "Error writing block (%s)\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (quiet < 2)
|
||||
fprintf(stderr, "Done.\n");
|
||||
|
||||
out:
|
||||
close (fd);
|
||||
sync();
|
||||
|
||||
return 0;
|
||||
}
|
||||
20
package/system/mtd/src/wrgg.h
Normal file
20
package/system/mtd/src/wrgg.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __wrgg_h
|
||||
#define __wrgg_h
|
||||
|
||||
#define WRGG03_MAGIC 0x20080321
|
||||
|
||||
struct wrgg03_header {
|
||||
char signature[32];
|
||||
uint32_t magic1;
|
||||
uint32_t magic2;
|
||||
char version[16];
|
||||
char model[16];
|
||||
uint32_t flag[2];
|
||||
uint32_t reserve[2];
|
||||
char buildno[16];
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
char dev_name[32];
|
||||
char digest[16];
|
||||
} __attribute__ ((packed));
|
||||
#endif /* __wrgg_h */
|
||||
39
package/system/openwrt-keyring/Makefile
Normal file
39
package/system/openwrt-keyring/Makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
# Copyright (C) 2016 LEDE project
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=openwrt-keyring
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/keyring.git
|
||||
PKG_SOURCE_DATE:=2022-03-25
|
||||
PKG_SOURCE_VERSION:=62471e693b4f9f19dd88afa6827fc3a2cf121d9a
|
||||
PKG_MIRROR_HASH:=dbc6cf709f702f92f6aabcd9f981a14901ec61c9b340bd506986f8b438503632
|
||||
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/openwrt-keyring
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
PROVIDES:=lede-keyring
|
||||
TITLE:=OpenWrt Developer Keyring
|
||||
URL:=https://openwrt.org/docs/guide-user/security/signatures
|
||||
endef
|
||||
|
||||
define Package/openwrt-keyring/description
|
||||
The keyring of with the developer using and gpg public keys.
|
||||
endef
|
||||
|
||||
Build/Compile=
|
||||
|
||||
define Package/openwrt-keyring/install
|
||||
$(INSTALL_DIR) $(1)/etc/opkg/keys/
|
||||
# Public usign key for unattended snapshot builds
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/usign/b5043e70f9a75cde $(1)/etc/opkg/keys/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,openwrt-keyring))
|
||||
98
package/system/opkg/Makefile
Normal file
98
package/system/opkg/Makefile
Normal file
@@ -0,0 +1,98 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Copyright (C) 2006-2021 OpenWrt.org
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=opkg
|
||||
PKG_RELEASE:=2
|
||||
PKG_FLAGS:=essential
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/opkg-lede.git
|
||||
PKG_SOURCE_DATE:=2022-02-24
|
||||
PKG_SOURCE_VERSION:=d038e5b6d155784575f62a66a8bb7e874173e92e
|
||||
PKG_MIRROR_HASH:=6889f7d322996f9291f42d7d6a5877d256b91d4a01d6015cebaae9227702eb43
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
||||
|
||||
# Extend depends from version.mk
|
||||
PKG_CONFIG_DEPENDS += \
|
||||
CONFIG_SIGNATURE_CHECK \
|
||||
CONFIG_TARGET_INIT_PATH
|
||||
|
||||
HOST_BUILD_DEPENDS:=libubox/host
|
||||
|
||||
PKG_BUILD_FLAGS:=gc-sections
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/opkg
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=opkg package manager
|
||||
DEPENDS:=+uclient-fetch +libpthread +libubox
|
||||
URL:=$(PKG_SOURCE_URL)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define Package/opkg/description
|
||||
Lightweight package management system
|
||||
opkg is the opkg Package Management System, for handling
|
||||
installation and removal of packages on a system. It can
|
||||
recursively follow dependencies and download all packages
|
||||
necessary to install a particular package.
|
||||
|
||||
opkg knows how to install both .ipk and .deb packages.
|
||||
endef
|
||||
|
||||
define Package/opkg/conffiles
|
||||
/etc/opkg.conf
|
||||
/etc/opkg/keys/
|
||||
/etc/opkg/customfeeds.conf
|
||||
endef
|
||||
|
||||
EXTRA_CFLAGS += $(TARGET_CPPFLAGS)
|
||||
|
||||
CMAKE_OPTIONS += \
|
||||
-DBUILD_TESTS=OFF \
|
||||
-DHOST_CPU=$(PKGARCH) \
|
||||
-DPATH_SPEC="$(TARGET_INIT_PATH)" \
|
||||
-DVERSION="$(PKG_SOURCE_VERSION) ($(PKG_SOURCE_DATE))"
|
||||
|
||||
CMAKE_HOST_OPTIONS += \
|
||||
-DSTATIC_UBOX=ON \
|
||||
-DBUILD_TESTS=OFF \
|
||||
-DHOST_CPU=$(PKGARCH) \
|
||||
-DLOCK_FILE=/tmp/opkg.lock \
|
||||
-DVERSION="$(PKG_SOURCE_VERSION) ($(PKG_SOURCE_DATE))"
|
||||
|
||||
define Package/opkg/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/opkg
|
||||
$(INSTALL_DIR) $(1)/bin
|
||||
$(INSTALL_DIR) $(1)/etc/opkg
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_DATA) ./files/customfeeds.conf $(1)/etc/opkg/customfeeds.conf
|
||||
$(INSTALL_DATA) ./files/opkg$(2).conf $(1)/etc/opkg.conf
|
||||
$(INSTALL_BIN) ./files/20_migrate-feeds $(1)/etc/uci-defaults/
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/opkg-cl $(1)/bin/opkg
|
||||
ifneq ($(CONFIG_SIGNATURE_CHECK),)
|
||||
echo "option check_signature" >> $(1)/etc/opkg.conf
|
||||
endif
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) ./files/opkg-key $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
$(INSTALL_BIN) $(HOST_BUILD_DIR)/src/opkg-cl $(STAGING_DIR_HOST)/bin/opkg
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,opkg))
|
||||
$(eval $(call HostBuild))
|
||||
9
package/system/opkg/files/20_migrate-feeds
Normal file
9
package/system/opkg/files/20_migrate-feeds
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -f /etc/opkg.conf ] && grep -q "src/" /etc/opkg.conf || exit 0
|
||||
|
||||
echo -e "# Old feeds from previous image\n# Uncomment to reenable\n" >> /etc/opkg/customfeeds.conf
|
||||
sed -n "s/.*\(src\/.*\)/# \1/p" /etc/opkg.conf >> /etc/opkg/customfeeds.conf
|
||||
sed -i "/.*src\/.*/d" /etc/opkg.conf
|
||||
|
||||
exit 0
|
||||
3
package/system/opkg/files/customfeeds.conf
Normal file
3
package/system/opkg/files/customfeeds.conf
Normal file
@@ -0,0 +1,3 @@
|
||||
# add your custom package feeds here
|
||||
#
|
||||
# src/gz example_feed_name http://www.example.com/path/to/files
|
||||
58
package/system/opkg/files/opkg-key
Executable file
58
package/system/opkg/files/opkg-key
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
|
||||
OPKG_KEYS="${OPKG_KEYS:-/etc/opkg/keys}"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 <command> <arguments...>
|
||||
Commands:
|
||||
add <file>: Add keyfile <file> to opkg trusted keys
|
||||
remove <file>: Remove keyfile matching <file> from opkg trusted keys
|
||||
verify <sigfile> <list>: Check list file <list> against signature file <sigfile>
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
opkg_key_verify() {
|
||||
local sigfile="$1"
|
||||
local msgfile="$2"
|
||||
|
||||
(
|
||||
zcat "$msgfile" 2>/dev/null ||
|
||||
cat "$msgfile" 2>/dev/null
|
||||
) | usign -V -P "$OPKG_KEYS" -q -x "$sigfile" -m -
|
||||
}
|
||||
|
||||
opkg_key_add() {
|
||||
local key="$1"
|
||||
[ -n "$key" ] || usage
|
||||
[ -f "$key" ] || echo "Cannot open file $1"
|
||||
local fingerprint="$(usign -F -p "$key")"
|
||||
mkdir -p "$OPKG_KEYS"
|
||||
cp "$key" "$OPKG_KEYS/$fingerprint"
|
||||
}
|
||||
|
||||
opkg_key_remove() {
|
||||
local key="$1"
|
||||
[ -n "$key" ] || usage
|
||||
[ -f "$key" ] || echo "Cannot open file $1"
|
||||
local fingerprint="$(usign -F -p "$key")"
|
||||
rm -f "$OPKG_KEYS/$fingerprint"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
add)
|
||||
shift
|
||||
opkg_key_add "$@"
|
||||
;;
|
||||
remove)
|
||||
shift
|
||||
opkg_key_remove "$@"
|
||||
;;
|
||||
verify)
|
||||
shift
|
||||
opkg_key_verify "$@"
|
||||
;;
|
||||
*) usage ;;
|
||||
esac
|
||||
6
package/system/opkg/files/opkg-smime.conf
Normal file
6
package/system/opkg/files/opkg-smime.conf
Normal file
@@ -0,0 +1,6 @@
|
||||
dest root /
|
||||
dest ram /tmp
|
||||
lists_dir ext /var/opkg-lists
|
||||
option overlay_root /overlay
|
||||
option check_signature 1
|
||||
option signature_ca_file /etc/ssl/certs/opkg.pem
|
||||
4
package/system/opkg/files/opkg.conf
Normal file
4
package/system/opkg/files/opkg.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
dest root /
|
||||
dest ram /tmp
|
||||
lists_dir ext /var/opkg-lists
|
||||
option overlay_root /overlay
|
||||
154
package/system/procd/Makefile
Normal file
154
package/system/procd/Makefile
Normal file
@@ -0,0 +1,154 @@
|
||||
#
|
||||
# Copyright (C) 2014-2016 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=procd
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/procd.git
|
||||
PKG_MIRROR_HASH:=9a0f7a5dfc883e7ea2f7f779e2e68f93507477ca780945219f808b145db5e71d
|
||||
PKG_SOURCE_DATE:=2024-07-07
|
||||
PKG_SOURCE_VERSION:=f230c11771875adc1f74bef013e8cea1fa1867bc
|
||||
CMAKE_INSTALL:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
|
||||
PKG_BUILD_FLAGS:=lto
|
||||
PKG_ASLR_PIE_REGULAR:=1
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_TARGET_INIT_PATH CONFIG_KERNEL_SECCOMP CONFIG_PROCD_SHOW_BOOT \
|
||||
CONFIG_KERNEL_NAMESPACES CONFIG_PACKAGE_procd-ujail CONFIG_PACKAGE_procd-seccomp
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
ifeq ($(DUMP),)
|
||||
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell echo $(CONFIG_TARGET_INIT_PATH) | $(MKHASH) md5)
|
||||
endif
|
||||
|
||||
CMAKE_OPTIONS += -DEARLY_PATH="$(TARGET_INIT_PATH)"
|
||||
|
||||
define Package/procd/Default
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+ubusd +ubus +libjson-script +ubox +libubox +libudebug \
|
||||
+libubus +libblobmsg-json +libjson-c +jshn
|
||||
TITLE:=OpenWrt system process manager
|
||||
USERID:=:dialout=20 :audio=29
|
||||
endef
|
||||
|
||||
define Package/procd
|
||||
$(call Package/procd/Default)
|
||||
VARIANT:=default
|
||||
CONFLICTS:=procd-selinux
|
||||
endef
|
||||
|
||||
define Package/procd-selinux
|
||||
$(call Package/procd/Default)
|
||||
DEPENDS += +libselinux
|
||||
TITLE += with SELinux support
|
||||
PROVIDES:=procd
|
||||
VARIANT:=selinux
|
||||
endef
|
||||
|
||||
define Package/procd-ujail
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=@KERNEL_NAMESPACES +@KERNEL_UTS_NS +@KERNEL_IPC_NS +@KERNEL_PID_NS \
|
||||
+libubox +libubus +libuci +libblobmsg-json
|
||||
TITLE:=OpenWrt process jail helper
|
||||
endef
|
||||
|
||||
define Package/procd-seccomp
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=@SECCOMP +libubox +libblobmsg-json
|
||||
TITLE:=OpenWrt process seccomp helper + utrace
|
||||
endef
|
||||
|
||||
define Package/uxc
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+procd-ujail +libubus +libubox +libblobmsg-json +blockd +PACKAGE_uxc:rpcd
|
||||
TITLE:=OpenWrt container management
|
||||
MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
|
||||
endef
|
||||
|
||||
define Package/procd/config
|
||||
menu "Configuration"
|
||||
depends on PACKAGE_procd || PACKAGE_procd-selinux
|
||||
|
||||
config PROCD_SHOW_BOOT
|
||||
bool
|
||||
default n
|
||||
prompt "Print the shutdown to the console as well as logging it to syslog"
|
||||
|
||||
endmenu
|
||||
endef
|
||||
|
||||
ifeq ($(BUILD_VARIANT),selinux)
|
||||
CMAKE_OPTIONS += -DSELINUX=1
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PROCD_SHOW_BOOT),y)
|
||||
CMAKE_OPTIONS += -DSHOW_BOOT_ON_CONSOLE=1
|
||||
endif
|
||||
|
||||
ifdef CONFIG_PACKAGE_procd-ujail
|
||||
CMAKE_OPTIONS += -DJAIL_SUPPORT=1
|
||||
endif
|
||||
|
||||
SECCOMP=$(if $(CONFIG_PACKAGE_procd-seccomp),1,0)
|
||||
CMAKE_OPTIONS += -DSECCOMP_SUPPORT=$(SECCOMP) -DUTRACE_SUPPORT=$(SECCOMP)
|
||||
|
||||
define Package/procd/install
|
||||
$(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/functions
|
||||
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{init,procd,askfirst,udevtrigger,upgraded} $(1)/sbin/
|
||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libsetlbf.so $(1)/lib
|
||||
$(INSTALL_BIN) ./files/reload_config $(1)/sbin/
|
||||
$(INSTALL_CONF) ./files/hotplug*.json $(1)/etc/
|
||||
$(INSTALL_DATA) ./files/procd.sh $(1)/lib/functions/
|
||||
$(INSTALL_BIN) ./files/service $(1)/sbin/service
|
||||
endef
|
||||
|
||||
Package/procd-selinux/install = $(Package/procd/install)
|
||||
|
||||
define Package/procd-ujail/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ujail $(1)/sbin/
|
||||
endef
|
||||
|
||||
define Package/procd-seccomp/install
|
||||
$(INSTALL_DIR) $(1)/sbin $(1)/lib
|
||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libpreload-seccomp.so $(1)/lib
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/utrace $(1)/sbin/
|
||||
$(LN) utrace $(1)/sbin/seccomp-trace
|
||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libpreload-trace.so $(1)/lib
|
||||
endef
|
||||
|
||||
define Package/uxc/conffiles
|
||||
/etc/uxc
|
||||
endef
|
||||
|
||||
define Package/uxc/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/uxc $(1)/sbin/
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/uxc.init $(1)/etc/init.d/uxc
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,procd))
|
||||
$(eval $(call BuildPackage,procd-selinux))
|
||||
$(eval $(call BuildPackage,procd-ujail))
|
||||
$(eval $(call BuildPackage,procd-seccomp))
|
||||
$(eval $(call BuildPackage,uxc))
|
||||
18
package/system/procd/files/hotplug-preinit.json
Normal file
18
package/system/procd/files/hotplug-preinit.json
Normal file
@@ -0,0 +1,18 @@
|
||||
[
|
||||
[ "case", "ACTION", {
|
||||
"add": [
|
||||
[ "if",
|
||||
[ "has", "FIRMWARE" ],
|
||||
[
|
||||
[ "exec", "/sbin/hotplug-call", "%SUBSYSTEM%" ],
|
||||
[ "load-firmware", "/lib/firmware" ],
|
||||
[ "return" ]
|
||||
]
|
||||
]
|
||||
]
|
||||
} ],
|
||||
[ "if",
|
||||
[ "eq", "SUBSYSTEM", "button" ],
|
||||
[ "exec", "/etc/rc.button/failsafe" ]
|
||||
]
|
||||
]
|
||||
88
package/system/procd/files/hotplug.json
Normal file
88
package/system/procd/files/hotplug.json
Normal file
@@ -0,0 +1,88 @@
|
||||
[
|
||||
[ "case", "ACTION", {
|
||||
"add": [
|
||||
[ "if",
|
||||
[ "and",
|
||||
[ "has", "MAJOR" ],
|
||||
[ "has", "MINOR" ]
|
||||
],
|
||||
[
|
||||
[ "if",
|
||||
[ "eq", "DEVNAME", "null" ],
|
||||
[
|
||||
[ "makedev", "/dev/%DEVNAME%", "0666" ],
|
||||
[ "exec", "/bin/ln", "-s", "/proc/self/fd", "/dev/fd" ],
|
||||
[ "exec", "/bin/ln", "-s", "/proc/self/fd/0", "/dev/stdin" ],
|
||||
[ "exec", "/bin/ln", "-s", "/proc/self/fd/1", "/dev/stdout" ],
|
||||
[ "exec", "/bin/ln", "-s", "/proc/self/fd/2", "/dev/stderr" ],
|
||||
[ "return" ]
|
||||
]
|
||||
],
|
||||
[ "if",
|
||||
[ "eq", "DEVNAME",
|
||||
[ "full", "ptmx", "zero", "tty", "net", "random", "urandom" ]
|
||||
],
|
||||
[
|
||||
[ "makedev", "/dev/%DEVNAME%", "0666" ],
|
||||
[ "return" ]
|
||||
]
|
||||
],
|
||||
[ "if",
|
||||
[ "regex", "DEVNAME", "^snd" ],
|
||||
[ "makedev", "/dev/%DEVNAME%", "0660", "audio" ]
|
||||
],
|
||||
[ "if",
|
||||
[ "regex", "DEVNAME", "^tty" ],
|
||||
[ "makedev", "/dev/%DEVNAME%", "0660", "dialout" ]
|
||||
],
|
||||
[ "if",
|
||||
[ "has", "DEVNAME" ],
|
||||
[ "makedev", "/dev/%DEVNAME%", "0600" ]
|
||||
]
|
||||
]
|
||||
],
|
||||
[ "if",
|
||||
[ "has", "FIRMWARE" ],
|
||||
[
|
||||
[ "exec", "/sbin/hotplug-call", "%SUBSYSTEM%" ],
|
||||
[ "load-firmware", "/lib/firmware" ],
|
||||
[ "return" ]
|
||||
]
|
||||
],
|
||||
[ "if",
|
||||
[ "regex", "DEVNAME", "^ttyGS" ],
|
||||
[ "start-console", "%DEVNAME%" ]
|
||||
]
|
||||
],
|
||||
"remove" : [
|
||||
[ "if",
|
||||
[ "and",
|
||||
[ "has", "DEVNAME" ],
|
||||
[ "has", "MAJOR" ],
|
||||
[ "has", "MINOR" ]
|
||||
],
|
||||
[ "rm", "/dev/%DEVNAME%" ]
|
||||
]
|
||||
]
|
||||
} ],
|
||||
[ "if",
|
||||
[ "and",
|
||||
[ "has", "BUTTON" ],
|
||||
[ "eq", "SUBSYSTEM", "button" ]
|
||||
],
|
||||
[ "button", "/etc/rc.button/%BUTTON%" ]
|
||||
],
|
||||
[ "if",
|
||||
[ "and",
|
||||
[ "eq", "SUBSYSTEM", "usb-serial" ],
|
||||
[ "regex", "DEVNAME",
|
||||
[ "^ttyUSB", "^ttyACM" ]
|
||||
]
|
||||
],
|
||||
[ "exec", "/sbin/hotplug-call", "tty" ],
|
||||
[ "if",
|
||||
[ "isdir", "/etc/hotplug.d/%SUBSYSTEM%" ],
|
||||
[ "exec", "/sbin/hotplug-call", "%SUBSYSTEM%" ]
|
||||
]
|
||||
]
|
||||
]
|
||||
680
package/system/procd/files/procd.sh
Normal file
680
package/system/procd/files/procd.sh
Normal file
@@ -0,0 +1,680 @@
|
||||
# procd API:
|
||||
#
|
||||
# procd_open_service(name, [script]):
|
||||
# Initialize a new procd command message containing a service with one or more instances
|
||||
#
|
||||
# procd_close_service()
|
||||
# Send the command message for the service
|
||||
#
|
||||
# procd_open_instance([name]):
|
||||
# Add an instance to the service described by the previous procd_open_service call
|
||||
#
|
||||
# procd_set_param(type, [value...])
|
||||
# Available types:
|
||||
# command: command line (array).
|
||||
# respawn info: array with 3 values $fail_threshold $restart_timeout $max_fail
|
||||
# env: environment variable (passed to the process)
|
||||
# data: arbitrary name/value pairs for detecting config changes (table)
|
||||
# file: configuration files (array)
|
||||
# netdev: bound network device (detects ifindex changes)
|
||||
# limits: resource limits (passed to the process)
|
||||
# user: $username to run service as
|
||||
# group: $groupname to run service as
|
||||
# pidfile: file name to write pid into
|
||||
# stdout: boolean whether to redirect commands stdout to syslog (default: 0)
|
||||
# stderr: boolean whether to redirect commands stderr to syslog (default: 0)
|
||||
# facility: syslog facility used when logging to syslog (default: daemon)
|
||||
#
|
||||
# No space separation is done for arrays/tables - use one function argument per command line argument
|
||||
#
|
||||
# procd_close_instance():
|
||||
# Complete the instance being prepared
|
||||
#
|
||||
# procd_running(service, [instance]):
|
||||
# Checks if service/instance is currently running
|
||||
#
|
||||
# procd_kill(service, [instance]):
|
||||
# Kill a service instance (or all instances)
|
||||
#
|
||||
# procd_send_signal(service, [instance], [signal])
|
||||
# Send a signal to a service instance (or all instances)
|
||||
#
|
||||
|
||||
. "$IPKG_INSTROOT/usr/share/libubox/jshn.sh"
|
||||
|
||||
PROCD_RELOAD_DELAY=1000
|
||||
_PROCD_SERVICE=
|
||||
|
||||
procd_lock() {
|
||||
local basescript=$(readlink "$initscript")
|
||||
local service_name="$(basename ${basescript:-$initscript})"
|
||||
|
||||
flock -n 1000 &> /dev/null
|
||||
if [ "$?" != "0" ]; then
|
||||
exec 1000>"$IPKG_INSTROOT/var/lock/procd_${service_name}.lock"
|
||||
flock 1000
|
||||
if [ "$?" != "0" ]; then
|
||||
logger "warning: procd flock for $service_name failed"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
_procd_call() {
|
||||
local old_cb
|
||||
|
||||
json_set_namespace procd old_cb
|
||||
"$@"
|
||||
json_set_namespace $old_cb
|
||||
}
|
||||
|
||||
_procd_wrapper() {
|
||||
procd_lock
|
||||
while [ -n "$1" ]; do
|
||||
eval "$1() { _procd_call _$1 \"\$@\"; }"
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
_procd_ubus_call() {
|
||||
local cmd="$1"
|
||||
|
||||
[ -n "$PROCD_DEBUG" ] && json_dump >&2
|
||||
ubus call service "$cmd" "$(json_dump)"
|
||||
json_cleanup
|
||||
}
|
||||
|
||||
_procd_open_service() {
|
||||
local name="$1"
|
||||
local script="$2"
|
||||
|
||||
_PROCD_SERVICE="$name"
|
||||
_PROCD_INSTANCE_SEQ=0
|
||||
|
||||
json_init
|
||||
json_add_string name "$name"
|
||||
[ -n "$script" ] && json_add_string script "$script"
|
||||
json_add_object instances
|
||||
}
|
||||
|
||||
_procd_close_service() {
|
||||
json_close_object
|
||||
_procd_open_trigger
|
||||
service_triggers
|
||||
_procd_close_trigger
|
||||
_procd_open_data
|
||||
service_data
|
||||
_procd_close_data
|
||||
_procd_ubus_call ${1:-set}
|
||||
}
|
||||
|
||||
_procd_add_array_data() {
|
||||
while [ "$#" -gt 0 ]; do
|
||||
json_add_string "" "$1"
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
_procd_add_array() {
|
||||
json_add_array "$1"
|
||||
shift
|
||||
_procd_add_array_data "$@"
|
||||
json_close_array
|
||||
}
|
||||
|
||||
_procd_add_table_data() {
|
||||
while [ -n "$1" ]; do
|
||||
local var="${1%%=*}"
|
||||
local val="${1#*=}"
|
||||
[ "$1" = "$val" ] && val=
|
||||
json_add_string "$var" "$val"
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
_procd_add_table() {
|
||||
json_add_object "$1"
|
||||
shift
|
||||
_procd_add_table_data "$@"
|
||||
json_close_object
|
||||
}
|
||||
|
||||
_procd_open_instance() {
|
||||
local name="$1"; shift
|
||||
|
||||
_PROCD_INSTANCE_SEQ="$(($_PROCD_INSTANCE_SEQ + 1))"
|
||||
name="${name:-instance$_PROCD_INSTANCE_SEQ}"
|
||||
json_add_object "$name"
|
||||
[ -n "$TRACE_SYSCALLS" ] && json_add_boolean trace "1"
|
||||
}
|
||||
|
||||
_procd_open_trigger() {
|
||||
let '_procd_trigger_open = _procd_trigger_open + 1'
|
||||
[ "$_procd_trigger_open" -gt 1 ] && return
|
||||
json_add_array "triggers"
|
||||
}
|
||||
|
||||
_procd_close_trigger() {
|
||||
let '_procd_trigger_open = _procd_trigger_open - 1'
|
||||
[ "$_procd_trigger_open" -lt 1 ] || return
|
||||
json_close_array
|
||||
}
|
||||
|
||||
_procd_open_data() {
|
||||
let '_procd_data_open = _procd_data_open + 1'
|
||||
[ "$_procd_data_open" -gt 1 ] && return
|
||||
json_add_object "data"
|
||||
}
|
||||
|
||||
_procd_close_data() {
|
||||
let '_procd_data_open = _procd_data_open - 1'
|
||||
[ "$_procd_data_open" -lt 1 ] || return
|
||||
json_close_object
|
||||
}
|
||||
|
||||
_procd_open_validate() {
|
||||
json_select ..
|
||||
json_add_array "validate"
|
||||
}
|
||||
|
||||
_procd_close_validate() {
|
||||
json_close_array
|
||||
json_select triggers
|
||||
}
|
||||
|
||||
_procd_add_jail() {
|
||||
json_add_object "jail"
|
||||
json_add_string name "$1"
|
||||
|
||||
shift
|
||||
|
||||
for a in $@; do
|
||||
case $a in
|
||||
log) json_add_boolean "log" "1";;
|
||||
ubus) json_add_boolean "ubus" "1";;
|
||||
procfs) json_add_boolean "procfs" "1";;
|
||||
sysfs) json_add_boolean "sysfs" "1";;
|
||||
ronly) json_add_boolean "ronly" "1";;
|
||||
requirejail) json_add_boolean "requirejail" "1";;
|
||||
netns) json_add_boolean "netns" "1";;
|
||||
userns) json_add_boolean "userns" "1";;
|
||||
cgroupsns) json_add_boolean "cgroupsns" "1";;
|
||||
esac
|
||||
done
|
||||
json_add_object "mount"
|
||||
json_close_object
|
||||
json_close_object
|
||||
}
|
||||
|
||||
_procd_add_jail_mount() {
|
||||
local _json_no_warning=1
|
||||
|
||||
json_select "jail"
|
||||
[ $? = 0 ] || return
|
||||
json_select "mount"
|
||||
[ $? = 0 ] || {
|
||||
json_select ..
|
||||
return
|
||||
}
|
||||
for a in $@; do
|
||||
json_add_string "$a" "0"
|
||||
done
|
||||
json_select ..
|
||||
json_select ..
|
||||
}
|
||||
|
||||
_procd_add_jail_mount_rw() {
|
||||
local _json_no_warning=1
|
||||
|
||||
json_select "jail"
|
||||
[ $? = 0 ] || return
|
||||
json_select "mount"
|
||||
[ $? = 0 ] || {
|
||||
json_select ..
|
||||
return
|
||||
}
|
||||
for a in $@; do
|
||||
json_add_string "$a" "1"
|
||||
done
|
||||
json_select ..
|
||||
json_select ..
|
||||
}
|
||||
|
||||
_procd_set_param() {
|
||||
local type="$1"; shift
|
||||
|
||||
case "$type" in
|
||||
env|data|limits)
|
||||
_procd_add_table "$type" "$@"
|
||||
;;
|
||||
command|netdev|file|respawn|watch|watchdog)
|
||||
_procd_add_array "$type" "$@"
|
||||
;;
|
||||
error)
|
||||
json_add_array "$type"
|
||||
json_add_string "" "$@"
|
||||
json_close_array
|
||||
;;
|
||||
nice|term_timeout)
|
||||
json_add_int "$type" "$1"
|
||||
;;
|
||||
reload_signal)
|
||||
json_add_int "$type" $(kill -l "$1")
|
||||
;;
|
||||
pidfile|user|group|seccomp|capabilities|facility|\
|
||||
extroot|overlaydir|tmpoverlaysize)
|
||||
json_add_string "$type" "$1"
|
||||
;;
|
||||
stdout|stderr|no_new_privs)
|
||||
json_add_boolean "$type" "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_procd_add_timeout() {
|
||||
[ "$PROCD_RELOAD_DELAY" -gt 0 ] && json_add_int "" "$PROCD_RELOAD_DELAY"
|
||||
return 0
|
||||
}
|
||||
|
||||
_procd_add_interface_trigger() {
|
||||
json_add_array
|
||||
_procd_add_array_data "$1"
|
||||
shift
|
||||
|
||||
json_add_array
|
||||
_procd_add_array_data "if"
|
||||
|
||||
json_add_array
|
||||
_procd_add_array_data "eq" "interface" "$1"
|
||||
shift
|
||||
json_close_array
|
||||
|
||||
json_add_array
|
||||
_procd_add_array_data "run_script" "$@"
|
||||
json_close_array
|
||||
|
||||
json_close_array
|
||||
_procd_add_timeout
|
||||
json_close_array
|
||||
}
|
||||
|
||||
_procd_add_reload_interface_trigger() {
|
||||
local script=$(readlink "$initscript")
|
||||
local name=$(basename ${script:-$initscript})
|
||||
|
||||
_procd_open_trigger
|
||||
_procd_add_interface_trigger "interface.*" $1 /etc/init.d/$name reload
|
||||
_procd_close_trigger
|
||||
}
|
||||
|
||||
_procd_add_config_trigger() {
|
||||
json_add_array
|
||||
_procd_add_array_data "$1"
|
||||
shift
|
||||
|
||||
json_add_array
|
||||
_procd_add_array_data "if"
|
||||
|
||||
json_add_array
|
||||
_procd_add_array_data "eq" "package" "$1"
|
||||
shift
|
||||
json_close_array
|
||||
|
||||
json_add_array
|
||||
_procd_add_array_data "run_script" "$@"
|
||||
json_close_array
|
||||
|
||||
json_close_array
|
||||
_procd_add_timeout
|
||||
json_close_array
|
||||
}
|
||||
|
||||
_procd_add_mount_trigger() {
|
||||
json_add_array
|
||||
_procd_add_array_data "$1"
|
||||
local action="$2"
|
||||
local multi=0
|
||||
shift ; shift
|
||||
|
||||
json_add_array
|
||||
_procd_add_array_data "if"
|
||||
|
||||
if [ "$2" ]; then
|
||||
json_add_array
|
||||
_procd_add_array_data "or"
|
||||
multi=1
|
||||
fi
|
||||
|
||||
while [ "$1" ]; do
|
||||
json_add_array
|
||||
_procd_add_array_data "eq" "target" "$1"
|
||||
shift
|
||||
json_close_array
|
||||
done
|
||||
|
||||
[ $multi = 1 ] && json_close_array
|
||||
|
||||
json_add_array
|
||||
_procd_add_array_data "run_script" /etc/init.d/$name $action
|
||||
json_close_array
|
||||
|
||||
json_close_array
|
||||
_procd_add_timeout
|
||||
json_close_array
|
||||
}
|
||||
|
||||
_procd_add_action_mount_trigger() {
|
||||
local action="$1"
|
||||
shift
|
||||
local mountpoints="$(procd_get_mountpoints "$@")"
|
||||
[ "${mountpoints//[[:space:]]}" ] || return 0
|
||||
local script=$(readlink "$initscript")
|
||||
local name=$(basename ${script:-$initscript})
|
||||
|
||||
_procd_open_trigger
|
||||
_procd_add_mount_trigger mount.add $action "$mountpoints"
|
||||
_procd_close_trigger
|
||||
}
|
||||
|
||||
procd_get_mountpoints() {
|
||||
(
|
||||
__procd_check_mount() {
|
||||
local cfg="$1"
|
||||
local path="${2%%/}/"
|
||||
local target
|
||||
config_get target "$cfg" target
|
||||
target="${target%%/}/"
|
||||
[ "$path" != "${path##$target}" ] && echo "${target%%/}"
|
||||
}
|
||||
local mpath
|
||||
config_load fstab
|
||||
for mpath in "$@"; do
|
||||
config_foreach __procd_check_mount mount "$mpath"
|
||||
done
|
||||
) | sort -u
|
||||
}
|
||||
|
||||
_procd_add_restart_mount_trigger() {
|
||||
_procd_add_action_mount_trigger restart "$@"
|
||||
}
|
||||
|
||||
_procd_add_reload_mount_trigger() {
|
||||
_procd_add_action_mount_trigger reload "$@"
|
||||
}
|
||||
|
||||
_procd_add_raw_trigger() {
|
||||
json_add_array
|
||||
_procd_add_array_data "$1"
|
||||
shift
|
||||
local timeout=$1
|
||||
shift
|
||||
|
||||
json_add_array
|
||||
json_add_array
|
||||
_procd_add_array_data "run_script" "$@"
|
||||
json_close_array
|
||||
json_close_array
|
||||
|
||||
json_add_int "" "$timeout"
|
||||
|
||||
json_close_array
|
||||
}
|
||||
|
||||
_procd_add_reload_trigger() {
|
||||
local script=$(readlink "$initscript")
|
||||
local name=$(basename ${script:-$initscript})
|
||||
local file
|
||||
|
||||
_procd_open_trigger
|
||||
for file in "$@"; do
|
||||
_procd_add_config_trigger "config.change" "$file" /etc/init.d/$name reload
|
||||
done
|
||||
_procd_close_trigger
|
||||
}
|
||||
|
||||
_procd_add_validation() {
|
||||
_procd_open_validate
|
||||
$@
|
||||
_procd_close_validate
|
||||
}
|
||||
|
||||
_procd_append_param() {
|
||||
local type="$1"; shift
|
||||
local _json_no_warning=1
|
||||
|
||||
json_select "$type"
|
||||
[ $? = 0 ] || {
|
||||
_procd_set_param "$type" "$@"
|
||||
return
|
||||
}
|
||||
case "$type" in
|
||||
env|data|limits)
|
||||
_procd_add_table_data "$@"
|
||||
;;
|
||||
command|netdev|file|respawn|watch|watchdog)
|
||||
_procd_add_array_data "$@"
|
||||
;;
|
||||
error)
|
||||
json_add_string "" "$@"
|
||||
;;
|
||||
esac
|
||||
json_select ..
|
||||
}
|
||||
|
||||
_procd_close_instance() {
|
||||
local respawn_vals
|
||||
_json_no_warning=1
|
||||
if json_select respawn ; then
|
||||
json_get_values respawn_vals
|
||||
if [ -z "$respawn_vals" ]; then
|
||||
local respawn_threshold=$(uci_get system.@service[0].respawn_threshold)
|
||||
local respawn_timeout=$(uci_get system.@service[0].respawn_timeout)
|
||||
local respawn_retry=$(uci_get system.@service[0].respawn_retry)
|
||||
_procd_add_array_data ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
|
||||
fi
|
||||
json_select ..
|
||||
fi
|
||||
|
||||
json_close_object
|
||||
}
|
||||
|
||||
_procd_add_instance() {
|
||||
_procd_open_instance
|
||||
_procd_set_param command "$@"
|
||||
_procd_close_instance
|
||||
}
|
||||
|
||||
procd_running() {
|
||||
local service="$1"
|
||||
local instance="${2:-*}"
|
||||
[ "$instance" = "*" ] || instance="'$instance'"
|
||||
|
||||
json_init
|
||||
json_add_string name "$service"
|
||||
local running=$(_procd_ubus_call list | jsonfilter -l 1 -e "@['$service'].instances[$instance].running")
|
||||
|
||||
[ "$running" = "true" ]
|
||||
}
|
||||
|
||||
_procd_kill() {
|
||||
local service="$1"
|
||||
local instance="$2"
|
||||
|
||||
json_init
|
||||
[ -n "$service" ] && json_add_string name "$service"
|
||||
[ -n "$instance" ] && json_add_string instance "$instance"
|
||||
_procd_ubus_call delete
|
||||
}
|
||||
|
||||
_procd_send_signal() {
|
||||
local service="$1"
|
||||
local instance="$2"
|
||||
local signal="$3"
|
||||
|
||||
case "$signal" in
|
||||
[A-Z]*) signal="$(kill -l "$signal" 2>/dev/null)" || return 1;;
|
||||
esac
|
||||
|
||||
json_init
|
||||
json_add_string name "$service"
|
||||
[ -n "$instance" -a "$instance" != "*" ] && json_add_string instance "$instance"
|
||||
[ -n "$signal" ] && json_add_int signal "$signal"
|
||||
_procd_ubus_call signal
|
||||
}
|
||||
|
||||
_procd_status() {
|
||||
local service="$1"
|
||||
local instance="$2"
|
||||
local data state
|
||||
local n_running=0
|
||||
local n_stopped=0
|
||||
local n_total=0
|
||||
|
||||
json_init
|
||||
[ -n "$service" ] && json_add_string name "$service"
|
||||
|
||||
data=$(_procd_ubus_call list | jsonfilter -e '@["'"$service"'"]')
|
||||
[ -z "$data" ] && { echo "inactive"; return 3; }
|
||||
|
||||
data=$(echo "$data" | jsonfilter -e '$.instances')
|
||||
if [ -z "$data" ]; then
|
||||
[ -z "$instance" ] && { echo "active with no instances"; return 0; }
|
||||
data="[]"
|
||||
fi
|
||||
|
||||
[ -n "$instance" ] && instance="\"$instance\"" || instance='*'
|
||||
|
||||
for state in $(jsonfilter -s "$data" -e '$['"$instance"'].running'); do
|
||||
n_total=$((n_total + 1))
|
||||
case "$state" in
|
||||
false) n_stopped=$((n_stopped + 1)) ;;
|
||||
true) n_running=$((n_running + 1)) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $n_total -gt 0 ]; then
|
||||
if [ $n_running -gt 0 ] && [ $n_stopped -eq 0 ]; then
|
||||
echo "running"
|
||||
return 0
|
||||
elif [ $n_running -gt 0 ]; then
|
||||
echo "running ($n_running/$n_total)"
|
||||
return 0
|
||||
else
|
||||
echo "not running"
|
||||
return 5
|
||||
fi
|
||||
else
|
||||
echo "unknown instance $instance"
|
||||
return 4
|
||||
fi
|
||||
}
|
||||
|
||||
procd_open_data() {
|
||||
local name="$1"
|
||||
json_set_namespace procd __procd_old_cb
|
||||
json_add_object data
|
||||
}
|
||||
|
||||
procd_close_data() {
|
||||
json_close_object
|
||||
json_set_namespace $__procd_old_cb
|
||||
}
|
||||
|
||||
_procd_set_config_changed() {
|
||||
local package="$1"
|
||||
|
||||
json_init
|
||||
json_add_string type config.change
|
||||
json_add_object data
|
||||
json_add_string package "$package"
|
||||
json_close_object
|
||||
|
||||
ubus call service event "$(json_dump)"
|
||||
}
|
||||
|
||||
procd_add_mdns_service() {
|
||||
local service proto port txt_count=0
|
||||
service=$1; shift
|
||||
proto=$1; shift
|
||||
port=$1; shift
|
||||
json_add_object "${service}_$port"
|
||||
json_add_string "service" "_$service._$proto.local"
|
||||
json_add_int port "$port"
|
||||
for txt in "$@"; do
|
||||
[ -z "$txt" ] && continue
|
||||
txt_count=$((txt_count+1))
|
||||
[ $txt_count -eq 1 ] && json_add_array txt
|
||||
json_add_string "" "$txt"
|
||||
done
|
||||
[ $txt_count -gt 0 ] && json_select ..
|
||||
|
||||
json_select ..
|
||||
}
|
||||
|
||||
procd_add_mdns() {
|
||||
procd_open_data
|
||||
json_add_object "mdns"
|
||||
procd_add_mdns_service "$@"
|
||||
json_close_object
|
||||
procd_close_data
|
||||
}
|
||||
|
||||
uci_validate_section()
|
||||
{
|
||||
local _package="$1"
|
||||
local _type="$2"
|
||||
local _name="$3"
|
||||
local _result
|
||||
local _error
|
||||
shift; shift; shift
|
||||
_result=$(/sbin/validate_data "$_package" "$_type" "$_name" "$@" 2> /dev/null)
|
||||
_error=$?
|
||||
eval "$_result"
|
||||
[ "$_error" = "0" ] || $(/sbin/validate_data "$_package" "$_type" "$_name" "$@" 1> /dev/null)
|
||||
return $_error
|
||||
}
|
||||
|
||||
uci_load_validate() {
|
||||
local _package="$1"
|
||||
local _type="$2"
|
||||
local _name="$3"
|
||||
local _function="$4"
|
||||
local _option
|
||||
local _result
|
||||
shift; shift; shift; shift
|
||||
for _option in "$@"; do
|
||||
eval "local ${_option%%:*}"
|
||||
done
|
||||
uci_validate_section "$_package" "$_type" "$_name" "$@"
|
||||
_result=$?
|
||||
[ -n "$_function" ] || return $_result
|
||||
eval "$_function \"\$_name\" \"\$_result\""
|
||||
}
|
||||
|
||||
_procd_wrapper \
|
||||
procd_open_service \
|
||||
procd_close_service \
|
||||
procd_add_instance \
|
||||
procd_add_raw_trigger \
|
||||
procd_add_config_trigger \
|
||||
procd_add_interface_trigger \
|
||||
procd_add_mount_trigger \
|
||||
procd_add_reload_trigger \
|
||||
procd_add_reload_interface_trigger \
|
||||
procd_add_action_mount_trigger \
|
||||
procd_add_reload_mount_trigger \
|
||||
procd_add_restart_mount_trigger \
|
||||
procd_open_trigger \
|
||||
procd_close_trigger \
|
||||
procd_open_instance \
|
||||
procd_close_instance \
|
||||
procd_open_validate \
|
||||
procd_close_validate \
|
||||
procd_add_jail \
|
||||
procd_add_jail_mount \
|
||||
procd_add_jail_mount_rw \
|
||||
procd_set_param \
|
||||
procd_append_param \
|
||||
procd_add_validation \
|
||||
procd_set_config_changed \
|
||||
procd_kill \
|
||||
procd_send_signal
|
||||
15
package/system/procd/files/reload_config
Normal file
15
package/system/procd/files/reload_config
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
rm -rf /var/run/config.check
|
||||
mkdir -p /var/run/config.check
|
||||
for config in /etc/config/*; do
|
||||
file=${config##*/}
|
||||
uci show "${file##*/}" > /var/run/config.check/$file
|
||||
done
|
||||
MD5FILE=/var/run/config.md5
|
||||
[ -f $MD5FILE ] && {
|
||||
for c in $(md5sum -c $MD5FILE 2>/dev/null| grep FAILED | cut -d: -f1); do
|
||||
ubus call service event "{ \"type\": \"config.change\", \"data\": { \"package\": \"$(basename $c)\" }}"
|
||||
done
|
||||
}
|
||||
md5sum /var/run/config.check/* > $MD5FILE
|
||||
rm -rf /var/run/config.check
|
||||
30
package/system/procd/files/service
Normal file
30
package/system/procd/files/service
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
main() {
|
||||
local service="$1"
|
||||
shift
|
||||
|
||||
local boot status
|
||||
|
||||
if [ -f "/etc/init.d/${service}" ]; then
|
||||
/etc/init.d/"${service}" "$@"
|
||||
exit "$?"
|
||||
fi
|
||||
|
||||
if [ -n "$service" ]; then
|
||||
echo "Service \"$service\" not found:"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Usage: $(basename "$0") <service> [command]"
|
||||
for service in /etc/init.d/* ; do
|
||||
boot="$($service enabled && echo "enabled" || echo "disabled" )"
|
||||
status="$( [ "$(ubus call service list "{ 'verbose': true, 'name': '$(basename "$service")' }" \
|
||||
| jsonfilter -q -e "@['$(basename "$service")'].instances[*].running" | uniq)" = "true" ] \
|
||||
&& echo "running" || echo "stopped" )"
|
||||
|
||||
printf "%-30s\\t%10s\\t%10s\\n" "$service" "$boot" "$status"
|
||||
done
|
||||
}
|
||||
|
||||
main "$@"
|
||||
16
package/system/procd/files/uxc.init
Normal file
16
package/system/procd/files/uxc.init
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
NAME=uxc
|
||||
PROG=/sbin/uxc
|
||||
|
||||
start_service() {
|
||||
procd_open_instance "uxc"
|
||||
procd_set_param command "$PROG" boot
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_raw_trigger "mount.add" 3000 /etc/init.d/uxc start
|
||||
}
|
||||
80
package/system/refpolicy/Makefile
Normal file
80
package/system/refpolicy/Makefile
Normal file
@@ -0,0 +1,80 @@
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=refpolicy
|
||||
PKG_VERSION:=2.20200229
|
||||
PKG_RELEASE:=3
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:=https://github.com/SELinuxProject/refpolicy/releases/download/RELEASE_2_20200229
|
||||
PKG_HASH:=dec854512ed00cd057408f330c2cea4de7a4405f7a147458f59c994bf578e4b0
|
||||
PKG_INSTALL:=1
|
||||
PKG_BUILD_DEPENDS:=checkpolicy/host policycoreutils/host
|
||||
|
||||
PKG_MAINTAINER:=Thomas Petazzoni <thomas.petazzoni@bootlin.com>
|
||||
PKG_CPE_ID:=cpe:/a:tresys:refpolicy
|
||||
PKG_LICENSE:=GPL-2.0-or-later
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
TAR_OPTIONS:=--transform='s%^refpolicy%$(PKG_NAME)-$(PKG_VERSION)%' -xf -
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/refpolicy
|
||||
SECTION:=system
|
||||
CATEGORY:=Base system
|
||||
TITLE:=SELinux reference policy
|
||||
URL:=http://selinuxproject.org/page/Main_Page
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/refpolicy/description
|
||||
The SELinux Reference Policy project (refpolicy) is a
|
||||
complete SELinux policy that can be used as the system
|
||||
policy for a variety of systems and used as the basis for
|
||||
creating other policies. Reference Policy was originally
|
||||
based on the NSA example policy, but aims to accomplish many
|
||||
additional goals.
|
||||
|
||||
The current refpolicy does not fully support OpenWRT and
|
||||
needs modifications to work with the default system file
|
||||
layout. These changes should be added as patches to the
|
||||
refpolicy that modify a single SELinux policy.
|
||||
|
||||
The refpolicy works for the most part in permissive
|
||||
mode. Only the basic set of utilities are enabled in the
|
||||
example policy config and some of the pathing in the
|
||||
policies is not correct. Individual policies would need to
|
||||
be tweaked to get everything functioning properly.
|
||||
endef
|
||||
|
||||
# Yes, we want CC=$(HOSTCC) because the only code that checkpolicy
|
||||
# builds is a small host tool that gets run as part of the build
|
||||
# process.
|
||||
MAKE_FLAGS += \
|
||||
SETFILES="$(STAGING_DIR_HOST)/bin/setfiles" \
|
||||
CHECKPOLICY="$(STAGING_DIR_HOSTPKG)/bin/checkpolicy" \
|
||||
CC="$(HOSTCC)" \
|
||||
CFLAGS="$(HOST_CFLAGS)"
|
||||
|
||||
define Build/Configure
|
||||
$(SED) "/MONOLITHIC/c\MONOLITHIC = y" $(PKG_BUILD_DIR)/build.conf
|
||||
$(SED) "/NAME/c\NAME = targeted" $(PKG_BUILD_DIR)/build.conf
|
||||
$(call Build/Compile/Default,conf)
|
||||
endef
|
||||
|
||||
define Package/refpolicy/conffiles
|
||||
/etc/selinux/config
|
||||
endef
|
||||
|
||||
define Package/refpolicy/install
|
||||
$(INSTALL_DIR) $(1)/etc/selinux
|
||||
$(CP) $(PKG_INSTALL_DIR)/etc/selinux/* $(1)/etc/selinux/
|
||||
$(CP) ./files/selinux-config $(1)/etc/selinux/config
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,refpolicy))
|
||||
7
package/system/refpolicy/files/selinux-config
Normal file
7
package/system/refpolicy/files/selinux-config
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file controls the state of SELinux on the system.
|
||||
# SELINUX= can take one of these three values:
|
||||
# enforcing - SELinux security policy is enforced.
|
||||
# permissive - SELinux prints warnings instead of enforcing.
|
||||
# disabled - No SELinux policy is loaded.
|
||||
SELINUX=permissive
|
||||
SELINUXTYPE=targeted
|
||||
10
package/system/refpolicy/patches/100-no-docs.patch
Normal file
10
package/system/refpolicy/patches/100-no-docs.patch
Normal file
@@ -0,0 +1,10 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -648,6 +648,6 @@ ifneq ($(generated_fc),)
|
||||
endif
|
||||
endif
|
||||
|
||||
-.PHONY: install-src install-appconfig install-headers generate xml conf html bare tags
|
||||
+.PHONY: install-src install-appconfig install-headers generate conf bare tags
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c
|
||||
107
package/system/rpcd/Makefile
Normal file
107
package/system/rpcd/Makefile
Normal file
@@ -0,0 +1,107 @@
|
||||
#
|
||||
# Copyright (C) 2013-2016 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=rpcd
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/rpcd.git
|
||||
PKG_MIRROR_HASH:=4b4c0a15180a4e39a5af5a6b9c7cf663bcef53d40df780e4da6edd6e63966006
|
||||
PKG_SOURCE_DATE:=2024-02-22
|
||||
PKG_SOURCE_VERSION:=8ef4c2587ac0041049c67befed281a70cf240769
|
||||
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
||||
|
||||
PKG_LICENSE:=ISC
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_ASLR_PIE_REGULAR:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(CP) $(PKG_BUILD_DIR)/include/rpcd $(1)/usr/include/
|
||||
endef
|
||||
|
||||
define Package/rpcd/default
|
||||
SECTION:=utils
|
||||
CATEGORY:=Base system
|
||||
TITLE:=OpenWrt ubus RPC backend server
|
||||
DEPENDS:=+libubus +libubox
|
||||
endef
|
||||
|
||||
define Package/rpcd
|
||||
$(Package/rpcd/default)
|
||||
DEPENDS+= +libuci +libblobmsg-json +libjson-c
|
||||
endef
|
||||
|
||||
define Package/rpcd/description
|
||||
This package provides the UBUS RPC backend server to expose various
|
||||
functionality to frontend programs via JSON-RPC.
|
||||
endef
|
||||
|
||||
define Package/rpcd/conffiles
|
||||
/etc/config/rpcd
|
||||
endef
|
||||
|
||||
TARGET_LDFLAGS += -lcrypt
|
||||
|
||||
define Package/rpcd/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/rpcd.init $(1)/etc/init.d/rpcd
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/rpcd $(1)/sbin/rpcd
|
||||
$(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/unauthenticated.json $(1)/usr/share/rpcd/acl.d/unauthenticated.json
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./files/rpcd.config $(1)/etc/config/rpcd
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) ./files/50-migrate-rpcd-ubus-sock.sh $(1)/etc/uci-defaults
|
||||
endef
|
||||
|
||||
|
||||
# 1: plugin name
|
||||
# 2: additional dependencies
|
||||
# 3: plugin title/description
|
||||
# 4: extra dependencies
|
||||
define BuildPlugin
|
||||
|
||||
PKG_CONFIG_DEPENDS += CONFIG_PACKAGE_rpcd-mod-$(1)
|
||||
|
||||
define Package/rpcd-mod-$(1)
|
||||
$(Package/rpcd/default)
|
||||
TITLE+= ($(1) plugin)
|
||||
DEPENDS+=rpcd $(2)
|
||||
EXTRA_DEPENDS:=$(4)
|
||||
endef
|
||||
|
||||
define Package/rpcd-mod-$(1)/description
|
||||
$(3)
|
||||
endef
|
||||
|
||||
define Package/rpcd-mod-$(1)/postinst
|
||||
#!/bin/sh
|
||||
[ -n "$$$${IPKG_INSTROOT}" ] || /etc/init.d/rpcd reload
|
||||
endef
|
||||
|
||||
define Package/rpcd-mod-$(1)/install
|
||||
$(INSTALL_DIR) $$(1)/usr/lib/rpcd
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(1).so $$(1)/usr/lib/rpcd/
|
||||
endef
|
||||
|
||||
$$(eval $$(call BuildPackage,rpcd-mod-$(1)))
|
||||
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,rpcd))
|
||||
$(eval $(call BuildPlugin,file,,Provides ubus calls for file and directory operations.))
|
||||
$(eval $(call BuildPlugin,rpcsys,,Provides ubus calls for sysupgrade and password changing.))
|
||||
$(eval $(call BuildPlugin,iwinfo,+libiwinfo,Provides ubus calls for accessing iwinfo data.,libiwinfo (>=2023.01.21)))
|
||||
$(eval $(call BuildPlugin,ucode,+libucode,Allows implementing plugins using ucode scripts.))
|
||||
8
package/system/rpcd/files/50-migrate-rpcd-ubus-sock.sh
Executable file
8
package/system/rpcd/files/50-migrate-rpcd-ubus-sock.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "$(uci get rpcd.@rpcd[0].socket)" = "/var/run/ubus.sock" ] || exit 0
|
||||
|
||||
uci set rpcd.@rpcd[0].socket='/var/run/ubus/ubus.sock'
|
||||
uci commit rpcd
|
||||
|
||||
exit 0
|
||||
10
package/system/rpcd/files/rpcd.config
Normal file
10
package/system/rpcd/files/rpcd.config
Normal file
@@ -0,0 +1,10 @@
|
||||
config rpcd
|
||||
option socket /var/run/ubus/ubus.sock
|
||||
option timeout 30
|
||||
|
||||
config login
|
||||
option username 'root'
|
||||
option password '$p$root'
|
||||
list read '*'
|
||||
list write '*'
|
||||
|
||||
21
package/system/rpcd/files/rpcd.init
Executable file
21
package/system/rpcd/files/rpcd.init
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=12
|
||||
|
||||
USE_PROCD=1
|
||||
NAME=rpcd
|
||||
PROG=/sbin/rpcd
|
||||
|
||||
start_service() {
|
||||
local socket=$(uci -q get rpcd.@rpcd[0].socket)
|
||||
local timeout=$(uci -q get rpcd.@rpcd[0].timeout)
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command "$PROG" ${socket:+-s "$socket"} ${timeout:+-t "$timeout"}
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
procd_send_signal rpcd
|
||||
}
|
||||
54
package/system/selinux-policy/Makefile
Normal file
54
package/system/selinux-policy/Makefile
Normal file
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=selinux-policy
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://git.defensec.nl/selinux-policy.git
|
||||
PKG_VERSION:=1.2.5
|
||||
PKG_MIRROR_HASH:=0b485aefed7ecc1ba3c5f5843cb3b10e9d7c55c09b361cd56933081c0dbdc223
|
||||
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
|
||||
PKG_BUILD_DEPENDS:=secilc/host policycoreutils/host
|
||||
|
||||
PKG_MAINTAINER:=Dominick Grift <dominick.grift@defensec.nl>
|
||||
PKG_CPE_ID:=cpe:/a:defensec:selinux-policy
|
||||
PKG_LICENSE:=Unlicense
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/selinux-policy
|
||||
SECTION:=system
|
||||
CATEGORY:=Base system
|
||||
TITLE:=SELinux security policy for OpenWrt
|
||||
URL:=https://git.defensec.nl/?p=selinux-policy.git;a=summary
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/selinux-policy/description
|
||||
Basic SELinux Security Policy designed specifically for
|
||||
OpenWrt and written in Common Intermediate Language.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(call Build/Compile/Default,policy)
|
||||
endef
|
||||
|
||||
define Package/selinux-policy/conffiles
|
||||
/etc/selinux/config
|
||||
endef
|
||||
|
||||
define Package/selinux-policy/install
|
||||
$(INSTALL_DIR) $(1)/etc/selinux/$(PKG_NAME)/contexts/files/
|
||||
$(INSTALL_DIR) $(1)/etc/selinux/$(PKG_NAME)/policy/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/customizable_types $(1)/etc/selinux/$(PKG_NAME)/contexts/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/file_contexts.subs_dist $(1)/etc/selinux/$(PKG_NAME)/contexts/files/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/file_contexts $(1)/etc/selinux/$(PKG_NAME)/contexts/files/
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/policy.* $(1)/etc/selinux/$(PKG_NAME)/policy/
|
||||
$(INSTALL_DATA) ./files/selinux-config $(1)/etc/selinux/config
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,selinux-policy))
|
||||
2
package/system/selinux-policy/files/selinux-config
Normal file
2
package/system/selinux-policy/files/selinux-config
Normal file
@@ -0,0 +1,2 @@
|
||||
SELINUX=enforcing
|
||||
SELINUXTYPE=selinux-policy
|
||||
77
package/system/ubox/Makefile
Normal file
77
package/system/ubox/Makefile
Normal file
@@ -0,0 +1,77 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ubox
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubox.git
|
||||
PKG_SOURCE_DATE:=2024-04-26
|
||||
PKG_SOURCE_VERSION:=85f1053019caf4cd333795760950235ee4529ba7
|
||||
PKG_MIRROR_HASH:=9e3fb6ab94854405fb91626a673b0547a061582c552ce719691be1bc8818da6c
|
||||
CMAKE_INSTALL:=1
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/ubox
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+libubox +ubusd +ubus +libubus +libuci
|
||||
TITLE:=OpenWrt system helper toolbox
|
||||
ALTERNATIVES:=\
|
||||
100:/sbin/rmmod:/sbin/kmodloader \
|
||||
100:/sbin/insmod:/sbin/kmodloader \
|
||||
100:/sbin/lsmod:/sbin/kmodloader \
|
||||
100:/sbin/modinfo:/sbin/kmodloader \
|
||||
100:/sbin/modprobe:/sbin/kmodloader
|
||||
endef
|
||||
|
||||
define Package/ubox/conffiles
|
||||
/etc/modules.conf
|
||||
endef
|
||||
|
||||
define Package/getrandom
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=OpenWrt getrandom system helper
|
||||
endef
|
||||
|
||||
define Package/logd
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+libubox +libubus +libblobmsg-json +libudebug
|
||||
TITLE:=OpenWrt system log implementation
|
||||
USERID:=logd=514:logd=514
|
||||
ALTERNATIVES:=200:/sbin/logread:/usr/libexec/logread-ubox
|
||||
endef
|
||||
|
||||
define Package/getrandom/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/getrandom $(1)/usr/bin/
|
||||
endef
|
||||
|
||||
define Package/ubox/install
|
||||
$(INSTALL_DIR) $(1)/sbin $(1)/usr/sbin $(1)/lib $(1)/usr/bin $(1)/etc
|
||||
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{kmodloader,validate_data} $(1)/sbin/
|
||||
$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libvalidate.so $(1)/lib
|
||||
$(INSTALL_DATA) ./files/modules.conf $(1)/etc/modules.conf
|
||||
endef
|
||||
|
||||
define Package/logd/install
|
||||
$(INSTALL_DIR) $(1)/sbin $(1)/usr/libexec/ $(1)/etc/init.d/ $(1)/usr/share/acl.d
|
||||
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/logd $(1)/sbin/
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/logread $(1)/usr/libexec/logread-ubox
|
||||
$(INSTALL_BIN) ./files/log.init $(1)/etc/init.d/log
|
||||
$(INSTALL_DATA) ./files/logd.json $(1)/usr/share/acl.d
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ubox))
|
||||
$(eval $(call BuildPackage,getrandom))
|
||||
$(eval $(call BuildPackage,logd))
|
||||
112
package/system/ubox/files/log.init
Normal file
112
package/system/ubox/files/log.init
Normal file
@@ -0,0 +1,112 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2013 OpenWrt.org
|
||||
|
||||
# start after and stop before networking
|
||||
START=12
|
||||
STOP=89
|
||||
PIDCOUNT=0
|
||||
|
||||
USE_PROCD=1
|
||||
PROG=/sbin/logread
|
||||
|
||||
validate_log_section()
|
||||
{
|
||||
uci_load_validate system system "$1" "$2" \
|
||||
'log_file:string' \
|
||||
'log_size:uinteger' \
|
||||
'log_hostname:string' \
|
||||
'log_ip:host' \
|
||||
'log_remote:bool:1' \
|
||||
'log_port:port:514' \
|
||||
'log_proto:or("tcp", "udp"):udp' \
|
||||
'log_trailer_null:bool:0' \
|
||||
'log_prefix:string'
|
||||
}
|
||||
|
||||
validate_log_daemon()
|
||||
{
|
||||
uci_load_validate system system "$1" "$2" \
|
||||
'log_size:uinteger:0' \
|
||||
'log_buffer_size:uinteger:0'
|
||||
}
|
||||
|
||||
start_service_daemon()
|
||||
{
|
||||
[ $log_buffer_size -eq 0 -a $log_size -gt 0 ] && log_buffer_size=$log_size
|
||||
[ $log_buffer_size -eq 0 ] && log_buffer_size=64
|
||||
procd_open_instance logd
|
||||
procd_set_param command "/sbin/logd"
|
||||
procd_append_param command -S "${log_buffer_size}"
|
||||
procd_set_param respawn 5 1 -1
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
start_service_file()
|
||||
{
|
||||
PIDCOUNT="$(( ${PIDCOUNT} + 1))"
|
||||
local pid_file="/var/run/logread.${PIDCOUNT}.pid"
|
||||
|
||||
[ "$2" = 0 ] || {
|
||||
echo "validation failed"
|
||||
return 1
|
||||
}
|
||||
[ -z "${log_file}" ] && return
|
||||
|
||||
[ "$_BOOT" = "1" ] &&
|
||||
[ "$(procd_get_mountpoints "${log_file}")" ] && return 0
|
||||
|
||||
mkdir -p "$(dirname "${log_file}")"
|
||||
|
||||
procd_open_instance logfile
|
||||
procd_set_param command "$PROG" -f -F "$log_file" -p "$pid_file"
|
||||
[ -n "${log_size}" ] && procd_append_param command -S "$log_size"
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
start_service_remote()
|
||||
{
|
||||
PIDCOUNT="$(( ${PIDCOUNT} + 1))"
|
||||
local pid_file="/var/run/logread.${PIDCOUNT}.pid"
|
||||
|
||||
[ "$2" = 0 ] || {
|
||||
echo "validation failed"
|
||||
return 1
|
||||
}
|
||||
[ "${log_remote}" -ne 0 ] || return
|
||||
[ -z "${log_ip}" ] && return
|
||||
[ -z "${log_hostname}" ] && log_hostname=$(cat /proc/sys/kernel/hostname)
|
||||
|
||||
procd_open_instance logremote
|
||||
procd_set_param command "$PROG" -f -h "$log_hostname" -r "$log_ip" "${log_port}" -p "$pid_file"
|
||||
case "${log_proto}" in
|
||||
"udp") procd_append_param command -u;;
|
||||
"tcp") [ "${log_trailer_null}" -eq 1 ] && procd_append_param command -0;;
|
||||
esac
|
||||
[ -z "${log_prefix}" ] || procd_append_param command -P "${log_prefix}"
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
register_mount_trigger()
|
||||
{
|
||||
[ -n "${log_file}" ] && procd_add_action_mount_trigger start "${log_file}"
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
config_load system
|
||||
procd_add_reload_trigger "system"
|
||||
procd_add_validation validate_log_section
|
||||
config_foreach validate_log_section system register_mount_trigger
|
||||
}
|
||||
|
||||
start_service()
|
||||
{
|
||||
config_load system
|
||||
config_foreach validate_log_daemon system start_service_daemon
|
||||
config_foreach validate_log_section system start_service_file
|
||||
config_foreach validate_log_section system start_service_remote
|
||||
}
|
||||
|
||||
boot() {
|
||||
_BOOT=1 start
|
||||
}
|
||||
4
package/system/ubox/files/logd.json
Normal file
4
package/system/ubox/files/logd.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"user": "logd",
|
||||
"publish": [ "log" ]
|
||||
}
|
||||
3
package/system/ubox/files/modules.conf
Normal file
3
package/system/ubox/files/modules.conf
Normal file
@@ -0,0 +1,3 @@
|
||||
# examples:
|
||||
# options mod1 option=val
|
||||
# blacklist mod2
|
||||
83
package/system/ubus/Makefile
Normal file
83
package/system/ubus/Makefile
Normal file
@@ -0,0 +1,83 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ubus
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubus.git
|
||||
PKG_SOURCE_DATE:=2023-11-28
|
||||
PKG_SOURCE_VERSION:=f84eb5998c6ea2d34989ca2d3254e56c66139313
|
||||
PKG_MIRROR_HASH:=c9f6118b98550802893c7c0b497f2215dbfd863d819fabc9df2aa57ce29a5fd2
|
||||
PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
|
||||
CMAKE_INSTALL:=1
|
||||
|
||||
PKG_LICENSE:=LGPL-2.1
|
||||
PKG_LICENSE_FILES:=
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
PKG_BUILD_FLAGS:=lto
|
||||
PKG_ASLR_PIE_REGULAR:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/ubus
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+libubus +libblobmsg-json +ubusd
|
||||
TITLE:=OpenWrt RPC client utility
|
||||
endef
|
||||
|
||||
define Package/ubusd
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
TITLE:=OpenWrt RPC daemon
|
||||
DEPENDS:=+libubox +libblobmsg-json
|
||||
USERID:=ubus=81:ubus=81
|
||||
endef
|
||||
|
||||
define Package/libubus
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
DEPENDS:=+libubox
|
||||
ABI_VERSION:=$(PKG_ABI_VERSION)
|
||||
TITLE:=OpenWrt RPC client library
|
||||
endef
|
||||
|
||||
define Package/libubus-lua
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
DEPENDS:=+libubus +liblua
|
||||
TITLE:=Lua binding for the OpenWrt RPC client
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
|
||||
|
||||
CMAKE_OPTIONS += \
|
||||
-DLUAPATH=/usr/lib/lua \
|
||||
-DABIVERSION="$(PKG_ABI_VERSION)"
|
||||
|
||||
define Package/ubus/install
|
||||
$(INSTALL_DIR) $(1)/bin
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/bin/ubus $(1)/bin/
|
||||
endef
|
||||
|
||||
define Package/ubusd/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/sbin/ubusd $(1)/sbin/
|
||||
endef
|
||||
|
||||
define Package/libubus/install
|
||||
$(INSTALL_DIR) $(1)/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libubus.so.* $(1)/lib/
|
||||
endef
|
||||
|
||||
define Package/libubus-lua/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua
|
||||
$(CP) $(PKG_BUILD_DIR)/lua/ubus.so $(1)/usr/lib/lua/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libubus))
|
||||
$(eval $(call BuildPackage,libubus-lua))
|
||||
$(eval $(call BuildPackage,ubus))
|
||||
$(eval $(call BuildPackage,ubusd))
|
||||
71
package/system/ucert/Makefile
Normal file
71
package/system/ucert/Makefile
Normal file
@@ -0,0 +1,71 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ucert
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/ucert.git
|
||||
PKG_SOURCE_DATE:=2020-05-24
|
||||
PKG_SOURCE_VERSION:=00b921d80ac0dc47339305d803f865ff43c56d63
|
||||
PKG_MIRROR_HASH:=45391983bd5ec9bf03004f31388f01b84ad1a564e16b71acf1b1b26a6055e721
|
||||
|
||||
CMAKE_INSTALL:=1
|
||||
PKG_CHECK_FORMAT_SECURITY:=1
|
||||
|
||||
PKG_LICENSE:=GPL-3.0+
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
CMAKE_HOST_OPTIONS += \
|
||||
-DUCERT_FULL=1 \
|
||||
-DUCERT_HOST_BUILD=1 \
|
||||
-DCMAKE_SKIP_RPATH=FALSE \
|
||||
-DUSE_RPATH="${STAGING_DIR_HOST}/lib"
|
||||
|
||||
HOST_BUILD_DEPENDS:=libubox/host libjson-c/host usign/host
|
||||
HOST_BUILD_PREFIX:=$(STAGING_DIR_HOST)
|
||||
PKG_BUILD_DEPENDS:=ucert/host
|
||||
|
||||
define Package/ucert-full
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+usign +libubox +libjson-c +libblobmsg-json
|
||||
TITLE:=OpenWrt certificate generation and verification utility
|
||||
PROVIDES:=ucert
|
||||
VARIANT:=full
|
||||
endef
|
||||
|
||||
define Package/ucert
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+usign +libubox
|
||||
TITLE:=OpenWrt certificate verification utility
|
||||
PROVIDES:=ucert
|
||||
CONFLICTS:=ucert-full
|
||||
VARIANT:=tiny
|
||||
endef
|
||||
|
||||
ifeq ($(BUILD_VARIANT),full)
|
||||
CMAKE_OPTIONS += -DUCERT_FULL=1
|
||||
endif
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(call Build/Prepare/Default)
|
||||
endef
|
||||
|
||||
define Package/ucert/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/ucert $(1)/usr/bin
|
||||
endef
|
||||
|
||||
Package/ucert-full/install = $(Package/ucert/install)
|
||||
|
||||
$(eval $(call BuildPackage,ucert))
|
||||
$(eval $(call BuildPackage,ucert-full))
|
||||
$(eval $(call HostBuild))
|
||||
87
package/system/uci/Makefile
Normal file
87
package/system/uci/Makefile
Normal file
@@ -0,0 +1,87 @@
|
||||
#
|
||||
# Copyright (C) 2008-2014 OpenWrt.org
|
||||
# Copyright (C) 2016 LEDE project
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=uci
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/uci.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2023-08-10
|
||||
PKG_SOURCE_VERSION:=5781664d5087ccc4b5ab58505883231212dbedbc
|
||||
PKG_MIRROR_HASH:=0ca4a29c077e85a7cfe69916c3ceb2bee98662b6268befc3c02519939647f984
|
||||
|
||||
PKG_LICENSE:=LGPL-2.1
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
# set to 1 to enable debugging
|
||||
DEBUG=
|
||||
|
||||
define Package/libuci
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
TITLE:=C library for the Unified Configuration Interface (UCI)
|
||||
DEPENDS:=+libubox
|
||||
ABI_VERSION:=20130104
|
||||
endef
|
||||
|
||||
define Package/uci
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+libuci
|
||||
TITLE:=Utility for the Unified Configuration Interface (UCI)
|
||||
endef
|
||||
|
||||
define Package/libuci-lua
|
||||
SECTION=libs
|
||||
CATEGORY=Libraries
|
||||
DEPENDS:=+libuci +liblua
|
||||
TITLE:=Lua plugin for UCI
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
|
||||
TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib
|
||||
|
||||
CMAKE_OPTIONS += \
|
||||
-DLUAPATH=/usr/lib/lua \
|
||||
$(if $(DEBUG),-DUCI_DEBUG=ON)
|
||||
|
||||
define Package/libuci/install
|
||||
$(INSTALL_DIR) $(1)/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/libuci.so* $(1)/lib/
|
||||
endef
|
||||
|
||||
define Package/libuci-lua/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua
|
||||
$(CP) $(PKG_BUILD_DIR)/lua/uci.so $(1)/usr/lib/lua/
|
||||
endef
|
||||
|
||||
define Package/uci/install
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/uci $(1)/sbin/
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(CP) $(PKG_BUILD_DIR)/uci{,_config,_blob,map}.h $(1)/usr/include
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/libuci.so* $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/libucimap.a $(1)/usr/lib
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libuci))
|
||||
$(eval $(call BuildPackage,libuci-lua))
|
||||
$(eval $(call BuildPackage,uci))
|
||||
163
package/system/uci/files/lib/config/uci.sh
Normal file
163
package/system/uci/files/lib/config/uci.sh
Normal file
@@ -0,0 +1,163 @@
|
||||
# Shell script compatibility wrappers for /sbin/uci
|
||||
#
|
||||
# Copyright (C) 2008-2010 OpenWrt.org
|
||||
# Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
CONFIG_APPEND=
|
||||
uci_load() {
|
||||
local PACKAGE="$1"
|
||||
local DATA
|
||||
local RET
|
||||
local VAR
|
||||
|
||||
_C=0
|
||||
if [ -z "$CONFIG_APPEND" ]; then
|
||||
for VAR in $CONFIG_LIST_STATE; do
|
||||
export ${NO_EXPORT:+-n} CONFIG_${VAR}=
|
||||
export ${NO_EXPORT:+-n} CONFIG_${VAR}_LENGTH=
|
||||
done
|
||||
export ${NO_EXPORT:+-n} CONFIG_LIST_STATE=
|
||||
export ${NO_EXPORT:+-n} CONFIG_SECTIONS=
|
||||
export ${NO_EXPORT:+-n} CONFIG_NUM_SECTIONS=0
|
||||
export ${NO_EXPORT:+-n} CONFIG_SECTION=
|
||||
fi
|
||||
|
||||
DATA="$(/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} ${LOAD_STATE:+-P /var/state} -S -n export "$PACKAGE" 2>/dev/null)"
|
||||
RET="$?"
|
||||
[ "$RET" != 0 -o -z "$DATA" ] || eval "$DATA"
|
||||
unset DATA
|
||||
|
||||
${CONFIG_SECTION:+config_cb}
|
||||
return "$RET"
|
||||
}
|
||||
|
||||
uci_set_default() {
|
||||
local PACKAGE="$1"
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -q show "$PACKAGE" > /dev/null && return 0
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} import "$PACKAGE"
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} commit "$PACKAGE"
|
||||
}
|
||||
|
||||
uci_revert_state() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state revert "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
|
||||
}
|
||||
|
||||
uci_set_state() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
local VALUE="$4"
|
||||
|
||||
[ "$#" = 4 ] || return 0
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} -P /var/state set "$PACKAGE.$CONFIG${OPTION:+.$OPTION}=$VALUE"
|
||||
}
|
||||
|
||||
uci_toggle_state() {
|
||||
uci_revert_state "$1" "$2" "$3"
|
||||
uci_set_state "$1" "$2" "$3" "$4"
|
||||
}
|
||||
|
||||
uci_set() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
local VALUE="$4"
|
||||
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} set "$PACKAGE.$CONFIG.$OPTION=$VALUE"
|
||||
}
|
||||
|
||||
uci_add_list() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
local VALUE="$4"
|
||||
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} add_list "$PACKAGE.$CONFIG.$OPTION=$VALUE"
|
||||
}
|
||||
|
||||
uci_get_state() {
|
||||
uci_get "$1" "$2" "$3" "$4" "/var/state"
|
||||
}
|
||||
|
||||
uci_get() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
local DEFAULT="$4"
|
||||
local STATE="$5"
|
||||
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} ${STATE:+-P $STATE} -q get "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
|
||||
RET="$?"
|
||||
[ "$RET" -ne 0 ] && [ -n "$DEFAULT" ] && echo "$DEFAULT"
|
||||
return "$RET"
|
||||
}
|
||||
|
||||
uci_add() {
|
||||
local PACKAGE="$1"
|
||||
local TYPE="$2"
|
||||
local CONFIG="$3"
|
||||
|
||||
if [ -z "$CONFIG" ]; then
|
||||
export ${NO_EXPORT:+-n} CONFIG_SECTION="$(/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} add "$PACKAGE" "$TYPE")"
|
||||
else
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} set "$PACKAGE.$CONFIG=$TYPE"
|
||||
export ${NO_EXPORT:+-n} CONFIG_SECTION="$CONFIG"
|
||||
fi
|
||||
}
|
||||
|
||||
uci_rename() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
local VALUE="$4"
|
||||
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} rename "$PACKAGE.$CONFIG${VALUE:+.$OPTION}=${VALUE:-$OPTION}"
|
||||
}
|
||||
|
||||
uci_remove() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} del "$PACKAGE.$CONFIG${OPTION:+.$OPTION}"
|
||||
}
|
||||
|
||||
uci_remove_list() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
local VALUE="$4"
|
||||
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} del_list "$PACKAGE.$CONFIG.$OPTION=$VALUE"
|
||||
}
|
||||
|
||||
uci_revert() {
|
||||
local PACKAGE="$1"
|
||||
local CONFIG="$2"
|
||||
local OPTION="$3"
|
||||
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} revert "$PACKAGE${CONFIG:+.$CONFIG}${OPTION:+.$OPTION}"
|
||||
}
|
||||
|
||||
uci_commit() {
|
||||
local PACKAGE="$1"
|
||||
/sbin/uci ${UCI_CONFIG_DIR:+-c $UCI_CONFIG_DIR} commit $PACKAGE
|
||||
}
|
||||
32
package/system/urandom-seed/Makefile
Normal file
32
package/system/urandom-seed/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=urandom-seed
|
||||
PKG_RELEASE:=3
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/urandom-seed
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+getrandom
|
||||
TITLE:=/etc/urandom.seed handling for OpenWrt
|
||||
URL:=https://openwrt.org/
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
endef
|
||||
|
||||
define Build/Quilt
|
||||
endef
|
||||
|
||||
define Build/Compile/Default
|
||||
endef
|
||||
Build/Compile = $(Build/Compile/Default)
|
||||
|
||||
define Package/urandom-seed/install
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,urandom-seed))
|
||||
12
package/system/urandom-seed/files/etc/init.d/urandom_seed
Executable file
12
package/system/urandom-seed/files/etc/init.d/urandom_seed
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
start_service() {
|
||||
procd_open_instance "urandom_seed"
|
||||
procd_set_param command "/sbin/urandom_seed"
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
log_urandom_seed() {
|
||||
echo "urandom-seed: $1" > /dev/kmsg
|
||||
}
|
||||
|
||||
_do_urandom_seed() {
|
||||
[ -f "$1" ] || { log_urandom_seed "Seed file not found ($1)"; return; }
|
||||
[ -O "$1" -a -G "$1" -a ! -x "$1" ] || { log_urandom_seed "Wrong owner / permissions for $1"; return; }
|
||||
|
||||
log_urandom_seed "Seeding with $1"
|
||||
cat "$1" > /dev/urandom
|
||||
}
|
||||
|
||||
do_urandom_seed() {
|
||||
[ -c /dev/urandom ] || { log_urandom_seed "Something is wrong with /dev/urandom"; return; }
|
||||
|
||||
_do_urandom_seed "/etc/urandom.seed"
|
||||
|
||||
SEED="$(uci -q get system.@system[0].urandom_seed)"
|
||||
[ "${SEED:0:1}" = "/" -a "$SEED" != "/etc/urandom.seed" ] && _do_urandom_seed "$SEED"
|
||||
}
|
||||
|
||||
boot_hook_add preinit_main do_urandom_seed
|
||||
20
package/system/urandom-seed/files/sbin/urandom_seed
Executable file
20
package/system/urandom-seed/files/sbin/urandom_seed
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
trap '[ "$?" -eq 0 ] || echo "An error occured" >&2' EXIT
|
||||
|
||||
save() {
|
||||
touch "$1.tmp"
|
||||
chown root:root "$1.tmp"
|
||||
chmod 600 "$1.tmp"
|
||||
getrandom 512 > "$1.tmp"
|
||||
mv "$1.tmp" "$1"
|
||||
echo "Seed saved ($1)"
|
||||
}
|
||||
|
||||
SEED="$(uci -q get system.@system[0].urandom_seed || true)"
|
||||
[ "${SEED:0:1}" = "/" ] && save "$SEED"
|
||||
|
||||
SEED=/etc/urandom.seed
|
||||
[ ! -f $SEED ] && save "$SEED"
|
||||
true
|
||||
46
package/system/urngd/Makefile
Normal file
46
package/system/urngd/Makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=urngd
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/urngd.git
|
||||
PKG_SOURCE_DATE:=2023-11-01
|
||||
PKG_SOURCE_VERSION:=44365eb1e1165f2a44cb31f404b04cf85031718e
|
||||
PKG_MIRROR_HASH:=b153530c4e66d1b0fe7d98b0ec24df580964f24a756e754323e3fa297eed1229
|
||||
|
||||
PKG_LICENSE:=GPL-2.0 BSD-3-Clause
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/urngd
|
||||
SECTION:=utils
|
||||
CATEGORY:=Base system
|
||||
TITLE:=OpenWrt non-physical true random number generator based on timing jitter
|
||||
DEPENDS:=+libubox
|
||||
endef
|
||||
|
||||
define Package/urngd/description
|
||||
urngd is OpenWrt's micro non-physical true random number generator based on
|
||||
timing jitter.
|
||||
|
||||
Using the Jitter RNG core, the rngd provides an entropy source that feeds into
|
||||
the Linux /dev/random device if its entropy runs low. It updates the
|
||||
/dev/random entropy estimator such that the newly provided entropy unblocks
|
||||
/dev/random.
|
||||
|
||||
The seeding of /dev/random also ensures that /dev/urandom benefits from
|
||||
entropy. Especially during boot time, when the entropy of Linux is low, the
|
||||
Jitter RNGd provides a source of sufficient entropy.
|
||||
endef
|
||||
|
||||
define Package/urngd/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/$(PKG_NAME).init $(1)/etc/init.d/$(PKG_NAME)
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/sbin/$(PKG_NAME)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,urngd))
|
||||
17
package/system/urngd/files/urngd.init
Normal file
17
package/system/urngd/files/urngd.init
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=00
|
||||
|
||||
USE_PROCD=1
|
||||
NAME=urngd
|
||||
PROG=/sbin/urngd
|
||||
|
||||
start_service() {
|
||||
procd_open_instance
|
||||
procd_set_param command "$PROG"
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
procd_send_signal $PROG
|
||||
}
|
||||
44
package/system/usign/Makefile
Normal file
44
package/system/usign/Makefile
Normal file
@@ -0,0 +1,44 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=usign
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/usign.git
|
||||
PKG_SOURCE_DATE:=2020-05-23
|
||||
PKG_SOURCE_VERSION:=f1f65026a94137c91b5466b149ef3ea3f20091e9
|
||||
PKG_MIRROR_HASH:=3157ad9e0ebe0512644fbd00191d97a91809f03c3deca67200845a5d07aa721f
|
||||
CMAKE_INSTALL:=1
|
||||
PKG_CHECK_FORMAT_SECURITY:=1
|
||||
PKG_BUILD_FLAGS:=no-mips16 lto
|
||||
|
||||
PKG_LICENSE:=ISC
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
HOST_BUILD_PREFIX:=$(STAGING_DIR_HOST)
|
||||
|
||||
define Package/usign
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+libubox
|
||||
TITLE:=OpenWrt signature verification utility
|
||||
endef
|
||||
|
||||
CMAKE_OPTIONS += \
|
||||
-DUSE_LIBUBOX=on
|
||||
|
||||
define Package/usign/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/usign $(1)/usr/bin
|
||||
ln -s usign $(1)/usr/bin/signify
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,usign))
|
||||
$(eval $(call HostBuild))
|
||||
48
package/system/zram-swap/Makefile
Normal file
48
package/system/zram-swap/Makefile
Normal file
@@ -0,0 +1,48 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Copyright (C) 2013-2021 OpenWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=zram-swap
|
||||
PKG_RELEASE:=32
|
||||
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/zram-swap
|
||||
SECTION:=utils
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:= \
|
||||
+@BUSYBOX_CONFIG_FEATURE_SWAPON_DISCARD \
|
||||
+@BUSYBOX_CONFIG_FEATURE_SWAPON_PRI \
|
||||
+@BUSYBOX_CONFIG_MKSWAP \
|
||||
+@BUSYBOX_CONFIG_SWAPOFF \
|
||||
+@BUSYBOX_CONFIG_SWAPON \
|
||||
+kmod-zram
|
||||
TITLE:=ZRAM swap scripts
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/zram-swap/description
|
||||
A script to activate swaping on a compressed zram partition. This
|
||||
could be used to increase the available memory, by using compressed
|
||||
memory.
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/zram-swap/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/zram.init $(1)/etc/init.d/zram
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,zram-swap))
|
||||
190
package/system/zram-swap/files/zram.init
Executable file
190
package/system/zram-swap/files/zram.init
Executable file
@@ -0,0 +1,190 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=15
|
||||
|
||||
extra_command "compact" "Trigger compaction for all zram swap devices"
|
||||
extra_command "status" "Print out information & statistics about zram swap devices"
|
||||
|
||||
ram_getsize()
|
||||
{
|
||||
local line
|
||||
|
||||
while read line; do case "$line" in MemTotal:*) set $line; echo "$2"; break ;; esac; done </proc/meminfo
|
||||
}
|
||||
|
||||
zram_getsize() # in megabytes
|
||||
{
|
||||
local zram_size="$( uci -q get system.@system[0].zram_size_mb )"
|
||||
local ram_size="$( ram_getsize )"
|
||||
|
||||
if [ -z "$zram_size" ]; then
|
||||
# e.g. 6mb for 16mb-routers or 61mb for 128mb-routers
|
||||
echo $(( ram_size / 2048 ))
|
||||
else
|
||||
echo "$zram_size"
|
||||
fi
|
||||
}
|
||||
|
||||
zram_dev()
|
||||
{
|
||||
local idx="$1"
|
||||
echo "/dev/zram${idx:-0}"
|
||||
}
|
||||
|
||||
zram_reset()
|
||||
{
|
||||
local dev="$1"
|
||||
local message="$2"
|
||||
local proc_entry="/sys/block/$( basename "$dev" )/reset"
|
||||
|
||||
logger -s -t zram_reset -p daemon.debug "$message via $proc_entry"
|
||||
echo "1" >"$proc_entry"
|
||||
}
|
||||
|
||||
zram_getdev()
|
||||
{
|
||||
#get unallocated zram dev
|
||||
local zdev=$( zram_dev )
|
||||
|
||||
if [ "$(mount | grep $zdev)" ]; then
|
||||
local idx=$(cat /sys/class/zram-control/hot_add)
|
||||
zdev="$( zram_dev $idx )"
|
||||
fi
|
||||
|
||||
echo $zdev
|
||||
}
|
||||
|
||||
zram_comp_algo()
|
||||
{
|
||||
local dev="$1"
|
||||
local zram_comp_algo="$( uci -q get system.@system[0].zram_comp_algo )"
|
||||
|
||||
if [ -z "$zram_comp_algo" ]; then
|
||||
# default to lzo, which is always available
|
||||
zram_comp_algo="lzo"
|
||||
fi
|
||||
|
||||
if [ $(grep -c "$zram_comp_algo" /sys/block/$( basename $dev )/comp_algorithm) -ne 0 ]; then
|
||||
logger -s -t zram_comp_algo -p daemon.debug "set compression algorithm '$zram_comp_algo' for zram '$dev'"
|
||||
echo $zram_comp_algo > "/sys/block/$( basename $dev )/comp_algorithm"
|
||||
else
|
||||
logger -s -t zram_comp_algo -p daemon.debug "compression algorithm '$zram_comp_algo' is not supported for '$dev'"
|
||||
fi
|
||||
}
|
||||
|
||||
#print various stats info about zram swap device
|
||||
zram_stats()
|
||||
{
|
||||
local zdev="/sys/block/$( basename "$1" )"
|
||||
|
||||
printf "\nGathering stats info for zram device \"$( basename "$1" )\"\n\n"
|
||||
|
||||
printf "ZRAM\n----\n"
|
||||
printf "%-25s - %s\n" "Block device" $zdev
|
||||
awk '{ printf "%-25s - %d MiB\n", "Device size", $1/1024/1024 }' <$zdev/disksize
|
||||
printf "%-25s - %s\n" "Compression algo" "$(cat $zdev/comp_algorithm)"
|
||||
|
||||
awk 'BEGIN { fmt = "%-25s - %.2f %s\n"
|
||||
fmt2 = "%-25s - %d\n"
|
||||
print "\nDATA\n----" }
|
||||
{ printf fmt, "Original data size", $1/1024/1024, "MiB"
|
||||
printf fmt, "Compressed data size", $2/1024/1024, "MiB"
|
||||
printf fmt, "Compress ratio", $1/$2, ""
|
||||
print "\nMEMORY\n------"
|
||||
printf fmt, "Memory used, total", $3/1024/1024, "MiB"
|
||||
printf fmt, "Allocator overhead", ($3-$2)/1024/1024, "MiB"
|
||||
printf fmt, "Allocator efficiency", $2/$3*100, "%"
|
||||
printf fmt, "Maximum memory ever used", $5/1024/1024, "MiB"
|
||||
printf fmt, "Memory limit", $4/1024/1024, "MiB"
|
||||
print "\nPAGES\n-----"
|
||||
printf fmt2, "Same pages count", $6
|
||||
printf fmt2, "Pages compacted", $7 }' <$zdev/mm_stat
|
||||
|
||||
awk '{ printf "%-25s - %d\n", "Free pages discarded", $4 }' <$zdev/io_stat
|
||||
}
|
||||
|
||||
zram_compact()
|
||||
{
|
||||
# compact zram device (reduce memory allocation overhead)
|
||||
local zdev="/sys/block/$( basename "$1" )"
|
||||
|
||||
local old_mem_used=$(awk '{print $3}' <$zdev/mm_stat)
|
||||
local old_overhead=$(awk '{print $3-$2}' <$zdev/mm_stat)
|
||||
|
||||
echo 1 > $zdev/compact
|
||||
|
||||
# If not running interactively, than just return
|
||||
[ -z "$PS1" ] && return 0
|
||||
|
||||
echo ""
|
||||
echo "Compacting zram device $zdev"
|
||||
awk -v old_mem="$old_mem_used" -v ovr="$old_overhead" 'BEGIN { fmt = "%-25s - %.1f %s\n" }
|
||||
{ printf fmt, "Memory usage reduced by ", (old_mem-$3)/1024/1024, "MiB"
|
||||
printf fmt, "Overhead reduced by", (ovr-($3-$2))/ovr*100, "%" }' <$zdev/mm_stat
|
||||
}
|
||||
|
||||
start()
|
||||
{
|
||||
[ -e /proc/swaps ] || {
|
||||
logger -s -t zram_start -p daemon.crit "kernel doesn't support swap"
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ $( grep -cs zram /proc/swaps ) -ne 0 ]; then
|
||||
logger -s -t zram_start -p daemon.notice "zram swap is already mounted"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local zram_dev="$( zram_getdev )"
|
||||
|
||||
[ -e "$zram_dev" ] || {
|
||||
logger -s -t zram_start -p daemon.crit "[ERROR] device '$zram_dev' not found"
|
||||
return 1
|
||||
}
|
||||
|
||||
local zram_size="$( zram_getsize )"
|
||||
local zram_priority="$( uci -q get system.@system[0].zram_priority )"
|
||||
|
||||
if [ -z "$zram_priority" ]; then
|
||||
zram_priority="100"
|
||||
fi
|
||||
|
||||
logger -s -t zram_start -p daemon.debug "activating '$zram_dev' for swapping ($zram_size MiB)"
|
||||
|
||||
zram_reset "$zram_dev" "enforcing defaults"
|
||||
zram_comp_algo "$zram_dev"
|
||||
echo $(( $zram_size * 1024 * 1024 )) >"/sys/block/$( basename "$zram_dev" )/disksize"
|
||||
busybox mkswap "$zram_dev"
|
||||
busybox swapon -d -p $zram_priority "$zram_dev"
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
local zram_dev
|
||||
|
||||
for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
|
||||
logger -s -t zram_stop -p daemon.debug "deactivate swap $zram_dev"
|
||||
busybox swapoff "$zram_dev" && zram_reset "$zram_dev" "claiming memory back"
|
||||
local dev_index="$( echo $zram_dev | grep -o "[0-9]*$" )"
|
||||
if [ $dev_index -ne 0 ]; then
|
||||
logger -s -t zram_stop -p daemon.debug "removing zram $zram_dev"
|
||||
echo $dev_index > /sys/class/zram-control/hot_remove
|
||||
fi
|
||||
} done
|
||||
}
|
||||
|
||||
# show memory stats for all zram swaps
|
||||
status()
|
||||
{
|
||||
for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
|
||||
zram_stats "$zram_dev"
|
||||
} done
|
||||
}
|
||||
|
||||
# trigger compaction for all zram swaps
|
||||
compact()
|
||||
{
|
||||
for zram_dev in $( grep zram /proc/swaps |awk '{print $1}' ); do {
|
||||
zram_compact "$zram_dev"
|
||||
} done
|
||||
}
|
||||
Reference in New Issue
Block a user