diff options
23 files changed, 1880 insertions, 0 deletions
| diff --git a/target/linux/brcm47xx/base-files.mk b/target/linux/brcm47xx/base-files.mk new file mode 100644 index 000000000..d6682bd38 --- /dev/null +++ b/target/linux/brcm47xx/base-files.mk @@ -0,0 +1,5 @@ +define Package/base-files/install-target +	rm -f $(1)/etc/config/network +endef + + diff --git a/target/linux/brcm47xx/base-files/etc/diag.sh b/target/linux/brcm47xx/base-files/etc/diag.sh new file mode 100644 index 000000000..3b08554c6 --- /dev/null +++ b/target/linux/brcm47xx/base-files/etc/diag.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# Copyright (C) 2006 OpenWrt.org + +set_led() { +	local led="$1" +	local state="$2" +	[ -f "/proc/diag/led/$1" ] && echo "$state" > "/proc/diag/led/$1" +} + +set_state() { +	case "$1" in +		preinit) +			set_led dmz 1 +			set_led diag 1 +			set_led power 0 +		;; +		failsafe) +			set_led diag f +			set_led power f +			set_led dmz f +		;; +		done) +			set_led dmz 0 +			set_led diag 0 +			set_led power 1 +		;; +	esac +} diff --git a/target/linux/brcm47xx/base-files/etc/init.d/netconfig b/target/linux/brcm47xx/base-files/etc/init.d/netconfig new file mode 100755 index 000000000..d7839b6b4 --- /dev/null +++ b/target/linux/brcm47xx/base-files/etc/init.d/netconfig @@ -0,0 +1,248 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +START=05 + +start() { +	[ -e /etc/config/network ] && { +		local batch + +		config_cb() { +			case "$1" in +			switch) +				option_cb() { +					case "$1" in +					vlan[0-9]|vlan1[0-5]) +						local id="${1#vlan}" +						local ports="${2%\*}" +						append batch "delete network.eth0.${1}${N}" +						append batch "set network.eth0_${id}=switch_vlan${N}" +						append batch "set network.eth0_${id}.device=eth0${N}" +						append batch "set network.eth0_${id}.vlan=${id}${N}" +						append batch "set network.eth0_${id}.ports='${ports}'${N}" +					;; +					esac +				} +			;; +			switch_vlan) +				option_cb() { :; } +				batch="" +			;; +			esac +		} + +		config_load network + +		[ -n "$batch" ] && { +			logger -t netconfig "migrating switch config to new format ..." +			echo "$batch${N}commit network" | uci batch +		} + +		exit 0 +	} + +	mkdir -p /etc/config + +	( +		if grep -E 'mtd0: 000(6|a)0000' /proc/mtd 2>&- >&-; then +			# WGT634u +			echo boardtype=wgt634u +		else +			strings "$(find_mtd_part nvram)" +		fi +	) | awk ' +	function p(cfgname, name) { +		if (c[name] != "") print "	option " cfgname "	\"" c[name] "\"" +	} + +	function vlan(id, name) { +		if (c[name] != "") { +			print "config switch_vlan eth0_" id +			print "	option device   \"eth0\"" +			print "	option vlan     " id +			print "	option ports    \"" c[name] "\"" +			print "" +		} +	} + +	function macinc(mac, maca, i, result) { +		split(mac, maca, ":") +		for (i = 1; i <= 6; i++) maca[i] = "0x" maca[i] +		if (++maca[6] > 0xff) { +			maca[5]++ +			maca[6] = 0 +		} +		for (i = 1; i <= 6; i++) { +			if (i != 1) result = result ":" +			result = result sprintf("%02x", maca[i]) +		} +		return result +	} + +	BEGIN { +		FS="=" +		c["lan_ifname"]="eth0.0" +		c["wan_ifname"]="eth0.1" +		c["vlan0ports"]="1 2 3 4 5" +		c["vlan1ports"]="0 5" +		getline < "/proc/diag/model" +		model=$0 +		for (i = 0; i < 6; i++) { +			if (mac_check != "") mac_check = mac_check ":" +			mac_check = mac_check "[0-9a-fA-F][0-9a-fA-F]" +		} +	} + +	($1 == "boardnum") || ($1 == "boardtype") || ($1 == "boardflags") || ($1 ~ /macaddr/) { +		nvram[$1] = $2 +	} + +	END { +		if ((model == "ASUS WL-HDD") || (model == "ASUS WL-300g") || (model == "Linksys WAP54G V1")) { +			c["wan_ifname"] = "" +			c["lan_ifname"] = "eth1" +		} +		if (model == "ASUS WL-330gE") { +			c["wan_ifname"] = "" +			c["lan_ifname"] = "eth0" +			c["vlan0ports"] = "" +			c["vlan1ports"] = "" +		} +		if ((model == "ASUS WL-500g") || (model == "Microsoft MN-700")) { +			c["wan_ifname"] = "eth1" +			c["lan_ifname"] = "eth0" +		} +		if ((model == "ASUS WL-500g Premium V2") || (model == "Dell TrueMobile 2300 v2") || (model == "Buffalo WHR-G125")) { +			c["vlan0ports"] = "0 1 2 3 5" +			c["vlan1ports"] = "4 5" +		} +		if (model == "Dell TrueMobile 2300") { +			c["lan_ifname"] = "eth0" +			c["wan_ifname"] = "eth1" +			c["vlan0ports"] = "0 1 2 3 4 5u" +			c["vlan1ports"] = "" +		} +		if (nvram["boardtype"] == "bcm94710r4") { +			# Toshiba WRC-1000 +			c["lan_ifname"] = "eth0" +			c["wan_ifname"] = "eth1" +		} +		if ((nvram["boardtype"] == "wgt634u") || (nvram["boardtype"] == "0x0467")) { +			c["vlan0ports"] = "0 1 2 3 5" +			c["vlan1ports"] = "4 5" +		} +		if ((nvram["boardtype"] == "0x042f") || (nvram["boardtype"] == "0x0472")) { +			if (nvram["boardnum"] == "45") { +				# WL-500gP +				c["vlan0ports"] = "1 2 3 4 5" +				c["vlan1ports"] = "0 5" +			} else { +				# Generic BCM94704 +				c["vlan0ports"] = "0 1 2 3 4 5u" +				c["vlan1ports"] = "" +				c["lan_ifname"] = "eth0" +				c["wan_ifname"] = "eth1" + +				# MAC addresses on 4704 tend to be screwed up. Add a workaround here +				if (nvram["et0macaddr"] ~ mac_check) { +					c["lan_macaddr"] = nvram["et0macaddr"] +					c["wan_macaddr"] = macinc(c["lan_macaddr"]) +				} +			} +		} +		# Buffalo WBR-B11 and Buffalo WBR-G54 +		if (nvram["boardtype"] == "bcm94710ap") { +			c["vlan0ports"] = "0 1 2 3 4 5u" +			c["vlan1ports"] = "" +			c["lan_ifname"] = "eth0" +			c["wan_ifname"] = "eth1" +		} +		# generic broadcom 4705/4785 processor with 5397 switch? +		#  EXCEPT Linksys WRT300N V1.1 +		if ((nvram["boardtype"] == "0x478") && \ +		    (model != "Linksys WRT300N V1.1")) { +			c["vlan0ports"] = "1 2 3 4 8*" +			c["vlan1ports"] = "0 8" +		} + +		# WAP54G +		if ((nvram["boardnum"] == "2") || \ +			(nvram["boardnum"] == "1024")) { +			c["lan_ifname"]="eth0" +			c["wan_ifname"]="" +		} + +		# Sitecom WL-105b +		if ((nvram["boardum"] == "2") && \ +			(nvram["GemtekPmonVer"] == "1")) { +			c["lan_ifname"]="eth0" +			c["wan_ifname"]="" +		} + +		# ASUS WL-700gE +		# These are actually same as defaults above. For some reason this script applies +		# Generic BCM94704 settings instead so we revert to proper settings here. +		# Hopefully someone will fix this properly soon. +		if (model == "ASUS WL-700gE") { +			c["lan_ifname"]="eth0.0" +			c["wan_ifname"]="eth0.1" +			c["vlan0ports"]="1 2 3 4 5" +			c["vlan1ports"]="0 5" +		} + +		if (model == "Motorola WR850G V2/V3") { +			c["vlan0ports"]="0 1 2 3 5" +			c["vlan1ports"]="4 5" +		} +		if (model == "ASUS WL-500W") { +			c["lan_ifname"] = "eth0" +			c["wan_ifname"] = "eth1" +			c["vlan0ports"] = "0 1 2 3 4 5u" +			c["vlan1ports"] = "" +		} +		if (model == "OvisLink WL-1600GL") { +			c["lan_ifname"] = "eth0.0" +			c["wan_ifname"] = "eth0.1" +			c["vlan0ports"] = "0 1 2 3 5" +			c["vlan1ports"] = "4 5" +		} + +		if (c["vlan0ports"] || c["vlan1ports"]) { +			print "#### VLAN configuration " +			print "config switch eth0" +			print "	option enable   1" +			print ""		 +			vlan(0, "vlan0ports") +			vlan(1, "vlan1ports") +		} +		print "#### Loopback configuration" +		print "config interface loopback" +		print "	option ifname	\"lo\"" +		print "	option proto	static" +		print "	option ipaddr	127.0.0.1" +		print "	option netmask	255.0.0.0" +		print "" +		print "" +		print "#### LAN configuration" +		print "config interface lan" +		print "	option type 	bridge" +		p("ifname", "lan_ifname") +		p("macaddr", "lan_macaddr") +		print "	option proto	static" +		print "	option ipaddr	192.168.1.1" +		print "	option netmask	255.255.255.0" +		print "" +		print "" +		if (c["wan_ifname"]) { +			print "#### WAN configuration" +			print "config interface	wan" +			p("ifname", "wan_ifname") +			p("macaddr", "wan_macaddr") +			print "	option proto	dhcp" +		} else { +			print "#### WAN configuration (disabled)" +			print "#config interface wan" +			print "#	option proto	dhcp" +		} +	}' > /etc/config/network +} diff --git a/target/linux/brcm47xx/base-files/etc/init.d/wmacfixup b/target/linux/brcm47xx/base-files/etc/init.d/wmacfixup new file mode 100755 index 000000000..ee1b75220 --- /dev/null +++ b/target/linux/brcm47xx/base-files/etc/init.d/wmacfixup @@ -0,0 +1,33 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2010 OpenWrt.org + +START=41 + +boot() { +	[ -d /sys/class/ieee80211 ] || exit + +	commit=0 + +	fixup_wmac() { +		local cfg="$1" +		local cfmac + +		config_get cfmac "$cfg" macaddr + +		[ "$cfmac" != "00:90:4c:5f:00:2a" ] || { +			local nvmac="$(nvram get il0macaddr 2>/dev/null)" +			[ -n "$nvmac" ] && [ "$nvmac != "$cfmac ] && { +				uci set wireless.$cfg.macaddr="$nvmac" +				commit=1 +			} +		} +	} + +	config_load wireless +	config_foreach fixup_wmac wifi-device + +	[ "$commit" = 1 ] && uci commit wireless +} + +start() { :; } +stop()  { :; } diff --git a/target/linux/brcm47xx/base-files/lib/preinit/03_init_hotplug_failsafe_brcm b/target/linux/brcm47xx/base-files/lib/preinit/03_init_hotplug_failsafe_brcm new file mode 100644 index 000000000..b0f4a4efa --- /dev/null +++ b/target/linux/brcm47xx/base-files/lib/preinit/03_init_hotplug_failsafe_brcm @@ -0,0 +1,9 @@ +#!/bin/sh + +init_hotplug_failsafe() { +	echo '/sbin/hotplug.failsafe' > /proc/sys/kernel/hotplug +} + +boot_hook_add preinit_main init_hotplug_failsafe + + diff --git a/target/linux/brcm47xx/base-files/lib/preinit/05_init_interfaces_brcm b/target/linux/brcm47xx/base-files/lib/preinit/05_init_interfaces_brcm new file mode 100644 index 000000000..3cd760e2d --- /dev/null +++ b/target/linux/brcm47xx/base-files/lib/preinit/05_init_interfaces_brcm @@ -0,0 +1,37 @@ +#!/bin/sh + +set_preinit_iface() { +	ifname=eth0 + +	insmod diag + +	# hardware specific overrides +	case "$(cat /proc/diag/model)" in +		"Linksys WAP54G V1") ifname=eth1;; +		"ASUS WL-HDD") ifname=eth1;; +		"ASUS WL-300g") ifname=eth1;; +		"ASUS (unknown, BCM4702)") ifname=eth1;; +		"Sitecom WL-105b") ifname=eth1;; +	esac +	ifconfig $ifname 0.0.0.0 up +} + +check_module () { +  module="$1"; shift; params="$*" + +  insmod "$module" "$params" +  sleep 1 +  grep "^$module" /proc/modules +  return $? +} + +init_iface() { +	check_module tg3 +	insmod switch-core +	check_module switch-robo || check_module switch-adm  || {  +	  check_module bcm57xx activate_gpio=0x4 && cpu_port="8u*" +	} || rmmod switch-core +} + +boot_hook_add preinit_main set_preinit_iface +boot_hook_add preinit_main init_iface diff --git a/target/linux/brcm47xx/base-files/lib/preinit/05_set_failsafe_switch_brcm b/target/linux/brcm47xx/base-files/lib/preinit/05_set_failsafe_switch_brcm new file mode 100644 index 000000000..a93559f97 --- /dev/null +++ b/target/linux/brcm47xx/base-files/lib/preinit/05_set_failsafe_switch_brcm @@ -0,0 +1,15 @@ +#!/bin/sh + +failsafe_ip() { +	[ -d /proc/switch/eth0 ] && [ "$ifname" = "eth0" ] && { +		ifconfig eth0 0.0.0.0 down +		echo "0 1 2 3 4 ${cpu_port:-5u*}" > /proc/switch/eth0/vlan/0/ports +	} +	 +	[ -n "$pi_ifname" ] && grep -q "$pi_ifname" /proc/net/dev && { +        	ifconfig $pi_ifname $pi_ip netmask $pi_netmask broadcast $pi_broadcast up +        } +} + +boot_hook_add failsafe failsafe_ip + diff --git a/target/linux/brcm47xx/base-files/lib/preinit/15_mount_proc_brcm b/target/linux/brcm47xx/base-files/lib/preinit/15_mount_proc_brcm new file mode 100644 index 000000000..fd5add16a --- /dev/null +++ b/target/linux/brcm47xx/base-files/lib/preinit/15_mount_proc_brcm @@ -0,0 +1,6 @@ +#!/bin/sh + +do_mount_procfs() { +	mount none /proc -t proc +} + diff --git a/target/linux/brcm47xx/base-files/lib/preinit/15_set_preinit_interface_brcm b/target/linux/brcm47xx/base-files/lib/preinit/15_set_preinit_interface_brcm new file mode 100644 index 000000000..fdc7c71ca --- /dev/null +++ b/target/linux/brcm47xx/base-files/lib/preinit/15_set_preinit_interface_brcm @@ -0,0 +1,39 @@ +#!/bin/sh + +port_net_echo() { +	[ -n "$pi_ifname" ] && grep -q "$pi_ifname" /proc/net/dev && { +		if [ "$pi_preinit_net_messages" = "y" ] || [ "$pi_failsafe_net_message" = "true" ] && [ "$pi_preinit_no_failsafe_netmsg" != "y" ]; then  +			netmsg $pi_broadcast "$1" +		fi +	} +} + +preinit_ip_deconfig() { +	if [ -z "$pi_ifname" ]; then +		ifconfig $ifname 0.0.0.0 down +	else +		grep -q "$pi_ifname" /proc/net/dev && { +			ifconfig $pi_ifname 0.0.0.0 down +		} +	fi +} + +preinit_net_echo() { +	preinit_ip +	 +	[ -d /proc/switch/eth0 ] && [ "$pi_ifname" = "eth0" ] && { +		echo 1 > /proc/switch/eth0/reset + +		# this would be easier if we blasted the message across all ports +		# but we don't want packets leaking across interfaces +		for port in $(seq 0 4); do { +			echo "$port ${cpu_port:-5u*}" > /proc/switch/eth0/vlan/0/ports +			port_net_echo $1 +		}; done +		 +		echo "0 ${cpu_port:-5u*}" > /proc/switch/eth0/vlan/0/ports +		 +	} || port_net_echo $1 +} + + diff --git a/target/linux/brcm47xx/base-files/lib/preinit/20_failsafe_net_echo_brcm b/target/linux/brcm47xx/base-files/lib/preinit/20_failsafe_net_echo_brcm new file mode 100644 index 000000000..f030cb283 --- /dev/null +++ b/target/linux/brcm47xx/base-files/lib/preinit/20_failsafe_net_echo_brcm @@ -0,0 +1,12 @@ +#!/bin/sh + +indicate_failsafe() { +	preinit_net_echo() { +		port_net_echo $1 +	} +	echo "- failsafe -" +	preinit_net_echo "Entering Failsafe!\n" +	indicate_failsafe_led +} + + diff --git a/target/linux/brcm47xx/base-files/lib/preinit/20_failsafe_set_boot_wait_brcm b/target/linux/brcm47xx/base-files/lib/preinit/20_failsafe_set_boot_wait_brcm new file mode 100644 index 000000000..da721b848 --- /dev/null +++ b/target/linux/brcm47xx/base-files/lib/preinit/20_failsafe_set_boot_wait_brcm @@ -0,0 +1,14 @@ +#!/bin/sh + +. /etc/functions.sh + +set_boot_wait() { +	[ -x "/usr/sbin/nvram" ] && { +		[ "$(nvram get boot_wait)" != "on" ] && { +			nvram set boot_wait=on +			nvram commit +		} +	} +} + +boot_hook_add failsafe set_boot_wait diff --git a/target/linux/brcm47xx/base-files/lib/upgrade/platform.sh b/target/linux/brcm47xx/base-files/lib/upgrade/platform.sh new file mode 100644 index 000000000..9921cf571 --- /dev/null +++ b/target/linux/brcm47xx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,16 @@ +PART_NAME=linux + +platform_check_image() { +	[ "$ARGC" -gt 1 ] && return 1 + +	case "$(get_magic_word "$1")" in +		# .trx files +		4844) return 0;; +		*) +			echo "Invalid image type. Please use only .trx files" +			return 1 +		;; +	esac +} + +# use default for platform_do_upgrade() diff --git a/target/linux/brcm47xx/base-files/sbin/hotplug.failsafe b/target/linux/brcm47xx/base-files/sbin/hotplug.failsafe new file mode 100755 index 000000000..0544339de --- /dev/null +++ b/target/linux/brcm47xx/base-files/sbin/hotplug.failsafe @@ -0,0 +1,4 @@ +#!/bin/sh +case "$1" in +	button) kill -USR1 1;; +esac diff --git a/target/linux/brcm47xx/image/Makefile b/target/linux/brcm47xx/image/Makefile new file mode 100644 index 000000000..b839a42d2 --- /dev/null +++ b/target/linux/brcm47xx/image/Makefile @@ -0,0 +1,110 @@ +#  +# Copyright (C) 2006-2010 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)/image.mk + +define Build/Clean +	$(MAKE) -C lzma-loader clean +endef + +define Image/Prepare +	cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma +	rm -f $(KDIR)/loader.gz +	$(MAKE) -C lzma-loader \ +		BUILD_DIR="$(KDIR)" \ +		TARGET="$(KDIR)" \ +		clean install +	echo -ne "\\x00" >> $(KDIR)/loader.gz +	rm -f $(KDIR)/fs_mark +	touch $(KDIR)/fs_mark +	$(call prepare_generic_squashfs,$(KDIR)/fs_mark) +endef + +ifneq ($(KERNEL),2.4) +  define Image/Build/wgt634u +	dd if=$(KDIR)/loader.elf of=$(BIN_DIR)/openwrt-wgt634u-$(2).bin bs=131072 conv=sync +	cat $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx >> $(BIN_DIR)/openwrt-wgt634u-$(2).bin +  endef +endif + +define Image/Build/CyberTAN +	$(STAGING_DIR_HOST)/bin/addpattern -4 -p $(3) -v v$(4) -i $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx -o $(BIN_DIR)/openwrt-$(2)-$(5).bin $(if $(6),-s $(6)) +endef +define Image/Build/CyberTAN2 +	$(STAGING_DIR_HOST)/bin/addpattern -4 -p $(3) -v v$(4) -i $(BIN_DIR)/openwrt-$(2)-$(5)-sysupgrade.bin -o $(BIN_DIR)/openwrt-$(2)-$(5)-factory.bin $(if $(6),-s $(6)) +endef +define Image/Build/CyberTANHead +	$(STAGING_DIR_HOST)/bin/addpattern -5 -p $(3) -v v$(4) -i /dev/null -o $(KDIR)/openwrt-$(2)-header.bin $(if $(6),-s $(6)) +endef + +define Image/Build/Motorola +	$(STAGING_DIR_HOST)/bin/motorola-bin -$(3) $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx $(BIN_DIR)/openwrt-$(2)-$(4).bin +endef + +define Image/Build/USR +	$(STAGING_DIR_HOST)/bin/trx2usr $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx $(BIN_DIR)/openwrt-$(2)-$(3).bin +endef + +define trxalign/jffs2-128k +-a 0x20000 -f $(KDIR)/root.$(1) +endef +define trxalign/jffs2-64k +-a 0x10000 -f $(KDIR)/root.$(1) +endef +define trxalign/squashfs +-a 1024 -f $(KDIR)/root.$(1) $(if $(2),-f $(2)) -a 0x10000 -A $(KDIR)/fs_mark +endef + +define Image/Build/trxV2 +	$(call Image/Build/CyberTANHead,$(1),$(2),$(3),$(4),$(5),$(if $(6),$(6))) +	$(STAGING_DIR_HOST)/bin/trx -2 -o $(BIN_DIR)/openwrt-$(2)-$(5)-sysupgrade.bin \ +		-f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma \ +		$(call trxalign/$(1),$(1),$(KDIR)/openwrt-$(2)-header.bin) +	$(call Image/Build/CyberTAN2,$(1),$(2),$(3),$(4),$(5),$(if $(6),$(6))) +endef + +define Image/Build/jffs2-128k +	$(call Image/Build/CyberTAN,$(1),wrt54gs,W54S,4.80.1,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/CyberTAN,$(1),wrtsl54gs,W54U,2.08.1,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/trxV2,$(1),wrt54g3gv2-vf,3G2V,3.00.24,$(patsubst jffs2-%,jffs2,$(1)),6) +  ifeq ($(KERNEL),2.6) +	$(call Image/Build/wgt634u,$(1),$(patsubst jffs2-%,jffs2,$(1))) +  endif +endef + +define Image/Build/jffs2-64k +	$(call Image/Build/CyberTAN,$(1),wrt54g3g,W54F,2.20.1,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/CyberTAN,$(1),wrt54g3g-em,W3GN,2.20.1,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/CyberTAN,$(1),wrt54g,W54G,4.71.1,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/CyberTAN,$(1),wrt54gs_v4,W54s,1.09.1,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/CyberTAN,$(1),wrt150n,N150,1.51.3,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/CyberTAN,$(1),wrt300n_v1,EWCB,1.03.6,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/CyberTAN,$(1),wrt300n_v11,EWC2,1.51.2,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/CyberTAN,$(1),wrt350n_v1,EWCG,1.04.1,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/Motorola,$(1),wa840g,2,$(patsubst jffs2-%,jffs2,$(1))) +	$(call Image/Build/Motorola,$(1),we800g,3,$(patsubst jffs2-%,jffs2,$(1))) +endef + +define Image/Build/squashfs +	$(call Image/Build/jffs2-64k,$(1)) +	$(call Image/Build/jffs2-128k,$(1)) +endef + +define Image/Build/Initramfs +	$(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/$(IMG_PREFIX)-initramfs.trx -f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma +endef + +define Image/Build +	$(STAGING_DIR_HOST)/bin/trx -o $(BIN_DIR)/$(IMG_PREFIX)-$(1).trx \ +		-f $(KDIR)/loader.gz -f $(KDIR)/vmlinux.lzma \ +		$(call trxalign/$(1),$(1)) +	$(call Image/Build/$(1),$(1)) +	$(call Image/Build/Motorola,$(1),wr850g,1,$(1)) +	$(call Image/Build/USR,$(1),usr5461,$(1)) +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/brcm47xx/image/lzma-loader/Makefile b/target/linux/brcm47xx/image/lzma-loader/Makefile new file mode 100644 index 000000000..5dd6f5097 --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/Makefile @@ -0,0 +1,33 @@ +#  +# Copyright (C) 2006 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 := lzma-loader +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +$(PKG_BUILD_DIR)/.prepared: +	mkdir $(PKG_BUILD_DIR) +	$(CP) ./src/* $(PKG_BUILD_DIR)/ +	touch $@ + +$(PKG_BUILD_DIR)/loader.gz: $(PKG_BUILD_DIR)/.prepared +	$(MAKE) -C $(PKG_BUILD_DIR) CC="$(TARGET_CC)" \ +		LD="$(TARGET_CROSS)ld" CROSS_COMPILE="$(TARGET_CROSS)" + +download:  +prepare: $(PKG_BUILD_DIR)/.prepared +compile: $(PKG_BUILD_DIR)/loader.gz +install: + +ifneq ($(TARGET),) +install: compile +	$(CP) $(PKG_BUILD_DIR)/loader.gz $(PKG_BUILD_DIR)/loader.elf $(TARGET)/ +endif + +clean: +	rm -rf $(PKG_BUILD_DIR) diff --git a/target/linux/brcm47xx/image/lzma-loader/src/LzmaDecode.c b/target/linux/brcm47xx/image/lzma-loader/src/LzmaDecode.c new file mode 100644 index 000000000..951700bdd --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/src/LzmaDecode.c @@ -0,0 +1,663 @@ +/* +  LzmaDecode.c +  LZMA Decoder +   +  LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) +  http://www.7-zip.org/ + +  LZMA SDK is licensed under two licenses: +  1) GNU Lesser General Public License (GNU LGPL) +  2) Common Public License (CPL) +  It means that you can select one of these two licenses and  +  follow rules of that license. + +  SPECIAL EXCEPTION: +  Igor Pavlov, as the author of this code, expressly permits you to  +  statically or dynamically link your code (or bind by name) to the  +  interfaces of this file without subjecting your linked code to the  +  terms of the CPL or GNU LGPL. Any modifications or additions  +  to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#ifndef Byte +#define Byte unsigned char +#endif + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +typedef struct _CRangeDecoder +{ +  Byte *Buffer; +  Byte *BufferLim; +  UInt32 Range; +  UInt32 Code; +  #ifdef _LZMA_IN_CB +  ILzmaInCallback *InCallback; +  int Result; +  #endif +  int ExtraBytes; +} CRangeDecoder; + +Byte RangeDecoderReadByte(CRangeDecoder *rd) +{ +  if (rd->Buffer == rd->BufferLim) +  { +    #ifdef _LZMA_IN_CB +    UInt32 size; +    rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); +    rd->BufferLim = rd->Buffer + size; +    if (size == 0) +    #endif +    { +      rd->ExtraBytes = 1; +      return 0xFF; +    } +  } +  return (*rd->Buffer++); +} + +/* #define ReadByte (*rd->Buffer++) */ +#define ReadByte (RangeDecoderReadByte(rd)) + +void RangeDecoderInit(CRangeDecoder *rd, +  #ifdef _LZMA_IN_CB +    ILzmaInCallback *inCallback +  #else +    Byte *stream, UInt32 bufferSize +  #endif +    ) +{ +  int i; +  #ifdef _LZMA_IN_CB +  rd->InCallback = inCallback; +  rd->Buffer = rd->BufferLim = 0; +  #else +  rd->Buffer = stream; +  rd->BufferLim = stream + bufferSize; +  #endif +  rd->ExtraBytes = 0; +  rd->Code = 0; +  rd->Range = (0xFFFFFFFF); +  for(i = 0; i < 5; i++) +    rd->Code = (rd->Code << 8) | ReadByte; +} + +#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code;         +#define RC_FLUSH_VAR rd->Range = range; rd->Code = code; +#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } + +UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) +{ +  RC_INIT_VAR +  UInt32 result = 0; +  int i; +  for (i = numTotalBits; i > 0; i--) +  { +    /* UInt32 t; */ +    range >>= 1; + +    result <<= 1; +    if (code >= range) +    { +      code -= range; +      result |= 1; +    } +    /* +    t = (code - range) >> 31; +    t &= 1; +    code -= range & (t - 1); +    result = (result + result) | (1 - t); +    */ +    RC_NORMALIZE +  } +  RC_FLUSH_VAR +  return result; +} + +int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) +{ +  UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; +  if (rd->Code < bound) +  { +    rd->Range = bound; +    *prob += (kBitModelTotal - *prob) >> kNumMoveBits; +    if (rd->Range < kTopValue) +    { +      rd->Code = (rd->Code << 8) | ReadByte; +      rd->Range <<= 8; +    } +    return 0; +  } +  else +  { +    rd->Range -= bound; +    rd->Code -= bound; +    *prob -= (*prob) >> kNumMoveBits; +    if (rd->Range < kTopValue) +    { +      rd->Code = (rd->Code << 8) | ReadByte; +      rd->Range <<= 8; +    } +    return 1; +  } +} + +#define RC_GET_BIT2(prob, mi, A0, A1) \ +  UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ +  if (code < bound) \ +    { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ +  else \ +    { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ +  RC_NORMALIZE + +#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;)                + +int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ +  int mi = 1; +  int i; +  #ifdef _LZMA_LOC_OPT +  RC_INIT_VAR +  #endif +  for(i = numLevels; i > 0; i--) +  { +    #ifdef _LZMA_LOC_OPT +    CProb *prob = probs + mi; +    RC_GET_BIT(prob, mi) +    #else +    mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); +    #endif +  } +  #ifdef _LZMA_LOC_OPT +  RC_FLUSH_VAR +  #endif +  return mi - (1 << numLevels); +} + +int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ +  int mi = 1; +  int i; +  int symbol = 0; +  #ifdef _LZMA_LOC_OPT +  RC_INIT_VAR +  #endif +  for(i = 0; i < numLevels; i++) +  { +    #ifdef _LZMA_LOC_OPT +    CProb *prob = probs + mi; +    RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) +    #else +    int bit = RangeDecoderBitDecode(probs + mi, rd); +    mi = mi + mi + bit; +    symbol |= (bit << i); +    #endif +  } +  #ifdef _LZMA_LOC_OPT +  RC_FLUSH_VAR +  #endif +  return symbol; +} + +Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) +{  +  int symbol = 1; +  #ifdef _LZMA_LOC_OPT +  RC_INIT_VAR +  #endif +  do +  { +    #ifdef _LZMA_LOC_OPT +    CProb *prob = probs + symbol; +    RC_GET_BIT(prob, symbol) +    #else +    symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); +    #endif +  } +  while (symbol < 0x100); +  #ifdef _LZMA_LOC_OPT +  RC_FLUSH_VAR +  #endif +  return symbol; +} + +Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) +{  +  int symbol = 1; +  #ifdef _LZMA_LOC_OPT +  RC_INIT_VAR +  #endif +  do +  { +    int bit; +    int matchBit = (matchByte >> 7) & 1; +    matchByte <<= 1; +    #ifdef _LZMA_LOC_OPT +    { +      CProb *prob = probs + ((1 + matchBit) << 8) + symbol; +      RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) +    } +    #else +    bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd); +    symbol = (symbol << 1) | bit; +    #endif +    if (matchBit != bit) +    { +      while (symbol < 0x100) +      { +        #ifdef _LZMA_LOC_OPT +        CProb *prob = probs + symbol; +        RC_GET_BIT(prob, symbol) +        #else +        symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); +        #endif +      } +      break; +    } +  } +  while (symbol < 0x100); +  #ifdef _LZMA_LOC_OPT +  RC_FLUSH_VAR +  #endif +  return symbol; +} + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols)  + +int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) +{ +  if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) +    return RangeDecoderBitTreeDecode(p + LenLow + +        (posState << kLenNumLowBits), kLenNumLowBits, rd); +  if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) +    return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + +        (posState << kLenNumMidBits), kLenNumMidBits, rd); +  return kLenNumLowSymbols + kLenNumMidSymbols +  +      RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); +} + +#define kNumStates 12 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +#ifdef _LZMA_OUT_READ + +typedef struct _LzmaVarState +{ +  CRangeDecoder RangeDecoder; +  Byte *Dictionary; +  UInt32 DictionarySize; +  UInt32 DictionaryPos; +  UInt32 GlobalPos; +  UInt32 Reps[4]; +  int lc; +  int lp; +  int pb; +  int State; +  int PreviousIsMatch; +  int RemainLen; +} LzmaVarState; + +int LzmaDecoderInit( +    unsigned char *buffer, UInt32 bufferSize, +    int lc, int lp, int pb, +    unsigned char *dictionary, UInt32 dictionarySize, +    #ifdef _LZMA_IN_CB +    ILzmaInCallback *inCallback +    #else +    unsigned char *inStream, UInt32 inSize +    #endif +    ) +{ +  LzmaVarState *vs = (LzmaVarState *)buffer; +  CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); +  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); +  UInt32 i; +  if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState)) +    return LZMA_RESULT_NOT_ENOUGH_MEM; +  vs->Dictionary = dictionary; +  vs->DictionarySize = dictionarySize; +  vs->DictionaryPos = 0; +  vs->GlobalPos = 0; +  vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1; +  vs->lc = lc; +  vs->lp = lp; +  vs->pb = pb; +  vs->State = 0; +  vs->PreviousIsMatch = 0; +  vs->RemainLen = 0; +  dictionary[dictionarySize - 1] = 0; +  for (i = 0; i < numProbs; i++) +    p[i] = kBitModelTotal >> 1;  +  RangeDecoderInit(&vs->RangeDecoder,  +      #ifdef _LZMA_IN_CB +      inCallback +      #else +      inStream, inSize +      #endif +  ); +  return LZMA_RESULT_OK; +} + +int LzmaDecode(unsigned char *buffer,  +    unsigned char *outStream, UInt32 outSize, +    UInt32 *outSizeProcessed) +{ +  LzmaVarState *vs = (LzmaVarState *)buffer; +  CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); +  CRangeDecoder rd = vs->RangeDecoder; +  int state = vs->State; +  int previousIsMatch = vs->PreviousIsMatch; +  Byte previousByte; +  UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; +  UInt32 nowPos = 0; +  UInt32 posStateMask = (1 << (vs->pb)) - 1; +  UInt32 literalPosMask = (1 << (vs->lp)) - 1; +  int lc = vs->lc; +  int len = vs->RemainLen; +  UInt32 globalPos = vs->GlobalPos; + +  Byte *dictionary = vs->Dictionary; +  UInt32 dictionarySize = vs->DictionarySize; +  UInt32 dictionaryPos = vs->DictionaryPos; + +  if (len == -1) +  { +    *outSizeProcessed = 0; +    return LZMA_RESULT_OK; +  } + +  while(len > 0 && nowPos < outSize) +  { +    UInt32 pos = dictionaryPos - rep0; +    if (pos >= dictionarySize) +      pos += dictionarySize; +    outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; +    if (++dictionaryPos == dictionarySize) +      dictionaryPos = 0; +    len--; +  } +  if (dictionaryPos == 0) +    previousByte = dictionary[dictionarySize - 1]; +  else +    previousByte = dictionary[dictionaryPos - 1]; +#else + +int LzmaDecode( +    Byte *buffer, UInt32 bufferSize, +    int lc, int lp, int pb, +    #ifdef _LZMA_IN_CB +    ILzmaInCallback *inCallback, +    #else +    unsigned char *inStream, UInt32 inSize, +    #endif +    unsigned char *outStream, UInt32 outSize, +    UInt32 *outSizeProcessed) +{ +  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); +  CProb *p = (CProb *)buffer; +  CRangeDecoder rd; +  UInt32 i; +  int state = 0; +  int previousIsMatch = 0; +  Byte previousByte = 0; +  UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; +  UInt32 nowPos = 0; +  UInt32 posStateMask = (1 << pb) - 1; +  UInt32 literalPosMask = (1 << lp) - 1; +  int len = 0; +  if (bufferSize < numProbs * sizeof(CProb)) +    return LZMA_RESULT_NOT_ENOUGH_MEM; +  for (i = 0; i < numProbs; i++) +    p[i] = kBitModelTotal >> 1;  +  RangeDecoderInit(&rd,  +      #ifdef _LZMA_IN_CB +      inCallback +      #else +      inStream, inSize +      #endif +      ); +#endif + +  *outSizeProcessed = 0; +  while(nowPos < outSize) +  { +    int posState = (int)( +        (nowPos  +        #ifdef _LZMA_OUT_READ +        + globalPos +        #endif +        ) +        & posStateMask); +    #ifdef _LZMA_IN_CB +    if (rd.Result != LZMA_RESULT_OK) +      return rd.Result; +    #endif +    if (rd.ExtraBytes != 0) +      return LZMA_RESULT_DATA_ERROR; +    if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) +    { +      CProb *probs = p + Literal + (LZMA_LIT_SIZE *  +        ((( +        (nowPos  +        #ifdef _LZMA_OUT_READ +        + globalPos +        #endif +        ) +        & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + +      if (state < 4) state = 0; +      else if (state < 10) state -= 3; +      else state -= 6; +      if (previousIsMatch) +      { +        Byte matchByte; +        #ifdef _LZMA_OUT_READ +        UInt32 pos = dictionaryPos - rep0; +        if (pos >= dictionarySize) +          pos += dictionarySize; +        matchByte = dictionary[pos]; +        #else +        matchByte = outStream[nowPos - rep0]; +        #endif +        previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); +        previousIsMatch = 0; +      } +      else +        previousByte = LzmaLiteralDecode(probs, &rd); +      outStream[nowPos++] = previousByte; +      #ifdef _LZMA_OUT_READ +      dictionary[dictionaryPos] = previousByte; +      if (++dictionaryPos == dictionarySize) +        dictionaryPos = 0; +      #endif +    } +    else              +    { +      previousIsMatch = 1; +      if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) +      { +        if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) +        { +          if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) +          { +            #ifdef _LZMA_OUT_READ +            UInt32 pos; +            #endif +            if ( +               (nowPos  +                #ifdef _LZMA_OUT_READ +                + globalPos +                #endif +               ) +               == 0) +              return LZMA_RESULT_DATA_ERROR; +            state = state < 7 ? 9 : 11; +            #ifdef _LZMA_OUT_READ +            pos = dictionaryPos - rep0; +            if (pos >= dictionarySize) +              pos += dictionarySize; +            previousByte = dictionary[pos]; +            dictionary[dictionaryPos] = previousByte; +            if (++dictionaryPos == dictionarySize) +              dictionaryPos = 0; +            #else +            previousByte = outStream[nowPos - rep0]; +            #endif +            outStream[nowPos++] = previousByte; +            continue; +          } +        } +        else +        { +          UInt32 distance; +          if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) +            distance = rep1; +          else  +          { +            if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) +              distance = rep2; +            else +            { +              distance = rep3; +              rep3 = rep2; +            } +            rep2 = rep1; +          } +          rep1 = rep0; +          rep0 = distance; +        } +        len = LzmaLenDecode(p + RepLenCoder, &rd, posState); +        state = state < 7 ? 8 : 11; +      } +      else +      { +        int posSlot; +        rep3 = rep2; +        rep2 = rep1; +        rep1 = rep0; +        state = state < 7 ? 7 : 10; +        len = LzmaLenDecode(p + LenCoder, &rd, posState); +        posSlot = RangeDecoderBitTreeDecode(p + PosSlot + +            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<  +            kNumPosSlotBits), kNumPosSlotBits, &rd); +        if (posSlot >= kStartPosModelIndex) +        { +          int numDirectBits = ((posSlot >> 1) - 1); +          rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); +          if (posSlot < kEndPosModelIndex) +          { +            rep0 += RangeDecoderReverseBitTreeDecode( +                p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); +          } +          else +          { +            rep0 += RangeDecoderDecodeDirectBits(&rd,  +                numDirectBits - kNumAlignBits) << kNumAlignBits; +            rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); +          } +        } +        else +          rep0 = posSlot; +        rep0++; +      } +      if (rep0 == (UInt32)(0)) +      { +        /* it's for stream version */ +        len = -1; +        break; +      } +      if (rep0 > nowPos  +        #ifdef _LZMA_OUT_READ +        + globalPos +        #endif +        ) +      { +        return LZMA_RESULT_DATA_ERROR; +      } +      len += kMatchMinLen; +      do +      { +        #ifdef _LZMA_OUT_READ +        UInt32 pos = dictionaryPos - rep0; +        if (pos >= dictionarySize) +          pos += dictionarySize; +        previousByte = dictionary[pos]; +        dictionary[dictionaryPos] = previousByte; +        if (++dictionaryPos == dictionarySize) +          dictionaryPos = 0; +        #else +        previousByte = outStream[nowPos - rep0]; +        #endif +        outStream[nowPos++] = previousByte; +        len--; +      } +      while(len > 0 && nowPos < outSize); +    } +  } + +  #ifdef _LZMA_OUT_READ +  vs->RangeDecoder = rd; +  vs->DictionaryPos = dictionaryPos; +  vs->GlobalPos = globalPos + nowPos; +  vs->Reps[0] = rep0; +  vs->Reps[1] = rep1; +  vs->Reps[2] = rep2; +  vs->Reps[3] = rep3; +  vs->State = state; +  vs->PreviousIsMatch = previousIsMatch; +  vs->RemainLen = len; +  #endif + +  *outSizeProcessed = nowPos; +  return LZMA_RESULT_OK; +} diff --git a/target/linux/brcm47xx/image/lzma-loader/src/LzmaDecode.h b/target/linux/brcm47xx/image/lzma-loader/src/LzmaDecode.h new file mode 100644 index 000000000..f58944e3c --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/src/LzmaDecode.h @@ -0,0 +1,100 @@ +/*  +  LzmaDecode.h +  LZMA Decoder interface + +  LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) +  http://www.7-zip.org/ + +  LZMA SDK is licensed under two licenses: +  1) GNU Lesser General Public License (GNU LGPL) +  2) Common Public License (CPL) +  It means that you can select one of these two licenses and  +  follow rules of that license. + +  SPECIAL EXCEPTION: +  Igor Pavlov, as the author of this code, expressly permits you to  +  statically or dynamically link your code (or bind by name) to the  +  interfaces of this file without subjecting your linked code to the  +  terms of the CPL or GNU LGPL. Any modifications or additions  +  to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs,  +   but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb unsigned short +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 +#define LZMA_RESULT_NOT_ENOUGH_MEM 2 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ +  int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +/*  +bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb) +bufferSize += 100 in case of _LZMA_OUT_READ +by default CProb is unsigned short,  +but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int) +*/ + +#ifdef _LZMA_OUT_READ +int LzmaDecoderInit( +    unsigned char *buffer, UInt32 bufferSize, +    int lc, int lp, int pb, +    unsigned char *dictionary, UInt32 dictionarySize, +  #ifdef _LZMA_IN_CB +    ILzmaInCallback *inCallback +  #else +    unsigned char *inStream, UInt32 inSize +  #endif +); +#endif + +int LzmaDecode( +    unsigned char *buffer,  +  #ifndef _LZMA_OUT_READ +    UInt32 bufferSize, +    int lc, int lp, int pb, +  #ifdef _LZMA_IN_CB +    ILzmaInCallback *inCallback, +  #else +    unsigned char *inStream, UInt32 inSize, +  #endif +  #endif +    unsigned char *outStream, UInt32 outSize, +    UInt32 *outSizeProcessed); + +#endif diff --git a/target/linux/brcm47xx/image/lzma-loader/src/Makefile b/target/linux/brcm47xx/image/lzma-loader/src/Makefile new file mode 100644 index 000000000..3320e565d --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/src/Makefile @@ -0,0 +1,77 @@ +# +# Makefile for Broadcom BCM947XX boards +# +# Copyright 2001-2003, Broadcom Corporation +# All Rights Reserved. +#  +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. +# +# Copyright 2004  Manuel Novoa III <mjn3@codepoet.org> +#   Modified to support bzip'd kernels. +#   Of course, it would be better to integrate bunzip capability into CFE. +# +# Copyright 2005  Oleg I. Vdovikin <oleg@cs.msu.su> +#   Cleaned up, modified for lzma support, removed from kernel +# + +TEXT_START	:= 0x80001000 +BZ_TEXT_START	:= 0x80400000 + +OBJCOPY		:= $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S + +CFLAGS		= -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ +		  -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \ +		  -ffunction-sections -pipe -mlong-calls -fno-common \ +		  -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap +CFLAGS		+= -DLOADADDR=$(TEXT_START) -D_LZMA_IN_CB + +ASFLAGS		= $(CFLAGS) -D__ASSEMBLY__ -DBZ_TEXT_START=$(BZ_TEXT_START) + +SEDFLAGS	:= s/BZ_TEXT_START/$(BZ_TEXT_START)/;s/TEXT_START/$(TEXT_START)/ + +OBJECTS		:= head.o data.o + +all: loader.gz loader.elf + +# Don't build dependencies, this may die if $(CC) isn't gcc +dep: + +install: + +loader.gz: loader +	gzip -nc9 $< > $@ + +loader.elf: loader.o +	cp $< $@ + +loader: loader.o +	$(OBJCOPY) $< $@ + +loader.o: loader.lds $(OBJECTS) +	$(LD) -static --gc-sections -no-warn-mismatch -T loader.lds -o $@ $(OBJECTS) + +loader.lds: loader.lds.in Makefile +	@sed "$(SEDFLAGS)" < $< > $@ + +data.o: data.lds decompress.image +	$(LD) -no-warn-mismatch -T data.lds -r -o $@ -b binary decompress.image -b elf32-tradlittlemips + +data.lds: +	@echo "SECTIONS { .data : { code_start = .; *(.data) code_stop = .; }}" > $@ + +decompress.image: decompress +	$(OBJCOPY) $< $@ + +decompress: decompress.lds decompress.o LzmaDecode.o +	$(LD) -static --gc-sections -no-warn-mismatch -T decompress.lds -o $@ decompress.o LzmaDecode.o + +decompress.lds: decompress.lds.in Makefile +	@sed "$(SEDFLAGS)" < $< > $@ + +mrproper: clean + +clean: +	rm -f loader.gz loader decompress *.lds *.o *.image diff --git a/target/linux/brcm47xx/image/lzma-loader/src/README b/target/linux/brcm47xx/image/lzma-loader/src/README new file mode 100644 index 000000000..16649e950 --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/src/README @@ -0,0 +1,55 @@ +/* + * LZMA compressed kernel decompressor for bcm947xx boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> + * + * 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 + * + */ + +The code is intended to decompress kernel, being compressed using lzma utility +build using 7zip LZMA SDK. This utility is located in the LZMA_Alone directory + +decompressor code expects that your .trx file consist of three partitions:  + +1) decompressor itself (this is gziped code which pmon/cfe will extract and run +on boot-up instead of real kernel) +2) LZMA compressed kernel (both streamed and regular modes are supported now) +3) Root filesystem + +Please be sure to apply the following patch for use this new trx layout (it will +allow using both new and old trx files for root filesystem lookup code) + +--- linuz/arch/mips/brcm-boards/bcm947xx/setup.c        2005-01-23 19:24:27.503322896 +0300 ++++ linux/arch/mips/brcm-boards/bcm947xx/setup.c        2005-01-23 19:29:05.237100944 +0300 +@@ -221,7 +221,9 @@ +                /* Try looking at TRX header for rootfs offset */ +                if (le32_to_cpu(trx->magic) == TRX_MAGIC) { +                        bcm947xx_parts[1].offset = off; +-                       if (le32_to_cpu(trx->offsets[1]) > off) ++                       if (le32_to_cpu(trx->offsets[2]) > off) ++                               off = le32_to_cpu(trx->offsets[2]); ++                       else if (le32_to_cpu(trx->offsets[1]) > off) +                                off = le32_to_cpu(trx->offsets[1]); +                        continue; +                } + + +Revision history: +	0.02	Initial release +	0.03	Added Mineharu Takahara <mtakahar@yahoo.com> patch to pass actual +		output size to decoder (stream mode compressed input is not  +		a requirement anymore) +	0.04	Reordered functions using lds script diff --git a/target/linux/brcm47xx/image/lzma-loader/src/decompress.c b/target/linux/brcm47xx/image/lzma-loader/src/decompress.c new file mode 100644 index 000000000..ce2876a30 --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/src/decompress.c @@ -0,0 +1,179 @@ +/* + * LZMA compressed kernel decompressor for bcm947xx boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> + * + * 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 + * + * + * Please note, this was code based on the bunzip2 decompressor code + * by Manuel Novoa III  (mjn3@codepoet.org), although the only thing left + * is an idea and part of original vendor code + * + * + * 12-Mar-2005  Mineharu Takahara <mtakahar@yahoo.com> + *   pass actual output size to decoder (stream mode + *   compressed input is not a requirement anymore) + * + * 24-Apr-2005 Oleg I. Vdovikin + *   reordered functions using lds script, removed forward decl + * + */ + +#include "LzmaDecode.h" + +#define BCM4710_FLASH		0x1fc00000	/* Flash */ + +#define KSEG0			0x80000000 +#define KSEG1			0xa0000000 + +#define KSEG1ADDR(a)		((((unsigned)(a)) & 0x1fffffffU) | KSEG1) + +#define Index_Invalidate_I	0x00 +#define Index_Writeback_Inv_D   0x01 + +#define cache_unroll(base,op)	\ +	__asm__ __volatile__(		\ +		".set noreorder;\n"		\ +		".set mips3;\n"			\ +		"cache %1, (%0);\n"		\ +		".set mips0;\n"			\ +		".set reorder\n"		\ +		:						\ +		: "r" (base),			\ +		  "i" (op)); + +static __inline__ void blast_icache(unsigned long size, unsigned long lsize) +{ +	unsigned long start = KSEG0; +	unsigned long end = (start + size); + +	while(start < end) { +		cache_unroll(start,Index_Invalidate_I); +		start += lsize; +	} +} + +static __inline__ void blast_dcache(unsigned long size, unsigned long lsize) +{ +	unsigned long start = KSEG0; +	unsigned long end = (start + size); + +	while(start < end) { +		cache_unroll(start,Index_Writeback_Inv_D); +		start += lsize; +	} +} + +#define TRX_MAGIC       0x30524448      /* "HDR0" */ + +struct trx_header { +	unsigned int magic;		/* "HDR0" */ +	unsigned int len;		/* Length of file including header */ +	unsigned int crc32;		/* 32-bit CRC from flag_version to end of file */ +	unsigned int flag_version;	/* 0:15 flags, 16:31 version */ +	unsigned int offsets[3];	/* Offsets of partitions from start of header */ +}; + +/* beyound the image end, size not known in advance */ +extern unsigned char workspace[]; + +unsigned int offset; +unsigned char *data; + +/* flash access should be aligned, so wrapper is used */ +/* read byte from the flash, all accesses are 32-bit aligned */ +static int read_byte(void *object, unsigned char **buffer, UInt32 *bufferSize) +{ +	static unsigned int val; + +	if (((unsigned int)offset % 4) == 0) { +		val = *(unsigned int *)data; +		data += 4; +	} +	 +	*bufferSize = 1; +	*buffer = ((unsigned char *)&val) + (offset++ & 3); +	 +	return LZMA_RESULT_OK; +} + +static __inline__ unsigned char get_byte(void) +{ +	unsigned char *buffer; +	UInt32 fake; +	 +	return read_byte(0, &buffer, &fake), *buffer; +} + +/* should be the first function */ +void entry(unsigned long icache_size, unsigned long icache_lsize,  +	unsigned long dcache_size, unsigned long dcache_lsize, +	unsigned long fw_arg0, unsigned long fw_arg1, +	unsigned long fw_arg2, unsigned long fw_arg3) +{ +	unsigned int i;  /* temp value */ +	unsigned int lc; /* literal context bits */ +	unsigned int lp; /* literal pos state bits */ +	unsigned int pb; /* pos state bits */ +	unsigned int osize; /* uncompressed size */ + +	ILzmaInCallback callback; +	callback.Read = read_byte; + +	/* look for trx header, 32-bit data access */ +	for (data = ((unsigned char *) KSEG1ADDR(BCM4710_FLASH)); +		((struct trx_header *)data)->magic != TRX_MAGIC; data += 65536); + +	/* compressed kernel is in the partition 0 or 1 */ +	if (((struct trx_header *)data)->offsets[1] > 65536)  +		data += ((struct trx_header *)data)->offsets[0]; +	else +		data += ((struct trx_header *)data)->offsets[1]; + +	offset = 0; + +	/* lzma args */ +	i = get_byte(); +	lc = i % 9, i = i / 9; +	lp = i % 5, pb = i / 5; + +	/* skip rest of the LZMA coder property */ +	for (i = 0; i < 4; i++) +		get_byte(); + +	/* read the lower half of uncompressed size in the header */ +	osize = ((unsigned int)get_byte()) + +		((unsigned int)get_byte() << 8) + +		((unsigned int)get_byte() << 16) + +		((unsigned int)get_byte() << 24); + +	/* skip rest of the header (upper half of uncompressed size) */ +	for (i = 0; i < 4; i++)  +		get_byte(); + +	/* decompress kernel */ +	if (LzmaDecode(workspace, ~0, lc, lp, pb, &callback, +		(unsigned char*)LOADADDR, osize, &i) == LZMA_RESULT_OK) +	{ +		blast_dcache(dcache_size, dcache_lsize); +		blast_icache(icache_size, icache_lsize); + +		/* Jump to load address */ +		((void (*)(unsigned long, unsigned long, unsigned long, +			unsigned long)) LOADADDR)(fw_arg0, fw_arg1, fw_arg2, +				fw_arg3); +	} +} diff --git a/target/linux/brcm47xx/image/lzma-loader/src/decompress.lds.in b/target/linux/brcm47xx/image/lzma-loader/src/decompress.lds.in new file mode 100644 index 000000000..33f56f8a0 --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/src/decompress.lds.in @@ -0,0 +1,20 @@ +OUTPUT_ARCH(mips) +ENTRY(entry) +SECTIONS { +	. = BZ_TEXT_START; +	.text : { +		*(.text.entry) +		*(.text) +		*(.rodata) +	} + +	.data : { +		*(.data) +	} + +	.bss : { +		*(.bss) +	} + +	workspace = .; +} diff --git a/target/linux/brcm47xx/image/lzma-loader/src/head.S b/target/linux/brcm47xx/image/lzma-loader/src/head.S new file mode 100644 index 000000000..3a33e4016 --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/src/head.S @@ -0,0 +1,160 @@ +/* Copyright 2005 Oleg I. Vdovikin (oleg@cs.msu.su)	*/ +/* cache manipulation adapted from Broadcom code 	*/ +/* idea taken from original bunzip2 decompressor code	*/ +/* Copyright 2004 Manuel Novoa III (mjn3@codepoet.org)	*/ +/* Licensed under the linux kernel's version of the GPL.*/ + +#include <asm/asm.h> +#include <asm/regdef.h> + +#define KSEG0		0x80000000 + +#define C0_CONFIG	$16 +#define C0_TAGLO	$28 +#define C0_TAGHI	$29 + +#define	CONF1_DA_SHIFT	7			/* D$ associativity */ +#define CONF1_DA_MASK	0x00000380 +#define CONF1_DA_BASE	1 +#define CONF1_DL_SHIFT	10			/* D$ line size */ +#define CONF1_DL_MASK	0x00001c00 +#define CONF1_DL_BASE	2 +#define CONF1_DS_SHIFT	13			/* D$ sets/way */ +#define CONF1_DS_MASK	0x0000e000 +#define CONF1_DS_BASE	64 +#define CONF1_IA_SHIFT	16			/* I$ associativity */ +#define CONF1_IA_MASK	0x00070000 +#define CONF1_IA_BASE	1 +#define CONF1_IL_SHIFT	19			/* I$ line size */ +#define CONF1_IL_MASK	0x00380000 +#define CONF1_IL_BASE	2 +#define CONF1_IS_SHIFT	22			/* Instruction cache sets/way */ +#define CONF1_IS_MASK	0x01c00000 +#define CONF1_IS_BASE	64 + +#define Index_Invalidate_I	0x00 +#define Index_Writeback_Inv_D   0x01 + +	.text +	LEAF(startup) +	.set noreorder +	addi    sp, -48  +	sw      a0, 16(sp)  +	sw      a1, 20(sp)  +	sw      a2, 24(sp)  +	sw      a3, 28(sp) +	 +	/* Copy decompressor code to the right place */ +	li	t2, BZ_TEXT_START +	add	a0, t2, 0 +	la      a1, code_start +	la	a2, code_stop +$L1: +	lw	t0, 0(a1) +	sw	t0, 0(a0) +	add	a1, 4 +	add	a0, 4 +	blt	a1, a2, $L1 +	nop +	 +	/* At this point we need to invalidate dcache and */ +	/* icache before jumping to new code */ + +1:	/* Get cache sizes */ +	.set	mips32 +	mfc0	s0,C0_CONFIG,1 +	.set	mips0 + +	li	s1,CONF1_DL_MASK +	and	s1,s0 +	beq	s1,zero,nodc +	nop + +	srl	s1,CONF1_DL_SHIFT +	li	t0,CONF1_DL_BASE +	sll	s1,t0,s1		/* s1 has D$ cache line size */ + +	li	s2,CONF1_DA_MASK +	and	s2,s0 +	srl	s2,CONF1_DA_SHIFT +	addiu	s2,CONF1_DA_BASE	/* s2 now has D$ associativity */ + +	li	t0,CONF1_DS_MASK +	and	t0,s0 +	srl	t0,CONF1_DS_SHIFT +	li	s3,CONF1_DS_BASE +	sll	s3,s3,t0		/* s3 has D$ sets per way */ + +	multu	s2,s3			/* sets/way * associativity */ +	mflo	t0			/* total cache lines */ + +	multu	s1,t0			/* D$ linesize * lines */ +	mflo	s2			/* s2 is now D$ size in bytes */ + +	/* Initilize the D$: */ +	mtc0	zero,C0_TAGLO +	mtc0	zero,C0_TAGHI + +	li	t0,KSEG0		/* Just an address for the first $ line */ +	addu	t1,t0,s2		/*  + size of cache == end */ + +	.set	mips3 +1:	cache	Index_Writeback_Inv_D,0(t0) +	.set	mips0 +	bne	t0,t1,1b +	addu	t0,s1 +	 +nodc: +	/* Now we get to do it all again for the I$ */ +	 +	move	s3,zero			/* just in case there is no icache */ +	move	s4,zero + +	li	t0,CONF1_IL_MASK +	and	t0,s0 +	beq	t0,zero,noic +	nop + +	srl	t0,CONF1_IL_SHIFT +	li	s3,CONF1_IL_BASE +	sll	s3,t0			/* s3 has I$ cache line size */ + +	li	t0,CONF1_IA_MASK +	and	t0,s0 +	srl	t0,CONF1_IA_SHIFT +	addiu	s4,t0,CONF1_IA_BASE	/* s4 now has I$ associativity */ + +	li	t0,CONF1_IS_MASK +	and	t0,s0 +	srl	t0,CONF1_IS_SHIFT +	li	s5,CONF1_IS_BASE +	sll	s5,t0			/* s5 has I$ sets per way */ + +	multu	s4,s5			/* sets/way * associativity */ +	mflo	t0			/* s4 is now total cache lines */ + +	multu	s3,t0			/* I$ linesize * lines */ +	mflo	s4			/* s4 is cache size in bytes */ + +	/* Initilize the I$: */ +	mtc0	zero,C0_TAGLO +	mtc0	zero,C0_TAGHI + +	li	t0,KSEG0		/* Just an address for the first $ line */ +	addu	t1,t0,s4		/*  + size of cache == end */ + +	.set	mips3 +1:	cache	Index_Invalidate_I,0(t0) +	.set	mips0 +	bne	t0,t1,1b +	addu	t0,s3 + +noic: +	move	a0,s3			/* icache line size */ +	move	a1,s4			/* icache size */ +	move	a2,s1			/* dcache line size */ +	jal	t2 +	move	a3,s2			/* dcache size */ +	 +	.set reorder +	END(startup) diff --git a/target/linux/brcm47xx/image/lzma-loader/src/loader.lds.in b/target/linux/brcm47xx/image/lzma-loader/src/loader.lds.in new file mode 100644 index 000000000..20f2ea98e --- /dev/null +++ b/target/linux/brcm47xx/image/lzma-loader/src/loader.lds.in @@ -0,0 +1,17 @@ +OUTPUT_ARCH(mips) +ENTRY(startup) +SECTIONS { +	. = TEXT_START; +	.text : { +		*(.text) +		*(.rodata) +	} + +	.data : { +		*(.data) +	} + +	.bss : { +		*(.bss) +	} +} | 
