diff --git a/target/linux/mvebu/cortexa9/base-files/etc/board.d/02_network b/target/linux/mvebu/cortexa9/base-files/etc/board.d/02_network
index d2229fe6bf..9db29d52df 100644
--- a/target/linux/mvebu/cortexa9/base-files/etc/board.d/02_network
+++ b/target/linux/mvebu/cortexa9/base-files/etc/board.d/02_network
@@ -18,6 +18,9 @@ mvebu_setup_interfaces()
 	cznic,turris-omnia)
 		ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3 lan4" "eth2"
 		;;
+	fortinet,fg-50e)
+		ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 lan5" "eth1 eth2"
+		;;
 	iptime,nas1dual)
 		ucidef_set_interface_lan "eth0 eth1" "dhcp"
 		;;
diff --git a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/fortinet.sh b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/fortinet.sh
new file mode 100644
index 0000000000..a2742aa374
--- /dev/null
+++ b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/fortinet.sh
@@ -0,0 +1,54 @@
+. /lib/functions.sh
+
+fortinet_fwinfo_blocks() {
+	local fwinfo_mtd="$(find_mtd_part firmware-info)"
+	local offset="$1"
+	local len="$2"
+	local blks
+
+	if [ -z "$fwinfo_mtd" ]; then
+		echo "WARN: MTD device \"firmware-info\" not found"
+		return 1
+	fi
+
+	blks=$((len / 0x200))
+	[ $((len % 0x200)) -gt 0 ] && blks=$((blks + 1))
+	blks=$(printf "%04x" $blks)
+	printf "fwinfo: offset-> 0x%x, blocks-> 0x%s (len: 0x%08x)\n" \
+		$offset $blks $len
+
+	printf "\x${blks:2:2}\x${blks:0:2}" | \
+		dd bs=2 count=1 seek=$((offset / 2)) conv=notrunc of=${fwinfo_mtd}
+}
+
+fortinet_do_upgrade() {
+	local board_dir="$(tar tf "$1" | grep -m 1 '^sysupgrade-.*/$')"
+	local kern_mtd="$(find_mtd_part kernel)"
+	local root_mtd="$(find_mtd_part rootfs)"
+	local kern_len root_len
+
+	board_dir="${board_dir%/}"
+
+	if [ -z "$kern_mtd" ] || [ -z "$root_mtd" ]; then
+		echo "ERROR: MTD device \"kernel\" or \"rootfs\" not found"
+		umount -a
+		reboot -f
+	fi
+
+	kern_len=$( (tar xOf "$1" "$board_dir/kernel" | wc -c) 2> /dev/null)
+	root_len=$( (tar xOf "$1" "$board_dir/root" | wc -c) 2> /dev/null)
+
+	if [ -z "$kern_len" ] || [ -z "$root_len" ]; then
+		echo "ERROR: failed to get length of new kernel or rootfs"
+		umount -a
+		reboot -f
+	fi
+
+	fortinet_fwinfo_blocks "0x184" "$kern_len"
+	fortinet_fwinfo_blocks "0x18c" "$root_len"
+
+	tar xOf "$1" "$board_dir/kernel" | \
+		mtd write - "kernel"
+	tar xOf "$1" "$board_dir/root" | \
+		mtd ${UPGRADE_BACKUP:+-j "${UPGRADE_BACKUP}"} write - "rootfs"
+}
diff --git a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
index 9019c1aeff..fbbb68e05e 100755
--- a/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
+++ b/target/linux/mvebu/cortexa9/base-files/lib/upgrade/platform.sh
@@ -52,6 +52,9 @@ platform_do_upgrade() {
 	solidrun,clearfog-pro-a1)
 		legacy_sdcard_do_upgrade "$1"
 		;;
+	fortinet,fg-50e)
+		fortinet_do_upgrade "$1"
+		;;
 	linksys,wrt1200ac|\
 	linksys,wrt1900ac-v1|\
 	linksys,wrt1900ac-v2|\
diff --git a/target/linux/mvebu/files/arch/arm/boot/dts/armada-385-fortinet-fg-50e.dts b/target/linux/mvebu/files/arch/arm/boot/dts/armada-385-fortinet-fg-50e.dts
new file mode 100644
index 0000000000..506e01f0ff
--- /dev/null
+++ b/target/linux/mvebu/files/arch/arm/boot/dts/armada-385-fortinet-fg-50e.dts
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include "armada-385.dtsi"
+
+/ {
+	model = "Fortinet FortiGate 50E";
+	compatible = "fortinet,fg-50e", "marvell,armada385", "marvell,armada380";
+
+	aliases {
+		led-boot = &led_status_green;
+		led-failsafe = &led_status_red;
+		led-running = &led_status_green;
+		led-upgrade = &led_status_green;
+		label-mac-device = &eth0;
+	};
+
+	chosen {
+		stdout-path = "serial0:9600n8";
+	};
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000>; /* 2GB */
+	};
+
+	soc {
+		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+			  MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+			  MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+			  MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmx_gpio_keys_pins>;
+
+		reset {
+			label = "reset";
+			linux,code = <KEY_RESTART>;
+			gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmx_gpio_leds_pins>;
+
+		led-0 {
+			label = "red:alarm";
+			gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_ALARM;
+		};
+
+		led-1 {
+			label = "red:ha";
+			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_RED>;
+		};
+
+		led_status_green: led-2 {
+			label = "green:sta";
+			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_GREEN>;
+			function = LED_FUNCTION_STATUS;
+		};
+
+		led-3 {
+			label = "green:ha";
+			gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led-4 {
+			label = "amber:alarm";
+			gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_AMBER>;
+			function = LED_FUNCTION_ALARM;
+		};
+
+		led_status_red: led-5 {
+			label = "red:sta";
+			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_RED>;
+			function = LED_FUNCTION_STATUS;
+		};
+
+		led-6 {
+			label = "green:speed_wan1";
+			gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led-7 {
+			label = "green:speed_wan2";
+			gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led-8 {
+			label = "amber:speed_lan5";
+			gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_AMBER>;
+		};
+
+		led-9 {
+			label = "green:speed_lan5";
+			gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led-10 {
+			label = "green:speed_lan4";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led-11 {
+			label = "amber:speed_lan4";
+			gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_AMBER>;
+		};
+
+		led-12 {
+			label = "amber:speed_lan3";
+			gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_AMBER>;
+		};
+
+		led-13 {
+			label = "green:speed_lan3";
+			gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led-14 {
+			label = "green:speed_lan1";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led-15 {
+			label = "amber:speed_lan1";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_AMBER>;
+		};
+
+		led-16 {
+			label = "green:speed_lan2";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led-17 {
+			label = "amber:speed_lan2";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+			color = <LED_COLOR_ID_AMBER>;
+		};
+	};
+
+	reg_usb_vbus: regulator-usb-vbus {
+		compatible = "fixed-regulator";
+		regulator-name = "usb-vbus";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		gpio = <&gpio1 21 GPIO_ACTIVE_LOW>;
+		regulator-always-on;
+	};
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pins>;
+	status = "okay";
+
+	gpio2: gpio@24 {
+		compatible = "nxp,pca9555";
+		reg = <0x24>;
+		gpio-controller;
+		#gpio-cells = <0x2>;
+	};
+
+	hwmon@28 {
+		compatible = "nuvoton,nct7802";
+		reg = <0x28>;
+	};
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pins>;
+	status = "okay";
+};
+
+&pinctrl {
+	pmx_phy_switch_pins: phy-switch-pins {
+		marvell,pins = "mpp19", "mpp20", "mpp23", "mpp34", "mpp41";
+		marvell,function = "gpio";
+	};
+
+	pmx_gpio_leds_pins: gpio-leds-pins {
+		marvell,pins = "mpp30", "mpp32", "mpp33", "mpp35",
+			       "mpp45", "mpp47";
+		marvell,function = "gpio";
+	};
+
+	pmx_usb_pins: usb-pins {
+		marvell,pins = "mpp53";
+		marvell,function = "gpio";
+	};
+
+	pmx_gpio_keys_pins: gpio-keys-pins {
+		marvell,pins = "mpp54";
+		marvell,function = "gpio";
+	};
+};
+
+&bm {
+	status = "okay";
+};
+
+&bm_bppi {
+	status = "okay";
+};
+
+&eth0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&ge0_rgmii_pins>;
+	status = "okay";
+
+	phy-connection-type = "rgmii-id";
+	buffer-manager = <&bm>;
+	bm,pool-long = <0>;
+	bm,pool-short = <1>;
+	nvmem-cells = <&macaddr_bdinfo_d880>;
+	nvmem-cell-names = "mac-address";
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+};
+
+&eth1 {
+	status = "okay";
+
+	phy-handle = <&ethphy0>;
+	phy-connection-type = "sgmii";
+	buffer-manager = <&bm>;
+	bm,pool-long = <2>;
+	nvmem-cells = <&macaddr_bdinfo_d880>;
+	nvmem-cell-names = "mac-address";
+	mac-address-increment = <1>;
+};
+
+&eth2 {
+	status = "okay";
+
+	phy-handle = <&ethphy1>;
+	phy-connection-type = "sgmii";
+	buffer-manager = <&bm>;
+	bm,pool-long = <3>;
+	nvmem-cells = <&macaddr_bdinfo_d880>;
+	nvmem-cell-names = "mac-address";
+	mac-address-increment = <2>;
+};
+
+&mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mdio_pins>, <&pmx_phy_switch_pins>;
+
+	/* Marvell 88E1512 */
+	ethphy0: ethernet-phy@0 {
+		compatible = "ethernet-phy-id0141,0dd1",
+			     "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
+		/*
+		 * LINK/ACT   (Green): LED[0], Active Low
+		 * SPEED 100M (Amber): LED[1], Active High
+		 */
+		marvell,reg-init = <3 16 0 0x71>,
+				   <3 17 0 0x4>;
+	};
+
+	/* Marvell 88E1512 */
+	ethphy1: ethernet-phy@1 {
+		compatible = "ethernet-phy-id0141,0dd1",
+			     "ethernet-phy-ieee802.3-c22";
+		reg = <1>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
+		reset-gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
+		/*
+		 * LINK/ACT   (Green): LED[0], Active Low
+		 * SPEED 100M (Amber): LED[1], Active High
+		 */
+		marvell,reg-init = <3 16 0 0x71>,
+				   <3 17 0 0x4>;
+	};
+
+	/* Marvell 88E6176 */
+	switch@2 {
+		compatible = "marvell,mv88e6085";
+		reg = <0x2>;
+		reset-gpios = <&gpio0 19 GPIO_ACTIVE_LOW>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				label = "lan5";
+				nvmem-cells = <&macaddr_bdinfo_d880>;
+				nvmem-cell-names = "mac-address";
+				mac-address-increment = <7>;
+			};
+
+			port@1 {
+				reg = <1>;
+				label = "lan4";
+				nvmem-cells = <&macaddr_bdinfo_d880>;
+				nvmem-cell-names = "mac-address";
+				mac-address-increment = <6>;
+			};
+
+			port@2 {
+				reg = <2>;
+				label = "lan3";
+				nvmem-cells = <&macaddr_bdinfo_d880>;
+				nvmem-cell-names = "mac-address";
+				mac-address-increment = <5>;
+			};
+
+			port@3 {
+				reg = <3>;
+				label = "lan2";
+				nvmem-cells = <&macaddr_bdinfo_d880>;
+				nvmem-cell-names = "mac-address";
+				mac-address-increment = <4>;
+			};
+
+			port@4 {
+				reg = <4>;
+				label = "lan1";
+				nvmem-cells = <&macaddr_bdinfo_d880>;
+				nvmem-cell-names = "mac-address";
+				mac-address-increment = <3>;
+			};
+
+			port@6 {
+				reg = <6>;
+				ethernet = <&eth0>;
+				phy-connection-type = "rgmii-id";
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+				};
+			};
+		};
+	};
+};
+
+&usb3_0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pmx_usb_pins>;
+	status = "okay";
+
+	vbus-supply = <&reg_usb_vbus>;
+};
+
+&spi1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spi1_pins>;
+	status = "okay";
+
+	flash@0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				reg = <0x0 0x1c0000>;
+				label = "u-boot";
+				read-only;
+			};
+
+			partition@1c0000 {
+				reg = <0x1c0000 0x10000>;
+				label = "firmware-info";
+
+				/*
+				 *  0x10 - 0x2f : image name (image1)
+				 *  0x30 - 0x4f : image name (image2)
+				 * 0x170 (1byte): active image (0x0/0x1)
+				 * 0x184 - 0x185: kernel block count (image1)
+				 * 0x18c - 0x18d: rootfs block count (image1)
+				 * 0x194 - 0x195: kernel block count (image2)
+				 * 0x19c - 0x19d: rootfs block count (image2)
+				 * 0x1be (1byte): bit7 -> active flag (image1)?
+				 * 0x1ce (1byte): bit7 -> active flag (image2)?
+				 *
+				 * Note: block size --> 0x200 (512 bytes)
+				 */
+			};
+
+			partition@1d0000 {
+				reg = <0x1d0000 0x10000>;
+				label = "dtb";
+				read-only;
+			};
+
+			partition@1e0000 {
+				reg = <0x1e0000 0x10000>;
+				label = "u-boot-env";
+				read-only;
+			};
+
+			partition@1f0000 {
+				reg = <0x1f0000 0x10000>;
+				label = "board-info";
+				read-only;
+
+				compatible = "nvmem-cells";
+				#address-cells = <1>;
+				#size-cells = <1>;
+
+				macaddr_bdinfo_d880: macaddr@d880 {
+					reg = <0xd880 0x6>;
+				};
+			};
+
+			partition@200000 {
+				reg = <0x200000 0x600000>;
+				label = "kernel";
+			};
+
+			partition@800000 {
+				reg = <0x800000 0x1800000>;
+				label = "rootfs";
+			};
+
+			partition@2000000 {
+				reg = <0x2000000 0x600000>;
+				label = "kn2";
+				read-only;
+			};
+
+			partition@2600000 {
+				reg = <0x2600000 0x1800000>;
+				label = "rfs2";
+				read-only;
+			};
+
+			partition@3e00000 {
+				reg = <0x3e00000 0x1200000>;
+				label = "part1";
+				read-only;
+			};
+
+			partition@5000000 {
+				reg = <0x5000000 0x1200000>;
+				label = "part2";
+				read-only;
+			};
+
+			partition@6200000 {
+				reg = <0x6200000 0x1e00000>;
+				label = "config";
+				read-only;
+			};
+		};
+	};
+};
diff --git a/target/linux/mvebu/image/cortexa9.mk b/target/linux/mvebu/image/cortexa9.mk
index 56381ab5f8..248f1cd6fd 100644
--- a/target/linux/mvebu/image/cortexa9.mk
+++ b/target/linux/mvebu/image/cortexa9.mk
@@ -3,6 +3,19 @@
 # Copyright (C) 2012-2016 OpenWrt.org
 # Copyright (C) 2016 LEDE-project.org
 
+define Build/fortigate-header
+  ( \
+    dd if=/dev/zero bs=384 count=1 2>/dev/null; \
+    datalen=$$(wc -c $@ | cut -d' ' -f1); \
+    datalen=$$(printf "%08x" $$datalen); \
+    datalen="$${datalen:6:2}$${datalen:4:2}$${datalen:2:2}$${datalen:0:2}"; \
+    printf $$(echo "00020000$${datalen}ffff0000ffff0000" | sed 's/../\\x&/g'); \
+    dd if=/dev/zero bs=112 count=1 2>/dev/null; \
+    cat $@; \
+  ) > $@.new
+  mv $@.new $@
+endef
+
 define Device/dsa-migration
   DEVICE_COMPAT_VERSION := 1.1
   DEVICE_COMPAT_MESSAGE := Config cannot be migrated from swconfig to DSA
@@ -84,6 +97,21 @@ define Device/cznic_turris-omnia
 endef
 TARGET_DEVICES += cznic_turris-omnia
 
+define Device/fortinet_fg-50e
+  DEVICE_VENDOR := Fortinet
+  DEVICE_MODEL := FortiGate 50E
+  SOC := armada-385
+  KERNEL := kernel-bin | append-dtb
+  KERNEL_INITRAMFS := kernel-bin | append-dtb | fortigate-header | \
+    gzip-filename FGT50E
+  KERNEL_SIZE := 6144k
+  DEVICE_DTS := armada-385-fortinet-fg-50e
+  IMAGE/sysupgrade.bin := append-rootfs | pad-rootfs | \
+    sysupgrade-tar rootfs=$$$$@ | append-metadata
+  DEVICE_PACKAGES := kmod-hwmon-nct7802
+endef
+TARGET_DEVICES += fortinet_fg-50e
+
 define Device/globalscale_mirabox
   $(Device/NAND-512K)
   DEVICE_VENDOR := Globalscale
