ceilidh: added odriod-hc4 support
This commit is contained in:
parent
c7c5edae46
commit
89d96c00b0
|
@ -16,6 +16,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
airgead = import ../hosts/airgead.nix;
|
airgead = import ../hosts/airgead.nix;
|
||||||
|
ceilidh = import ../hosts/ceilidh.nix;
|
||||||
cuallaidh = import ../hosts/cuallaidh.nix;
|
cuallaidh = import ../hosts/cuallaidh.nix;
|
||||||
dhu = import ../hosts/dhu.nix;
|
dhu = import ../hosts/dhu.nix;
|
||||||
dionach = import ../hosts/dionach.nix;
|
dionach = import ../hosts/dionach.nix;
|
||||||
|
|
54
hardware/odroid-hc4/default.nix
Normal file
54
hardware/odroid-hc4/default.nix
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{ config, lib, modulesPath, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
sources = import ../../nix/sources.nix;
|
||||||
|
unstable = import sources.nixpkgsUnstable {};
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
"${modulesPath}/profiles/base.nix"
|
||||||
|
./uboot/hardkernel-uboot.nix
|
||||||
|
../../profiles/host_common.nix
|
||||||
|
../../profiles/server_common.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# The linux kernel used is compiled from the Hardkernel fork of
|
||||||
|
# torvalds/linux
|
||||||
|
boot = {
|
||||||
|
initrd.availableKernelModules = mkForce [ ];
|
||||||
|
kernelPackages = pkgs.linuxPackagesFor pkgs.linux_hardkernel;
|
||||||
|
# Bootloader (use Hardkernel fork of Das U-Boot)
|
||||||
|
loader = {
|
||||||
|
grub.enable = false;
|
||||||
|
generic-extlinux-compatible.enable = false;
|
||||||
|
hardkernel-uboot.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# We do know the hardware we are planning to deploy to
|
||||||
|
hardware.enableRedistributableFirmware = mkForce false;
|
||||||
|
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(import ./overlays/kernel/overlay.nix)
|
||||||
|
(import ./overlays/uboot/overlay.nix)
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
# DNS
|
||||||
|
services.resolved.enable = true;
|
||||||
|
services.resolved.dnssec = "false";
|
||||||
|
|
||||||
|
fileSystems = {
|
||||||
|
"/boot" = {
|
||||||
|
device = "/dev/disk/by-label/FIRMWARE";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
"/" = {
|
||||||
|
device = "/dev/disk/by-label/NIXOS_SD";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
44
hardware/odroid-hc4/modules/sd-image/default.nix
Normal file
44
hardware/odroid-hc4/modules/sd-image/default.nix
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
{ pkgs, lib, config, modulesPath, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
"${modulesPath}/installer/sd-card/sd-image.nix"
|
||||||
|
# should we include this module or should we treat the SD
|
||||||
|
# card as the final system to run?
|
||||||
|
"${modulesPath}/profiles/installation-device.nix"
|
||||||
|
../odroidhc4
|
||||||
|
];
|
||||||
|
|
||||||
|
security.polkit.enable = false;
|
||||||
|
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(final: prev: {
|
||||||
|
smartmontools = prev.smartmontools.override { enableMail = false; };
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
# Remove zfs from supported filesystems as it fails when cross-compiling due
|
||||||
|
# to not being able to build kernel module
|
||||||
|
boot.supportedFilesystems = lib.mkForce [ "btrfs" "reiserfs" "vfat" "f2fs" "xfs" "ntfs" "cifs" ];
|
||||||
|
|
||||||
|
sdImage = {
|
||||||
|
compressImage = false;
|
||||||
|
# Use 512 MB for boot partition to fit multiple kernel versions
|
||||||
|
firmwareSize = 512;
|
||||||
|
# Copy u-boot bootloader to SD card
|
||||||
|
postBuildCommands = ''
|
||||||
|
dd if="${pkgs.uboot-hardkernel}" of="$img" conv=fsync,notrunc bs=512 skip=1 seek=1
|
||||||
|
dd if="${pkgs.uboot-hardkernel}" of="$img" conv=fsync,notrunc bs=1 count=444
|
||||||
|
'';
|
||||||
|
# Fill the FIRMWARE partition with the u-boot files, linux kernel and initrd (ramdisk)
|
||||||
|
populateFirmwareCommands = ''
|
||||||
|
${config.boot.loader.hardkernel-uboot.populateCmd} -c ${config.system.build.toplevel} -d ./firmware
|
||||||
|
'';
|
||||||
|
# Fill the root partition with this nix configuration in /etc/nixos
|
||||||
|
# and create a mount point for the FIRMWARE partition at /boot
|
||||||
|
populateRootCommands = ''
|
||||||
|
mkdir -p ./files/boot ./files/etc/nixos
|
||||||
|
cp ${../../configuration.nix} ./files/etc/nixos/configuration.nix
|
||||||
|
cp -r ${../.} ./files/etc/nixos/modules
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
74
hardware/odroid-hc4/overlays/kernel/kernel.diff
Normal file
74
hardware/odroid-hc4/overlays/kernel/kernel.diff
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index bb2e9204..869ac5bb 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -899,7 +899,7 @@ KBUILD_CFLAGS += $(call cc-option,-Werror=strict-prototypes)
|
||||||
|
KBUILD_CFLAGS += $(call cc-option,-Werror=date-time)
|
||||||
|
|
||||||
|
# enforce correct pointer usage
|
||||||
|
-KBUILD_CFLAGS += $(call cc-option,-Werror=incompatible-pointer-types)
|
||||||
|
+KBUILD_CFLAGS += $(call cc-option,-Wno-error=incompatible-pointer-types)
|
||||||
|
|
||||||
|
# Require designated initializers for all marked structures
|
||||||
|
KBUILD_CFLAGS += $(call cc-option,-Werror=designated-init)
|
||||||
|
diff --git a/arch/arm64/configs/odroidg12_defconfig b/arch/arm64/configs/odroidg12_defconfig
|
||||||
|
index 8d21df65..d3eb2b6a 100644
|
||||||
|
--- a/arch/arm64/configs/odroidg12_defconfig
|
||||||
|
+++ b/arch/arm64/configs/odroidg12_defconfig
|
||||||
|
@@ -430,7 +430,7 @@ CONFIG_ARM64_VA_BITS=39
|
||||||
|
# CONFIG_CPU_BIG_ENDIAN is not set
|
||||||
|
CONFIG_SCHED_MC=y
|
||||||
|
# CONFIG_SCHED_SMT is not set
|
||||||
|
-CONFIG_NR_CPUS=8
|
||||||
|
+CONFIG_NR_CPUS=4
|
||||||
|
CONFIG_HOTPLUG_CPU=y
|
||||||
|
# CONFIG_NUMA is not set
|
||||||
|
# CONFIG_PREEMPT_NONE is not set
|
||||||
|
@@ -1841,6 +1841,8 @@ CONFIG_AMLOGIC_POWER=y
|
||||||
|
#
|
||||||
|
CONFIG_AMLOGIC_PCIE=y
|
||||||
|
# CONFIG_AMLOGIC_IRBLASTER_CORE is not set
|
||||||
|
+CONFIG_AMLOGIC_IRBLASTER_CORE=n
|
||||||
|
+CONFIG_AMLOGIC_IRBLASTER=n
|
||||||
|
CONFIG_AMLOGIC_IIO=y
|
||||||
|
|
||||||
|
#
|
||||||
|
diff --git a/drivers/amlogic/irblaster/sysfs.c b/drivers/amlogic/irblaster/sysfs.c
|
||||||
|
index 359d439c..e0e8eb05 100644
|
||||||
|
--- a/drivers/amlogic/irblaster/sysfs.c
|
||||||
|
+++ b/drivers/amlogic/irblaster/sysfs.c
|
||||||
|
@@ -16,6 +16,9 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/export.h>
|
||||||
|
+#include <linux/types.h>
|
||||||
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
|
||||||
|
index 471f26a2..97bd4ef3 100644
|
||||||
|
--- a/fs/userfaultfd.c
|
||||||
|
+++ b/fs/userfaultfd.c
|
||||||
|
@@ -496,7 +496,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
|
||||||
|
new_flags, vma->anon_vma,
|
||||||
|
vma->vm_file, vma->vm_pgoff,
|
||||||
|
vma_policy(vma),
|
||||||
|
- NULL_VM_UFFD_CTX);
|
||||||
|
+ NULL_VM_UFFD_CTX,
|
||||||
|
+ vma_get_anon_name(vma));
|
||||||
|
if (prev)
|
||||||
|
vma = prev;
|
||||||
|
else
|
||||||
|
@@ -555,9 +556,7 @@ static unsigned int userfaultfd_poll(struct file *file, poll_table *wait)
|
||||||
|
return POLLERR;
|
||||||
|
case UFFD_STATE_RUNNING:
|
||||||
|
/*
|
||||||
|
- * poll() never guarantees that read won't block.
|
||||||
|
- * userfaults can be waken before they're read().
|
||||||
|
- */
|
||||||
|
+ * poll() never guarantees that read won't block. userfaults can be waken before they're read(). */
|
||||||
|
if (unlikely(!(file->f_flags & O_NONBLOCK)))
|
||||||
|
return POLLERR;
|
||||||
|
/*
|
38
hardware/odroid-hc4/overlays/kernel/kernel.nix
Normal file
38
hardware/odroid-hc4/overlays/kernel/kernel.nix
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{ stdenv
|
||||||
|
, buildPackages
|
||||||
|
, fetchFromGitHub
|
||||||
|
, perl
|
||||||
|
, buildLinux
|
||||||
|
, libelf
|
||||||
|
, utillinux
|
||||||
|
, lib
|
||||||
|
, ...
|
||||||
|
}@args:
|
||||||
|
|
||||||
|
buildLinux (args // rec {
|
||||||
|
version = "4.9.241-107";
|
||||||
|
|
||||||
|
# modDirVersion needs to be x.y.z.
|
||||||
|
modDirVersion = "4.9.241";
|
||||||
|
|
||||||
|
# branchVersion needs to be x.y.
|
||||||
|
extraMeta.branch = "4.9";
|
||||||
|
|
||||||
|
# src = ./linux;
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "hardkernel";
|
||||||
|
repo = "linux";
|
||||||
|
rev = version;
|
||||||
|
sha256 = "1f004ahbj0x5nmr0240jdv7v6ssgbxd53ivsv7gra87hcm00hbn3";
|
||||||
|
};
|
||||||
|
|
||||||
|
defconfig = "odroidg12_defconfig";
|
||||||
|
|
||||||
|
autoModules = false;
|
||||||
|
structuredExtraConfig = with lib.kernel; {
|
||||||
|
NR_CPUS = lib.mkForce (freeform "8");
|
||||||
|
};
|
||||||
|
|
||||||
|
extraMeta.platforms = [ "aarch64-linux" ];
|
||||||
|
|
||||||
|
} // (args.argsOverride or { }))
|
13
hardware/odroid-hc4/overlays/kernel/overlay.nix
Normal file
13
hardware/odroid-hc4/overlays/kernel/overlay.nix
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
final: prev: {
|
||||||
|
linux_hardkernel = final.callPackage ./kernel.nix {
|
||||||
|
kernelPatches = [
|
||||||
|
# The kernel fails to cross-compile due to:
|
||||||
|
# 1. warnings caused by different interpretation of function pointers
|
||||||
|
# 2. NR_CPUS causing stack overflows when allocating cpu_topology
|
||||||
|
# 3. The IRBLASTER module not registering syscalls correctly
|
||||||
|
|
||||||
|
# The following patch makes the above warnings non-errors, decreases NR_CPUS to 4 and disables the IRBLASTER module.
|
||||||
|
({ name = "hardkernel-patches"; patch = ./kernel.diff; })
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
41
hardware/odroid-hc4/overlays/uboot/blx_fix.nix
Normal file
41
hardware/odroid-hc4/overlays/uboot/blx_fix.nix
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{ writeShellScript }:
|
||||||
|
writeShellScript "blx_fix" ''
|
||||||
|
#bl2 file size 41K, bl21 file size 3K (file size not equal runtime size)
|
||||||
|
#total 44K
|
||||||
|
#after encrypt process, bl2 add 4K header, cut off 4K tail
|
||||||
|
|
||||||
|
#bl30 limit 41K
|
||||||
|
#bl301 limit 12K
|
||||||
|
#bl2 limit 41K
|
||||||
|
#bl21 limit 3K, but encrypt tool need 48K bl2.bin, so fix to 7168byte.
|
||||||
|
|
||||||
|
#$7:name flag
|
||||||
|
if [ "$7" = "bl30" ]; then
|
||||||
|
declare blx_bin_limit=40960
|
||||||
|
declare blx01_bin_limit=13312
|
||||||
|
elif [ "$7" = "bl2" ]; then
|
||||||
|
declare blx_bin_limit=57344
|
||||||
|
declare blx01_bin_limit=4096
|
||||||
|
else
|
||||||
|
echo "blx_fix name flag not supported!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# blx_size: blx.bin size, zero_size: fill with zeros
|
||||||
|
declare -i blx_size=$(du -b $1 | awk '{print int($1)}')
|
||||||
|
declare -i zero_size=$blx_bin_limit-$blx_size
|
||||||
|
dd if=/dev/zero of=$2 bs=1 count=$zero_size
|
||||||
|
cat $1 $2 >$3
|
||||||
|
rm $2
|
||||||
|
|
||||||
|
declare -i blx01_size=$(du -b $4 | awk '{print int($1)}')
|
||||||
|
declare -i zero_size_01=$blx01_bin_limit-$blx01_size
|
||||||
|
dd if=/dev/zero of=$2 bs=1 count=$zero_size_01
|
||||||
|
cat $4 $2 >$5
|
||||||
|
|
||||||
|
cat $3 $5 >$6
|
||||||
|
|
||||||
|
rm $2
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
''
|
979
hardware/odroid-hc4/overlays/uboot/fip_create.diff
Normal file
979
hardware/odroid-hc4/overlays/uboot/fip_create.diff
Normal file
|
@ -0,0 +1,979 @@
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 730e8d752f..127a260ee8 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -875,8 +875,14 @@ $(ACS_BINARY): tools prepare u-boot.bin
|
||||||
|
bl21.bin: tools prepare u-boot.bin acs.bin
|
||||||
|
$(Q)$(MAKE) -C $(srctree)/$(CPUDIR)/${SOC}/firmware/bl21 all FIRMWARE=$@
|
||||||
|
|
||||||
|
+.PHONY: fip_create
|
||||||
|
+fip_create:
|
||||||
|
+ $(Q)$(MAKE) -C $(srctree)/tools/fip_create/
|
||||||
|
+ $(Q)cp $(srctree)/tools/fip_create/fip_create $(buildsrc)/fip/
|
||||||
|
+
|
||||||
|
+
|
||||||
|
.PHONY : fip.bin bootimage
|
||||||
|
-fip.bin bootimage: $(ACS_BINARY) $(BL301_BINARY)
|
||||||
|
+fip.bin bootimage: $(ACS_BINARY) $(BL301_BINARY) fip_create
|
||||||
|
$(Q)$(MAKE) -C $(srctree)/fip $@
|
||||||
|
|
||||||
|
#
|
||||||
|
diff --git a/tools/fip_create/Makefile b/tools/fip_create/Makefile
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..69569a1b2f6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tools/fip_create/Makefile
|
||||||
|
@@ -0,0 +1,62 @@
|
||||||
|
+#
|
||||||
|
+# Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
+#
|
||||||
|
+# Redistribution and use in source and binary forms, with or without
|
||||||
|
+# modification, are permitted provided that the following conditions are met:
|
||||||
|
+#
|
||||||
|
+# Redistributions of source code must retain the above copyright notice, this
|
||||||
|
+# list of conditions and the following disclaimer.
|
||||||
|
+#
|
||||||
|
+# Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
+# this list of conditions and the following disclaimer in the documentation
|
||||||
|
+# and/or other materials provided with the distribution.
|
||||||
|
+#
|
||||||
|
+# Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
+# to endorse or promote products derived from this software without specific
|
||||||
|
+# prior written permission.
|
||||||
|
+#
|
||||||
|
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
+# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+PROJECT = fip_create
|
||||||
|
+OBJECTS = fip_create.o
|
||||||
|
+
|
||||||
|
+CFLAGS = -Wall -Werror -pedantic -std=c99
|
||||||
|
+ifeq (${DEBUG},1)
|
||||||
|
+ CFLAGS += -g -O0 -DDEBUG
|
||||||
|
+else
|
||||||
|
+ CFLAGS += -O2
|
||||||
|
+endif
|
||||||
|
+
|
||||||
|
+# Make soft links and include from local directory otherwise wrong headers
|
||||||
|
+# could get pulled in from firmware tree.
|
||||||
|
+INCLUDE_PATHS = -I.
|
||||||
|
+
|
||||||
|
+CC := gcc
|
||||||
|
+RM := rm -rf
|
||||||
|
+
|
||||||
|
+.PHONY: all clean
|
||||||
|
+
|
||||||
|
+all: ${PROJECT}
|
||||||
|
+
|
||||||
|
+${PROJECT}: ${OBJECTS} Makefile
|
||||||
|
+ @echo " LD $@"
|
||||||
|
+ ${Q}${CC} ${OBJECTS} -o $@
|
||||||
|
+
|
||||||
|
+%.o: %.c %.h Makefile
|
||||||
|
+ @echo " CC $<"
|
||||||
|
+ ${Q}${CC} -c ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
|
||||||
|
+
|
||||||
|
+clean:
|
||||||
|
+ ${Q}${RM} ${PROJECT}
|
||||||
|
+ ${Q}${RM} ${OBJECTS}
|
||||||
|
diff --git a/tools/fip_create/fip_create.c b/tools/fip_create/fip_create.c
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..92affb9e7a9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tools/fip_create/fip_create.c
|
||||||
|
@@ -0,0 +1,677 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * Redistribution and use in source and binary forms, with or without
|
||||||
|
+ * modification, are permitted provided that the following conditions are met:
|
||||||
|
+ *
|
||||||
|
+ * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
+ * list of conditions and the following disclaimer.
|
||||||
|
+ *
|
||||||
|
+ * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
+ * this list of conditions and the following disclaimer in the documentation
|
||||||
|
+ * and/or other materials provided with the distribution.
|
||||||
|
+ *
|
||||||
|
+ * Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
+ * to endorse or promote products derived from this software without specific
|
||||||
|
+ * prior written permission.
|
||||||
|
+ *
|
||||||
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <getopt.h> /* getopt_long() is a GNU extention */
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include "fip_create.h"
|
||||||
|
+#include "firmware_image_package.h"
|
||||||
|
+
|
||||||
|
+/* Values returned by getopt() as part of the command line parsing */
|
||||||
|
+#define OPT_TOC_ENTRY 0
|
||||||
|
+#define OPT_DUMP 1
|
||||||
|
+#define OPT_HELP 2
|
||||||
|
+
|
||||||
|
+file_info_t files[MAX_FILES];
|
||||||
|
+unsigned file_info_count = 0;
|
||||||
|
+uuid_t uuid_null = {0};
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * TODO: Add ability to specify and flag different file types.
|
||||||
|
+ * Add flags to the toc_entry?
|
||||||
|
+ * const char* format_type_str[] = { "RAW", "ELF", "PIC" };
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/* The images used depends on the platform. */
|
||||||
|
+static entry_lookup_list_t toc_entry_lookup_list[] = {
|
||||||
|
+ { "Trusted Boot Firmware BL2", UUID_TRUSTED_BOOT_FIRMWARE_BL2,
|
||||||
|
+ "bl2", NULL, FLAG_FILENAME },
|
||||||
|
+ { "SCP Firmware BL3-0", UUID_SCP_FIRMWARE_BL30,
|
||||||
|
+ "bl30", NULL, FLAG_FILENAME},
|
||||||
|
+ { "SCP Firmware BL3-0-1", UUID_SCP_FIRMWARE_BL301,
|
||||||
|
+ "bl301", NULL, FLAG_FILENAME},
|
||||||
|
+ { "EL3 Runtime Firmware BL3-1", UUID_EL3_RUNTIME_FIRMWARE_BL31,
|
||||||
|
+ "bl31", NULL, FLAG_FILENAME},
|
||||||
|
+ { "Secure Payload BL3-2 (Trusted OS)", UUID_SECURE_PAYLOAD_BL32,
|
||||||
|
+ "bl32", NULL, FLAG_FILENAME},
|
||||||
|
+ { "Non-Trusted Firmware BL3-3", UUID_NON_TRUSTED_FIRMWARE_BL33,
|
||||||
|
+ "bl33", NULL, FLAG_FILENAME},
|
||||||
|
+ { NULL, {0}, 0 }
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* Return 0 for equal uuids */
|
||||||
|
+static inline int compare_uuids(const uuid_t *uuid1, const uuid_t *uuid2)
|
||||||
|
+{
|
||||||
|
+ return memcmp(uuid1, uuid2, sizeof(uuid_t));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static inline void copy_uuid(uuid_t *to_uuid, const uuid_t *from_uuid)
|
||||||
|
+{
|
||||||
|
+ memcpy(to_uuid, from_uuid, sizeof(uuid_t));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void print_usage(void)
|
||||||
|
+{
|
||||||
|
+ entry_lookup_list_t *entry = toc_entry_lookup_list;
|
||||||
|
+
|
||||||
|
+ printf("Usage: fip_create [options] FIP_FILENAME\n\n");
|
||||||
|
+ printf("\tThis tool is used to create a Firmware Image Package.\n\n");
|
||||||
|
+ printf("Options:\n");
|
||||||
|
+ printf("\t--help: Print this help message and exit\n");
|
||||||
|
+ printf("\t--dump: Print contents of FIP\n\n");
|
||||||
|
+ printf("\tComponents that can be added/updated:\n");
|
||||||
|
+ for (; entry->command_line_name != NULL; entry++) {
|
||||||
|
+ printf("\t--%s%s\t\t%s",
|
||||||
|
+ entry->command_line_name,
|
||||||
|
+ (entry->flags & FLAG_FILENAME) ? " FILENAME" : "",
|
||||||
|
+ entry->name);
|
||||||
|
+ printf("\n");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static entry_lookup_list_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
|
||||||
|
+{
|
||||||
|
+ unsigned int lookup_index = 0;
|
||||||
|
+
|
||||||
|
+ while (toc_entry_lookup_list[lookup_index].command_line_name != NULL) {
|
||||||
|
+ if (compare_uuids(&toc_entry_lookup_list[lookup_index].name_uuid,
|
||||||
|
+ uuid) == 0) {
|
||||||
|
+ return &toc_entry_lookup_list[lookup_index];
|
||||||
|
+ }
|
||||||
|
+ lookup_index++;
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static file_info_t *find_file_info_from_uuid(const uuid_t *uuid)
|
||||||
|
+{
|
||||||
|
+ int index;
|
||||||
|
+
|
||||||
|
+ for (index = 0; index < file_info_count; index++) {
|
||||||
|
+ if (compare_uuids(&files[index].name_uuid, uuid) == 0) {
|
||||||
|
+ return &files[index];
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int add_file_info_entry(entry_lookup_list_t *lookup_entry, char *filename)
|
||||||
|
+{
|
||||||
|
+ file_info_t *file_info_entry;
|
||||||
|
+ int error;
|
||||||
|
+ struct stat file_status;
|
||||||
|
+ bool is_new_entry = false;
|
||||||
|
+
|
||||||
|
+ /* Check if the file already exists in the array */
|
||||||
|
+ file_info_entry = find_file_info_from_uuid(&lookup_entry->name_uuid);
|
||||||
|
+ if (file_info_entry == NULL) {
|
||||||
|
+ /* The file does not exist in the current list; take the next
|
||||||
|
+ * one available in the file_info list. 'file_info_count' is
|
||||||
|
+ * incremented in case of successful update at the end of the
|
||||||
|
+ * function.
|
||||||
|
+ */
|
||||||
|
+ file_info_entry = &files[file_info_count];
|
||||||
|
+ is_new_entry = true;
|
||||||
|
+
|
||||||
|
+ /* Copy the uuid for the new entry */
|
||||||
|
+ copy_uuid(&file_info_entry->name_uuid,
|
||||||
|
+ &lookup_entry->name_uuid);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Get the file information for entry */
|
||||||
|
+ error = stat(filename, &file_status);
|
||||||
|
+ if (error != 0) {
|
||||||
|
+ printf("Error: Cannot get information for file \"%s\": %s\n",
|
||||||
|
+ filename, strerror(errno));
|
||||||
|
+ return errno;
|
||||||
|
+ }
|
||||||
|
+ file_info_entry->filename = filename;
|
||||||
|
+ file_info_entry->size = (unsigned int)file_status.st_size;
|
||||||
|
+ file_info_entry->align_size = 0x4000 * ((file_info_entry->size / 0x4000) + 1);
|
||||||
|
+ file_info_entry->entry = lookup_entry;
|
||||||
|
+
|
||||||
|
+ /* Increment the file_info counter on success if it is new file entry */
|
||||||
|
+ if (is_new_entry) {
|
||||||
|
+ file_info_count++;
|
||||||
|
+
|
||||||
|
+ /* Ensure we do not overflow */
|
||||||
|
+ if (file_info_count > MAX_FILES) {
|
||||||
|
+ printf("ERROR: Too many files in Package\n");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int write_memory_to_file(const uint8_t *start, const char *filename,
|
||||||
|
+ unsigned int size)
|
||||||
|
+{
|
||||||
|
+ FILE *stream;
|
||||||
|
+ unsigned int bytes_written;
|
||||||
|
+
|
||||||
|
+ /* Write the packed file out to the filesystem */
|
||||||
|
+ stream = fopen(filename, "r+");
|
||||||
|
+ if (stream == NULL) {
|
||||||
|
+ stream = fopen(filename, "w");
|
||||||
|
+ if (stream == NULL) {
|
||||||
|
+ printf("Error: Cannot create output file \"%s\": %s\n",
|
||||||
|
+ filename, strerror(errno));
|
||||||
|
+ return errno;
|
||||||
|
+ } else {
|
||||||
|
+ printf("Creating \"%s\"\n", filename);
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ printf("Updating \"%s\"\n", filename);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bytes_written = fwrite(start, sizeof(uint8_t), size, stream);
|
||||||
|
+ fclose(stream);
|
||||||
|
+
|
||||||
|
+ if (bytes_written != size) {
|
||||||
|
+ printf("Error: Incorrect write for file \"%s\": Size=%u,"
|
||||||
|
+ "Written=%u bytes.\n", filename, size, bytes_written);
|
||||||
|
+ return EIO;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static int read_file_to_memory(void *memory, const file_info_t *info)
|
||||||
|
+{
|
||||||
|
+ FILE *stream;
|
||||||
|
+ unsigned int bytes_read;
|
||||||
|
+
|
||||||
|
+ /* If the file_info is defined by its filename we need to load it */
|
||||||
|
+ if (info->filename) {
|
||||||
|
+ /* Read image from filesystem */
|
||||||
|
+ stream = fopen(info->filename, "r");
|
||||||
|
+ if (stream == NULL) {
|
||||||
|
+ printf("Error: Cannot open file \"%s\": %s\n",
|
||||||
|
+ info->filename, strerror(errno));
|
||||||
|
+ return errno;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bytes_read = (unsigned int)fread(memory, sizeof(uint8_t),
|
||||||
|
+ info->size, stream);
|
||||||
|
+ fclose(stream);
|
||||||
|
+ if (bytes_read != info->size) {
|
||||||
|
+ printf("Error: Incomplete read for file \"%s\":"
|
||||||
|
+ "Size=%u, Read=%u bytes.\n", info->filename,
|
||||||
|
+ info->size, bytes_read);
|
||||||
|
+ return EIO;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ if (info->image_buffer == NULL) {
|
||||||
|
+ printf("ERROR: info->image_buffer = NULL\n");
|
||||||
|
+ return EIO;
|
||||||
|
+ }
|
||||||
|
+ /* Copy the file_info buffer (extracted from the existing
|
||||||
|
+ * image package) into the new buffer.
|
||||||
|
+ */
|
||||||
|
+ memcpy(memory, info->image_buffer, info->size);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* Create the image package file */
|
||||||
|
+static int pack_images(const char *fip_filename)
|
||||||
|
+{
|
||||||
|
+ int status;
|
||||||
|
+ uint8_t *fip_base_address;
|
||||||
|
+ void *entry_address;
|
||||||
|
+ fip_toc_header_t *toc_header;
|
||||||
|
+ fip_toc_entry_t *toc_entry;
|
||||||
|
+ unsigned int entry_index;
|
||||||
|
+ unsigned int toc_size;
|
||||||
|
+ unsigned int fip_size;
|
||||||
|
+ unsigned int entry_offset_address;
|
||||||
|
+ unsigned int payload_size = 0;
|
||||||
|
+
|
||||||
|
+ /* Validate filename */
|
||||||
|
+ if ((fip_filename == NULL) || (strcmp(fip_filename, "") == 0)) {
|
||||||
|
+ return EINVAL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Payload size calculation */
|
||||||
|
+ for (entry_index = 0; entry_index < file_info_count; entry_index++) {
|
||||||
|
+ payload_size += files[entry_index].align_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Allocate memory for entire package, including the final null entry */
|
||||||
|
+ //toc_size = (sizeof(fip_toc_header_t) +
|
||||||
|
+ //(sizeof(fip_toc_entry_t) * (file_info_count + 1)));
|
||||||
|
+ toc_size = 0x4000;
|
||||||
|
+ fip_size = toc_size + payload_size;
|
||||||
|
+ fip_base_address = malloc(fip_size);
|
||||||
|
+ if (fip_base_address == NULL) {
|
||||||
|
+ printf("Error: Can't allocate enough memory to create package."
|
||||||
|
+ "Process aborted.\n");
|
||||||
|
+ return ENOMEM;
|
||||||
|
+ }
|
||||||
|
+ memset(fip_base_address, 0, fip_size);
|
||||||
|
+
|
||||||
|
+ /* Create ToC Header */
|
||||||
|
+ toc_header = (fip_toc_header_t *)fip_base_address;
|
||||||
|
+ toc_header->name = TOC_HEADER_NAME;
|
||||||
|
+ toc_header->serial_number = TOC_HEADER_SERIAL_NUMBER;
|
||||||
|
+ toc_header->flags = 0;
|
||||||
|
+
|
||||||
|
+ toc_entry = (fip_toc_entry_t *)(fip_base_address +
|
||||||
|
+ sizeof(fip_toc_header_t));
|
||||||
|
+
|
||||||
|
+ /* Calculate the starting address of the first image, right after the
|
||||||
|
+ * toc header.
|
||||||
|
+ */
|
||||||
|
+ entry_offset_address = toc_size;
|
||||||
|
+ entry_index = 0;
|
||||||
|
+
|
||||||
|
+ /* Create the package in memory. */
|
||||||
|
+ for (entry_index = 0; entry_index < file_info_count; entry_index++) {
|
||||||
|
+ entry_address = (fip_base_address + entry_offset_address);
|
||||||
|
+ status = read_file_to_memory(entry_address,
|
||||||
|
+ &files[entry_index]);
|
||||||
|
+ if (status != 0) {
|
||||||
|
+ printf("Error: While reading \"%s\" from filesystem.\n",
|
||||||
|
+ files[entry_index].filename);
|
||||||
|
+ return status;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ copy_uuid(&toc_entry->uuid, &files[entry_index].name_uuid);
|
||||||
|
+ toc_entry->offset_address = entry_offset_address;
|
||||||
|
+ toc_entry->size = files[entry_index].size;
|
||||||
|
+ toc_entry->flags = 0;
|
||||||
|
+ entry_offset_address += files[entry_index].align_size;
|
||||||
|
+ toc_entry++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Add a null uuid entry to mark the end of toc entries */
|
||||||
|
+ copy_uuid(&toc_entry->uuid, &uuid_null);
|
||||||
|
+ toc_entry->offset_address = entry_offset_address;
|
||||||
|
+ toc_entry->size = 0;
|
||||||
|
+ toc_entry->flags = 0;
|
||||||
|
+
|
||||||
|
+ /* Save the package to file */
|
||||||
|
+ status = write_memory_to_file(fip_base_address, fip_filename, fip_size);
|
||||||
|
+ if (status != 0) {
|
||||||
|
+ printf("Error: Failed while writing package to file \"%s\" "
|
||||||
|
+ "with status=%d.\n", fip_filename, status);
|
||||||
|
+ return status;
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+static void dump_toc(void)
|
||||||
|
+{
|
||||||
|
+ unsigned int index = 0;
|
||||||
|
+ unsigned int image_offset;
|
||||||
|
+ unsigned int image_size = 0;
|
||||||
|
+
|
||||||
|
+ //image_offset = sizeof(fip_toc_header_t) +
|
||||||
|
+ //(sizeof(fip_toc_entry_t) * (file_info_count + 1));
|
||||||
|
+ image_offset = 0x4000;
|
||||||
|
+
|
||||||
|
+ printf("Firmware Image Package ToC:\n");
|
||||||
|
+ printf("---------------------------\n");
|
||||||
|
+ for (index = 0; index < file_info_count; index++) {
|
||||||
|
+ if (files[index].entry) {
|
||||||
|
+ printf("- %s: ", files[index].entry->name);
|
||||||
|
+ } else {
|
||||||
|
+ printf("- Unknown entry: ");
|
||||||
|
+ }
|
||||||
|
+ image_size = files[index].size;
|
||||||
|
+
|
||||||
|
+ printf("offset=0x%X, size=0x%X\n", image_offset, image_size);
|
||||||
|
+ image_offset += files[index].align_size;
|
||||||
|
+
|
||||||
|
+ if (files[index].filename) {
|
||||||
|
+ printf(" file: '%s'\n", files[index].filename);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ printf("---------------------------\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* Read and load existing package into memory. */
|
||||||
|
+static int parse_fip(const char *fip_filename)
|
||||||
|
+{
|
||||||
|
+ FILE *fip;
|
||||||
|
+ char *fip_buffer;
|
||||||
|
+ char *fip_buffer_end;
|
||||||
|
+ int fip_size, read_fip_size;
|
||||||
|
+ fip_toc_header_t *toc_header;
|
||||||
|
+ fip_toc_entry_t *toc_entry;
|
||||||
|
+ bool found_last_toc_entry = false;
|
||||||
|
+ file_info_t *file_info_entry;
|
||||||
|
+ int status = -1;
|
||||||
|
+ struct stat st;
|
||||||
|
+
|
||||||
|
+ fip = fopen(fip_filename, "r");
|
||||||
|
+ if (fip == NULL) {
|
||||||
|
+ /* If the fip does not exist just return, it should not be
|
||||||
|
+ * considered as an error. The package will be created later
|
||||||
|
+ */
|
||||||
|
+ status = 0;
|
||||||
|
+ goto parse_fip_return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (stat(fip_filename, &st) != 0) {
|
||||||
|
+ status = errno;
|
||||||
|
+ goto parse_fip_fclose;
|
||||||
|
+ } else {
|
||||||
|
+ fip_size = (int)st.st_size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Allocate a buffer to read the package */
|
||||||
|
+ fip_buffer = (char *)malloc(fip_size);
|
||||||
|
+ if (fip_buffer == NULL) {
|
||||||
|
+ printf("ERROR: Cannot allocate %d bytes.\n", fip_size);
|
||||||
|
+ status = errno;
|
||||||
|
+ goto parse_fip_fclose;
|
||||||
|
+ }
|
||||||
|
+ fip_buffer_end = fip_buffer + fip_size;
|
||||||
|
+
|
||||||
|
+ /* Read the file */
|
||||||
|
+ read_fip_size = fread(fip_buffer, sizeof(char), fip_size, fip);
|
||||||
|
+ if (read_fip_size != fip_size) {
|
||||||
|
+ printf("ERROR: Cannot read the FIP.\n");
|
||||||
|
+ status = EIO;
|
||||||
|
+ goto parse_fip_free;
|
||||||
|
+ }
|
||||||
|
+ fclose(fip);
|
||||||
|
+ fip = NULL;
|
||||||
|
+
|
||||||
|
+ /* The package must at least contain the ToC Header */
|
||||||
|
+ if (fip_size < sizeof(fip_toc_header_t)) {
|
||||||
|
+ printf("ERROR: Given FIP is smaller than the ToC header.\n");
|
||||||
|
+ status = EINVAL;
|
||||||
|
+ goto parse_fip_free;
|
||||||
|
+ }
|
||||||
|
+ /* Set the ToC Header at the base of the buffer */
|
||||||
|
+ toc_header = (fip_toc_header_t *)fip_buffer;
|
||||||
|
+ /* The first toc entry should be just after the ToC header */
|
||||||
|
+ toc_entry = (fip_toc_entry_t *)(toc_header + 1);
|
||||||
|
+
|
||||||
|
+ /* While the ToC entry is contained into the buffer */
|
||||||
|
+ int cnt = 0;
|
||||||
|
+ while (((char *)toc_entry + sizeof(fip_toc_entry_t)) < fip_buffer_end) {
|
||||||
|
+ cnt++;
|
||||||
|
+ /* Check if the ToC Entry is the last one */
|
||||||
|
+ if (compare_uuids(&toc_entry->uuid, &uuid_null) == 0) {
|
||||||
|
+ found_last_toc_entry = true;
|
||||||
|
+ status = 0;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Add the entry into file_info */
|
||||||
|
+
|
||||||
|
+ /* Get the new entry in the array and clear it */
|
||||||
|
+ file_info_entry = &files[file_info_count++];
|
||||||
|
+ memset(file_info_entry, 0, sizeof(file_info_t));
|
||||||
|
+
|
||||||
|
+ /* Copy the info from the ToC entry */
|
||||||
|
+ copy_uuid(&file_info_entry->name_uuid, &toc_entry->uuid);
|
||||||
|
+ file_info_entry->image_buffer = fip_buffer +
|
||||||
|
+ toc_entry->offset_address;
|
||||||
|
+ file_info_entry->size = toc_entry->size;
|
||||||
|
+ file_info_entry->align_size = 0x4000 * ((toc_entry->size / 0x4000) + 1);
|
||||||
|
+
|
||||||
|
+ /* Check if there is a corresponding entry in lookup table */
|
||||||
|
+ file_info_entry->entry =
|
||||||
|
+ get_entry_lookup_from_uuid(&toc_entry->uuid);
|
||||||
|
+
|
||||||
|
+ /* Go to the next ToC entry */
|
||||||
|
+ toc_entry++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!found_last_toc_entry) {
|
||||||
|
+ printf("ERROR: Given FIP does not have an end ToC entry.\n");
|
||||||
|
+ status = EINVAL;
|
||||||
|
+ goto parse_fip_free;
|
||||||
|
+ } else {
|
||||||
|
+ /* All is well, we should not free any of the loaded images */
|
||||||
|
+ goto parse_fip_fclose;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ parse_fip_free:
|
||||||
|
+ if (fip_buffer != NULL) {
|
||||||
|
+ free(fip_buffer);
|
||||||
|
+ fip_buffer = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ parse_fip_fclose:
|
||||||
|
+ if (fip != NULL) {
|
||||||
|
+ fclose(fip);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ parse_fip_return:
|
||||||
|
+ return status;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* Parse all command-line options and return the FIP name if present. */
|
||||||
|
+static char *get_filename(int argc, char **argv, struct option *options)
|
||||||
|
+{
|
||||||
|
+ int c;
|
||||||
|
+ char *filename = NULL;
|
||||||
|
+
|
||||||
|
+ /* Reset option pointer so we parse all args. starts at 1.
|
||||||
|
+ * The filename is the only argument that does not have an option flag.
|
||||||
|
+ */
|
||||||
|
+ optind = 1;
|
||||||
|
+ while (1) {
|
||||||
|
+ c = getopt_long(argc, argv, "", options, NULL);
|
||||||
|
+ if (c == -1)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (c == '?') {
|
||||||
|
+ /* Failed to parse an option. Fail. */
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Only one argument left then it is the filename.
|
||||||
|
+ * We dont expect any other options
|
||||||
|
+ */
|
||||||
|
+ if (optind + 1 == argc)
|
||||||
|
+ filename = argv[optind];
|
||||||
|
+
|
||||||
|
+ return filename;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* Work through command-line options */
|
||||||
|
+static int parse_cmdline(int argc, char **argv, struct option *options,
|
||||||
|
+ int *do_pack)
|
||||||
|
+{
|
||||||
|
+ int c;
|
||||||
|
+ int status = 0;
|
||||||
|
+ int option_index = 0;
|
||||||
|
+ entry_lookup_list_t *lookup_entry;
|
||||||
|
+ int do_dump = 0;
|
||||||
|
+
|
||||||
|
+ /* restart parse to process all options. starts at 1. */
|
||||||
|
+ optind = 1;
|
||||||
|
+ while (1) {
|
||||||
|
+ c = getopt_long(argc, argv, "", options, &option_index);
|
||||||
|
+ if (c == -1)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ switch (c) {
|
||||||
|
+ case OPT_TOC_ENTRY:
|
||||||
|
+ if (optarg) {
|
||||||
|
+ /* Does the option expect a filename. */
|
||||||
|
+ lookup_entry = &toc_entry_lookup_list[option_index];
|
||||||
|
+ if (lookup_entry->flags & FLAG_FILENAME) {
|
||||||
|
+ status = add_file_info_entry(lookup_entry, optarg);
|
||||||
|
+ if (status != 0) {
|
||||||
|
+ printf("Failed to process %s\n",
|
||||||
|
+ options[option_index].name);
|
||||||
|
+ break;
|
||||||
|
+ } else {
|
||||||
|
+ /* Update package */
|
||||||
|
+ *do_pack = 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ case OPT_DUMP:
|
||||||
|
+ do_dump = 1;
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ case OPT_HELP:
|
||||||
|
+ print_usage();
|
||||||
|
+ exit(0);
|
||||||
|
+
|
||||||
|
+ default:
|
||||||
|
+ /* Unrecognised options are caught in get_filename() */
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ /* Do not dump toc if we have an error as it could hide the error */
|
||||||
|
+ if ((status == 0) && (do_dump)) {
|
||||||
|
+ dump_toc();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return status;
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int main(int argc, char **argv)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+ int status;
|
||||||
|
+ char *fip_filename;
|
||||||
|
+ int do_pack = 0;
|
||||||
|
+
|
||||||
|
+ /* Clear file list table. */
|
||||||
|
+ memset(files, 0, sizeof(files));
|
||||||
|
+
|
||||||
|
+ /* Initialise for getopt_long().
|
||||||
|
+ * Use image table as defined at top of file to get options.
|
||||||
|
+ * Add 'dump' option, 'help' option and end marker.
|
||||||
|
+ */
|
||||||
|
+ static struct option long_options[(sizeof(toc_entry_lookup_list)/
|
||||||
|
+ sizeof(entry_lookup_list_t)) + 2];
|
||||||
|
+
|
||||||
|
+ for (i = 0;
|
||||||
|
+ /* -1 because we dont want to process end marker in toc table */
|
||||||
|
+ i < sizeof(toc_entry_lookup_list)/sizeof(entry_lookup_list_t) - 1;
|
||||||
|
+ i++) {
|
||||||
|
+ long_options[i].name = toc_entry_lookup_list[i].command_line_name;
|
||||||
|
+ /* The only flag defined at the moment is for a FILENAME */
|
||||||
|
+ long_options[i].has_arg = toc_entry_lookup_list[i].flags ? 1 : 0;
|
||||||
|
+ long_options[i].flag = 0;
|
||||||
|
+ long_options[i].val = OPT_TOC_ENTRY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Add '--dump' option */
|
||||||
|
+ long_options[i].name = "dump";
|
||||||
|
+ long_options[i].has_arg = 0;
|
||||||
|
+ long_options[i].flag = 0;
|
||||||
|
+ long_options[i].val = OPT_DUMP;
|
||||||
|
+
|
||||||
|
+ /* Add '--help' option */
|
||||||
|
+ long_options[++i].name = "help";
|
||||||
|
+ long_options[i].has_arg = 0;
|
||||||
|
+ long_options[i].flag = 0;
|
||||||
|
+ long_options[i].val = OPT_HELP;
|
||||||
|
+
|
||||||
|
+ /* Zero the last entry (required) */
|
||||||
|
+ long_options[++i].name = 0;
|
||||||
|
+ long_options[i].has_arg = 0;
|
||||||
|
+ long_options[i].flag = 0;
|
||||||
|
+ long_options[i].val = 0;
|
||||||
|
+
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ /* Print all supported options */
|
||||||
|
+ for (i = 0; i < sizeof(long_options)/sizeof(struct option); i++) {
|
||||||
|
+ printf("long opt (%d) : name = %s\n", i, long_options[i].name);
|
||||||
|
+ }
|
||||||
|
+#endif /* DEBUG */
|
||||||
|
+
|
||||||
|
+ /* As the package may already exist and is to be updated we need to get
|
||||||
|
+ * the filename from the arguments and load from it.
|
||||||
|
+ * NOTE: As this is the first function to look at the program arguments
|
||||||
|
+ * it causes a failure if bad options were provided.
|
||||||
|
+ */
|
||||||
|
+ fip_filename = get_filename(argc, argv, long_options);
|
||||||
|
+
|
||||||
|
+ /* Try to open the file and load it into memory */
|
||||||
|
+ if (fip_filename != NULL) {
|
||||||
|
+ status = parse_fip(fip_filename);
|
||||||
|
+ if (status != 0) {
|
||||||
|
+ return status;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Work through provided program arguments and perform actions */
|
||||||
|
+ status = parse_cmdline(argc, argv, long_options, &do_pack);
|
||||||
|
+ if (status != 0) {
|
||||||
|
+ return status;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ if (fip_filename == NULL) {
|
||||||
|
+ printf("ERROR: Missing FIP filename\n");
|
||||||
|
+ print_usage();
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Processed all command line options. Create/update the package if
|
||||||
|
+ * required.
|
||||||
|
+ */
|
||||||
|
+ if (do_pack) {
|
||||||
|
+ status = pack_images(fip_filename);
|
||||||
|
+ if (status != 0) {
|
||||||
|
+ printf("Failed to create package (status = %d).\n",
|
||||||
|
+ status);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return status;
|
||||||
|
+}
|
||||||
|
diff --git a/tools/fip_create/fip_create.h b/tools/fip_create/fip_create.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..81e0897f987
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tools/fip_create/fip_create.h
|
||||||
|
@@ -0,0 +1,61 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * Redistribution and use in source and binary forms, with or without
|
||||||
|
+ * modification, are permitted provided that the following conditions are met:
|
||||||
|
+ *
|
||||||
|
+ * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
+ * list of conditions and the following disclaimer.
|
||||||
|
+ *
|
||||||
|
+ * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
+ * this list of conditions and the following disclaimer in the documentation
|
||||||
|
+ * and/or other materials provided with the distribution.
|
||||||
|
+ *
|
||||||
|
+ * Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
+ * to endorse or promote products derived from this software without specific
|
||||||
|
+ * prior written permission.
|
||||||
|
+ *
|
||||||
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef __FIP_CREATE_H__
|
||||||
|
+#define __FIP_CREATE_H__
|
||||||
|
+
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <uuid.h>
|
||||||
|
+
|
||||||
|
+#define MAX_FILES 10
|
||||||
|
+
|
||||||
|
+/* TODO: Update this number as required */
|
||||||
|
+#define TOC_HEADER_SERIAL_NUMBER 0x12345678
|
||||||
|
+
|
||||||
|
+#define FLAG_FILENAME (1 << 0)
|
||||||
|
+
|
||||||
|
+typedef struct entry_lookup_list {
|
||||||
|
+ const char *name;
|
||||||
|
+ uuid_t name_uuid;
|
||||||
|
+ const char *command_line_name;
|
||||||
|
+ struct file_info *info;
|
||||||
|
+ unsigned int flags;
|
||||||
|
+} entry_lookup_list_t;
|
||||||
|
+
|
||||||
|
+typedef struct file_info {
|
||||||
|
+ uuid_t name_uuid;
|
||||||
|
+ const char *filename;
|
||||||
|
+ unsigned int size;
|
||||||
|
+ unsigned int align_size;
|
||||||
|
+ void *image_buffer;
|
||||||
|
+ entry_lookup_list_t *entry;
|
||||||
|
+} file_info_t;
|
||||||
|
+
|
||||||
|
+#endif /* __FIP_CREATE_H__ */
|
||||||
|
diff --git a/tools/fip_create/firmware_image_package.h b/tools/fip_create/firmware_image_package.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..0a8a67d9ac9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tools/fip_create/firmware_image_package.h
|
||||||
|
@@ -0,0 +1,68 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * Redistribution and use in source and binary forms, with or without
|
||||||
|
+ * modification, are permitted provided that the following conditions are met:
|
||||||
|
+ *
|
||||||
|
+ * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
+ * list of conditions and the following disclaimer.
|
||||||
|
+ *
|
||||||
|
+ * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
+ * this list of conditions and the following disclaimer in the documentation
|
||||||
|
+ * and/or other materials provided with the distribution.
|
||||||
|
+ *
|
||||||
|
+ * Neither the name of ARM nor the names of its contributors may be used
|
||||||
|
+ * to endorse or promote products derived from this software without specific
|
||||||
|
+ * prior written permission.
|
||||||
|
+ *
|
||||||
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef __FIRMWARE_IMAGE_PACKAGE_H__
|
||||||
|
+#define __FIRMWARE_IMAGE_PACKAGE_H__
|
||||||
|
+
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <uuid.h>
|
||||||
|
+
|
||||||
|
+/* This is used as a signature to validate the blob header */
|
||||||
|
+#define TOC_HEADER_NAME 0xAA640001
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+/* ToC Entry UUIDs */
|
||||||
|
+#define UUID_TRUSTED_BOOT_FIRMWARE_BL2 \
|
||||||
|
+ {0x0becf95f, 0x224d, 0x4d3e, 0xa5, 0x44, {0xc3, 0x9d, 0x81, 0xc7, 0x3f, 0x0a} }
|
||||||
|
+#define UUID_SCP_FIRMWARE_BL30 \
|
||||||
|
+ {0x3dfd6697, 0xbe89, 0x49e8, 0xae, 0x5d, {0x78, 0xa1, 0x40, 0x60, 0x82, 0x13} }
|
||||||
|
+#define UUID_SCP_FIRMWARE_BL301 \
|
||||||
|
+ {0xAABBCCDD, 0xABCD, 0xEFEF, 0xAB, 0xCD, {0x12, 0x34, 0x56, 0x78, 0xAB, 0xCD} }
|
||||||
|
+#define UUID_EL3_RUNTIME_FIRMWARE_BL31 \
|
||||||
|
+ {0x6d08d447, 0xfe4c, 0x4698, 0x9b, 0x95, {0x29, 0x50, 0xcb, 0xbd, 0x5a, 0x00} }
|
||||||
|
+#define UUID_SECURE_PAYLOAD_BL32 \
|
||||||
|
+ {0x89e1d005, 0xdc53, 0x4713, 0x8d, 0x2b, {0x50, 0x0a, 0x4b, 0x7a, 0x3e, 0x38} }
|
||||||
|
+#define UUID_NON_TRUSTED_FIRMWARE_BL33 \
|
||||||
|
+ {0xa7eed0d6, 0xeafc, 0x4bd5, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} }
|
||||||
|
+
|
||||||
|
+typedef struct fip_toc_header {
|
||||||
|
+ uint32_t name;
|
||||||
|
+ uint32_t serial_number;
|
||||||
|
+ uint64_t flags;
|
||||||
|
+} fip_toc_header_t;
|
||||||
|
+
|
||||||
|
+typedef struct fip_toc_entry {
|
||||||
|
+ uuid_t uuid;
|
||||||
|
+ uint64_t offset_address;
|
||||||
|
+ uint64_t size;
|
||||||
|
+ uint64_t flags;
|
||||||
|
+} fip_toc_entry_t;
|
||||||
|
+
|
||||||
|
+#endif /* __FIRMWARE_IMAGE_PACKAGE_H__ */
|
||||||
|
diff --git a/tools/fip_create/uuid.h b/tools/fip_create/uuid.h
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..5c4767b5b55
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/tools/fip_create/uuid.h
|
||||||
|
@@ -0,0 +1,61 @@
|
||||||
|
+/*-
|
||||||
|
+ * Copyright (c) 2002 Marcel Moolenaar
|
||||||
|
+ * All rights reserved.
|
||||||
|
+ *
|
||||||
|
+ * Redistribution and use in source and binary forms, with or without
|
||||||
|
+ * modification, are permitted provided that the following conditions
|
||||||
|
+ * are met:
|
||||||
|
+ *
|
||||||
|
+ * 1. Redistributions of source code must retain the above copyright
|
||||||
|
+ * notice, this list of conditions and the following disclaimer.
|
||||||
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
+ * notice, this list of conditions and the following disclaimer in the
|
||||||
|
+ * documentation and/or other materials provided with the distribution.
|
||||||
|
+ *
|
||||||
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+ *
|
||||||
|
+ * $FreeBSD$
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Portions copyright (c) 2014, ARM Limited and Contributors.
|
||||||
|
+ * All rights reserved.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef _SYS_UUID_H_
|
||||||
|
+#define _SYS_UUID_H_
|
||||||
|
+
|
||||||
|
+#include <sys/cdefs.h>
|
||||||
|
+
|
||||||
|
+/* Length of a node address (an IEEE 802 address). */
|
||||||
|
+#define _UUID_NODE_LEN 6
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * See also:
|
||||||
|
+ * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
|
||||||
|
+ * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
|
||||||
|
+ *
|
||||||
|
+ * A DCE 1.1 compatible source representation of UUIDs.
|
||||||
|
+ */
|
||||||
|
+struct uuid {
|
||||||
|
+ uint32_t time_low;
|
||||||
|
+ uint16_t time_mid;
|
||||||
|
+ uint16_t time_hi_and_version;
|
||||||
|
+ uint8_t clock_seq_hi_and_reserved;
|
||||||
|
+ uint8_t clock_seq_low;
|
||||||
|
+ uint8_t node[_UUID_NODE_LEN];
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* XXX namespace pollution? */
|
||||||
|
+typedef struct uuid uuid_t;
|
||||||
|
+
|
||||||
|
+#endif /* _SYS_UUID_H_ */
|
50
hardware/odroid-hc4/overlays/uboot/hardkernel.nix
Normal file
50
hardware/odroid-hc4/overlays/uboot/hardkernel.nix
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
{ gcc49Stdenv, git, bc, bison, flex, nettools, buildPackages, arm-gcc49 }:
|
||||||
|
|
||||||
|
gcc49Stdenv.mkDerivation {
|
||||||
|
name = "hardkernel-uboot";
|
||||||
|
src = builtins.fetchTarball {
|
||||||
|
url = "https://github.com/hardkernel/u-boot/archive/766167bbe787e494e47376b31cd017b897e9594c.tar.gz";
|
||||||
|
sha256 = "0hj49jf9w2w55r7fjpx8asb92r85lws8mvq4mvl1v309z7k56zwv";
|
||||||
|
};
|
||||||
|
patches = [ ./pwd.diff ./fip_create.diff ];
|
||||||
|
nativeBuildInputs = [
|
||||||
|
git
|
||||||
|
gcc49Stdenv.cc
|
||||||
|
bc
|
||||||
|
bison
|
||||||
|
flex
|
||||||
|
nettools
|
||||||
|
];
|
||||||
|
depsBuildBuild = [
|
||||||
|
arm-gcc49
|
||||||
|
buildPackages.gcc49Stdenv.cc
|
||||||
|
];
|
||||||
|
makeFlags = [
|
||||||
|
"CROSS_COMPILE=${gcc49Stdenv.cc.targetPrefix}"
|
||||||
|
];
|
||||||
|
configurePhase = ''
|
||||||
|
make odroidc4_defconfig
|
||||||
|
'';
|
||||||
|
buildPhase = ''
|
||||||
|
make
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/fip $out/bin
|
||||||
|
cp build/scp_task/bl301.bin \
|
||||||
|
build/board/hardkernel/odroidc4/firmware/acs.bin \
|
||||||
|
fip/g12a/bl2.bin \
|
||||||
|
fip/g12a/bl30.bin \
|
||||||
|
fip/g12a/bl31.img \
|
||||||
|
fip/g12a/ddr3_1d.fw \
|
||||||
|
fip/g12a/ddr4_1d.fw \
|
||||||
|
fip/g12a/ddr4_2d.fw \
|
||||||
|
fip/g12a/diag_lpddr4.fw \
|
||||||
|
fip/g12a/lpddr3_1d.fw \
|
||||||
|
fip/g12a/lpddr4_1d.fw \
|
||||||
|
fip/g12a/lpddr4_2d.fw \
|
||||||
|
fip/g12a/piei.fw \
|
||||||
|
fip/g12a/aml_ddr.fw \
|
||||||
|
$out/fip/
|
||||||
|
cp fip/g12a/aml_encrypt_g12a $out/bin/
|
||||||
|
'';
|
||||||
|
}
|
15
hardware/odroid-hc4/overlays/uboot/meson64-tools.nix
Normal file
15
hardware/odroid-hc4/overlays/uboot/meson64-tools.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{ stdenv, python2, python3 }:
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "meson64-tools";
|
||||||
|
nativeBuildInputs = [ python2 python3 ];
|
||||||
|
src = builtins.fetchTarball {
|
||||||
|
url = "https://github.com/angerman/meson64-tools/archive/a2d57d11fd8b4242b903c10dca9d25f7f99d8ff0.tar.gz";
|
||||||
|
sha256 = "1487cr7sv34yry8f0chaj6s2g3736dzq0aqw239ahdy30yg7hb2v";
|
||||||
|
};
|
||||||
|
|
||||||
|
preBuild = ''
|
||||||
|
patchShebangs .
|
||||||
|
patchShebangs ./mbedtls/scripts/generate_psa_constants.py
|
||||||
|
'';
|
||||||
|
makeFlags = [ "PREFIX=$(out)/bin" ];
|
||||||
|
}
|
28
hardware/odroid-hc4/overlays/uboot/overlay.nix
Normal file
28
hardware/odroid-hc4/overlays/uboot/overlay.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
final: prev:
|
||||||
|
let
|
||||||
|
platform = final.lib.systems.examples.aarch64-multiplatform // {
|
||||||
|
gcc = {
|
||||||
|
arch = "armv8-a+crypto";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
arm64 = final.pkgsCross.aarch64-embedded;
|
||||||
|
arm = final.pkgsCross.arm-embedded;
|
||||||
|
uboot-hardkernel = arm64.callPackage ./hardkernel.nix {
|
||||||
|
arm-gcc49 = arm.buildPackages.gcc49;
|
||||||
|
};
|
||||||
|
with-crypto = import final.path {
|
||||||
|
crossSystem = platform;
|
||||||
|
};
|
||||||
|
meson64-tools = with-crypto.buildPackages.callPackage ./meson64-tools.nix { };
|
||||||
|
blx_fix = arm64.buildPackages.callPackage ./blx_fix.nix { };
|
||||||
|
uboot = arm64.callPackage ./u-boot.nix {
|
||||||
|
inherit uboot-hardkernel meson64-tools blx_fix;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
uboot-hardkernel = uboot;
|
||||||
|
ubootTools-hardkernel = final.buildPackages.ubootTools;
|
||||||
|
buildPackages = prev.buildPackages // {
|
||||||
|
ubootTools-hardkernel = final.buildPackages.buildPackages.ubootTools;
|
||||||
|
};
|
||||||
|
}
|
13
hardware/odroid-hc4/overlays/uboot/pwd.diff
Normal file
13
hardware/odroid-hc4/overlays/uboot/pwd.diff
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 730e8d752f..127a260ee8 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -134,7 +134,7 @@ ifneq ($(KBUILD_OUTPUT),)
|
||||||
|
# check that the output directory actually exists
|
||||||
|
saved-output := $(KBUILD_OUTPUT)
|
||||||
|
KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
|
||||||
|
- && /bin/pwd)
|
||||||
|
+ && pwd)
|
||||||
|
$(if $(KBUILD_OUTPUT),, \
|
||||||
|
$(error failed to create output directory "$(saved-output)"))
|
||||||
|
|
98
hardware/odroid-hc4/overlays/uboot/u-boot.nix
Normal file
98
hardware/odroid-hc4/overlays/uboot/u-boot.nix
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
{ stdenv
|
||||||
|
, git
|
||||||
|
, bc
|
||||||
|
, bison
|
||||||
|
, flex
|
||||||
|
, nettools
|
||||||
|
, openssl
|
||||||
|
, buildPackages
|
||||||
|
, uboot-hardkernel
|
||||||
|
, meson64-tools
|
||||||
|
, blx_fix
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
name = "uboot";
|
||||||
|
src = builtins.fetchTarball {
|
||||||
|
url = "https://github.com/u-boot/u-boot/archive/15f7e0dc01d8a851fb1bfbf0e47eab5b67ed26b3.tar.gz";
|
||||||
|
sha256 = "1ardkap35pi2dsajag728fnvlvpfmdrsa0igj93wbkbf2ypzzhf6";
|
||||||
|
};
|
||||||
|
CROSS_COMPILE = stdenv.cc.targetPrefix;
|
||||||
|
configurePhase = ''
|
||||||
|
make odroid-c4_defconfig
|
||||||
|
'';
|
||||||
|
buildPhase = ''
|
||||||
|
make
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir fip
|
||||||
|
cp ${uboot-hardkernel}/fip/* fip/
|
||||||
|
cp u-boot.bin fip/bl33.bin
|
||||||
|
${blx_fix} \
|
||||||
|
fip/bl30.bin \
|
||||||
|
fip/zero_tmp \
|
||||||
|
fip/bl30_zero.bin \
|
||||||
|
fip/bl301.bin \
|
||||||
|
fip/bl301_zero.bin \
|
||||||
|
fip/bl30_new.bin \
|
||||||
|
bl30
|
||||||
|
|
||||||
|
${blx_fix} \
|
||||||
|
fip/bl2.bin \
|
||||||
|
fip/zero_tmp \
|
||||||
|
fip/bl2_zero.bin \
|
||||||
|
fip/acs.bin \
|
||||||
|
fip/bl21_zero.bin \
|
||||||
|
fip/bl2_new.bin \
|
||||||
|
bl2
|
||||||
|
|
||||||
|
${meson64-tools}/bin/bl30sig \
|
||||||
|
--input fip/bl30_new.bin \
|
||||||
|
--output fip/bl30_new.bin.g12a.enc \
|
||||||
|
--level v3
|
||||||
|
${meson64-tools}/bin/bl3sig \
|
||||||
|
--input fip/bl30_new.bin.g12a.enc \
|
||||||
|
--output fip/bl30_new.bin.enc \
|
||||||
|
--level v3 --type bl30
|
||||||
|
${meson64-tools}/bin/bl3sig \
|
||||||
|
--input fip/bl31.img \
|
||||||
|
--output fip/bl31.img.enc \
|
||||||
|
--level v3 --type bl31
|
||||||
|
${meson64-tools}/bin/bl3sig \
|
||||||
|
--input fip/bl33.bin --compress lz4 \
|
||||||
|
--output fip/bl33.bin.enc \
|
||||||
|
--level v3 --type bl33 --compress lz4
|
||||||
|
${meson64-tools}/bin/bl2sig \
|
||||||
|
--input fip/bl2_new.bin \
|
||||||
|
--output fip/bl2.n.bin.sig
|
||||||
|
${meson64-tools}/bin/bootmk \
|
||||||
|
--output $out \
|
||||||
|
--bl2 fip/bl2.n.bin.sig \
|
||||||
|
--bl30 fip/bl30_new.bin.enc \
|
||||||
|
--bl31 fip/bl31.img.enc \
|
||||||
|
--bl33 fip/bl33.bin.enc \
|
||||||
|
--ddrfw1 fip/ddr4_1d.fw \
|
||||||
|
--ddrfw2 fip/ddr4_2d.fw \
|
||||||
|
--ddrfw3 fip/ddr3_1d.fw \
|
||||||
|
--ddrfw4 fip/piei.fw \
|
||||||
|
--ddrfw5 fip/lpddr4_1d.fw \
|
||||||
|
--ddrfw6 fip/lpddr4_2d.fw \
|
||||||
|
--ddrfw7 fip/diag_lpddr4.fw \
|
||||||
|
--ddrfw8 fip/aml_ddr.fw \
|
||||||
|
--ddrfw9 fip/lpddr3_1d.fw \
|
||||||
|
--level v3
|
||||||
|
'';
|
||||||
|
nativeBuildInputs = [
|
||||||
|
git
|
||||||
|
bc
|
||||||
|
bison
|
||||||
|
flex
|
||||||
|
nettools
|
||||||
|
];
|
||||||
|
|
||||||
|
depsBuildBuild = [
|
||||||
|
buildPackages.stdenv.cc
|
||||||
|
buildPackages.openssl.dev
|
||||||
|
];
|
||||||
|
}
|
15
hardware/odroid-hc4/uboot/boot-ini-builder.nix
Normal file
15
hardware/odroid-hc4/uboot/boot-ini-builder.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{ pkgs }:
|
||||||
|
|
||||||
|
pkgs.substituteAll {
|
||||||
|
src = ./boot-ini-builder.sh;
|
||||||
|
isExecutable = true;
|
||||||
|
path = [
|
||||||
|
pkgs.coreutils
|
||||||
|
pkgs.gnused
|
||||||
|
pkgs.gnugrep
|
||||||
|
pkgs.gzip
|
||||||
|
pkgs.ubootTools-hardkernel
|
||||||
|
];
|
||||||
|
configIni = ./config.ini;
|
||||||
|
inherit (pkgs) bash;
|
||||||
|
}
|
189
hardware/odroid-hc4/uboot/boot-ini-builder.sh
Normal file
189
hardware/odroid-hc4/uboot/boot-ini-builder.sh
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
#! @bash@/bin/sh -e
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
|
||||||
|
export PATH=/empty
|
||||||
|
for i in @path@; do PATH=$PATH:$i/bin; done
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "usage: $0 -t <timeout> -c <path-to-default-configuration> [-d <boot-dir>] [-g <num-generations>] [-n <dtbName>]" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout= # Timeout in centiseconds
|
||||||
|
default= # Default configuration
|
||||||
|
target=/boot # Target directory
|
||||||
|
numGenerations=0 # Number of other generations to include in the menu
|
||||||
|
|
||||||
|
while getopts "t:c:d:g:n:" opt; do
|
||||||
|
case "$opt" in
|
||||||
|
t) # U-Boot interprets '0' as infinite and negative as instant boot
|
||||||
|
if [ "$OPTARG" -lt 0 ]; then
|
||||||
|
timeout=0
|
||||||
|
elif [ "$OPTARG" = 0 ]; then
|
||||||
|
timeout=-10
|
||||||
|
else
|
||||||
|
timeout=$((OPTARG * 10))
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
c) default="$OPTARG" ;;
|
||||||
|
d) target="$OPTARG" ;;
|
||||||
|
g) numGenerations="$OPTARG" ;;
|
||||||
|
n) dtbName="$OPTARG" ;;
|
||||||
|
\?) usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
[ "$timeout" = "" -o "$default" = "" ] && usage
|
||||||
|
|
||||||
|
mkdir -p $target/nixos
|
||||||
|
|
||||||
|
# Convert a path to a file in the Nix store such as
|
||||||
|
# /nix/store/<hash>-<name>/file to <hash>-<name>-<file>.
|
||||||
|
cleanName() {
|
||||||
|
local path="$1"
|
||||||
|
echo "$path" | sed 's|^/nix/store/||' | sed 's|/|-|g'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy a file from the Nix store to $target/nixos.
|
||||||
|
declare -A filesCopied
|
||||||
|
|
||||||
|
copyToKernelsDir() {
|
||||||
|
local src=$(readlink -f "$1")
|
||||||
|
local dst="$target/nixos/$(cleanName $src)"
|
||||||
|
# Don't copy the file if $dst already exists. This means that we
|
||||||
|
# have to create $dst atomically to prevent partially copied
|
||||||
|
# kernels or initrd if this script is ever interrupted.
|
||||||
|
if ! test -e $dst; then
|
||||||
|
local dstTmp=$dst.tmp.$$
|
||||||
|
cp -r $src $dstTmp
|
||||||
|
mv $dstTmp $dst
|
||||||
|
fi
|
||||||
|
filesCopied[$dst]=1
|
||||||
|
result=$dst
|
||||||
|
}
|
||||||
|
|
||||||
|
copyInitrd() {
|
||||||
|
local src=$(readlink -f "$1")
|
||||||
|
local dst="$target/nixos/$(cleanName $src)"
|
||||||
|
if ! test -e $dst; then
|
||||||
|
local initrd=$dst.initrd.tmp.$$
|
||||||
|
local dstTmp=$dst.tmp.$$
|
||||||
|
# Unzip and convert ramdisk to uInitrd format (u-boot initrd)
|
||||||
|
gzip -d <"$path/initrd" >$initrd
|
||||||
|
mkimage -A arm64 -O linux -T ramdisk -C none -d "$initrd" "$dstTmp" >/dev/null
|
||||||
|
rm $initrd
|
||||||
|
mv $dstTmp $dst
|
||||||
|
fi
|
||||||
|
filesCopied[$dst]=1
|
||||||
|
result=$dst
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy its kernel, initrd and dtbs to $target/nixos, and echo out boot.ini entry
|
||||||
|
addEntry() {
|
||||||
|
local path=$(readlink -f "$1")
|
||||||
|
local tag="$2" # Generation number or 'default'
|
||||||
|
|
||||||
|
if ! test -e $path/kernel -a -e $path/initrd; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
copyToKernelsDir "$path/kernel"
|
||||||
|
kernel=$result
|
||||||
|
copyInitrd "$path/initrd"
|
||||||
|
initrd=$result
|
||||||
|
dtbDir=$(readlink -m "$path/dtbs")
|
||||||
|
if [ -e "$dtbDir" ]; then
|
||||||
|
copyToKernelsDir "$dtbDir"
|
||||||
|
dtbs=$result
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "load mmc \${devno}:1 \${k_addr} nixos/$(basename $kernel)"
|
||||||
|
echo "load mmc \${devno}:1 \${dtb_loadaddr} nixos/$(basename $dtbs)/amlogic/meson64_odroid\${variant}.dtb"
|
||||||
|
echo "fdt addr \${dtb_loadaddr}"
|
||||||
|
echo "load mmc \${devno}:1 \${initrd_loadaddr} nixos/$(basename $initrd)"
|
||||||
|
echo "setenv bootargs \"\${bootargs} \""
|
||||||
|
echo "# Boot Args"
|
||||||
|
echo "setenv bootargs \"root=root=/dev/mmcblk\${devno}p2 rootwait rw \${condev} \${amlogic} no_console_suspend fsck.repair=yes net.ifnames=0 elevator=noop hdmimode=\${hdmimode} cvbsmode=576cvbs max_freq_a55=\${max_freq_a55} maxcpus=\${maxcpus} voutmode=\${voutmode} \${cmode} disablehpd=\${disablehpd} cvbscable=\${cvbscable} overscan=\${overscan} \${hid_quirks} monitor_onoff=\${monitor_onoff} logo=osd0,loaded \${cec_enable} sdrmode=\${sdrmode} enable_wol=\${enable_wol} systemConfig=$path init=$path/init\""
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpFile="$target/boot.ini.tmp.$$"
|
||||||
|
|
||||||
|
# This configuration was adapted from the Ubuntu 20.04 image provided
|
||||||
|
# on the Hardkernel Wiki.
|
||||||
|
cat >$tmpFile <<EOF
|
||||||
|
ODROIDC4-UBOOT-CONFIG
|
||||||
|
# Generated file, all changes will be lost on nixos-rebuild!
|
||||||
|
|
||||||
|
setenv bootlabel "Hardkernel NixOS 21.05"
|
||||||
|
|
||||||
|
setenv board "odroidc4"
|
||||||
|
setenv display_autodetect "true"
|
||||||
|
setenv hdmimode "1080p60hz"
|
||||||
|
setenv monitor_onoff "false" # true or false
|
||||||
|
setenv overscan "100"
|
||||||
|
setenv sdrmode "auto"
|
||||||
|
setenv voutmode "hdmi"
|
||||||
|
setenv disablehpd "false"
|
||||||
|
setenv cec "true"
|
||||||
|
setenv disable_vu7 "true"
|
||||||
|
setenv max_freq_a55 "1908" # 1.908 GHz, default value
|
||||||
|
setenv maxcpus "4"
|
||||||
|
setenv enable_wol "0"
|
||||||
|
|
||||||
|
# Set load addresses
|
||||||
|
setenv dtb_loadaddr "0x10000000"
|
||||||
|
setenv dtbo_addr_r "0x11000000"
|
||||||
|
setenv k_addr "0x1100000"
|
||||||
|
setenv loadaddr "0x1B00000"
|
||||||
|
setenv initrd_loadaddr "0x00000000"
|
||||||
|
|
||||||
|
if test "\${variant}" = "hc4"; then
|
||||||
|
setenv max_freq_a55 "1800"
|
||||||
|
fi
|
||||||
|
|
||||||
|
load mmc \${devno}:1 \${loadaddr} config.ini \
|
||||||
|
&& ini generic \${loadaddr}
|
||||||
|
if test "x\${overlay_profile}" != "x"; then
|
||||||
|
ini overlay_\${overlay_profile} \${loadaddr}
|
||||||
|
fi
|
||||||
|
|
||||||
|
setenv condev "console=ttyS0,115200n8" # on both
|
||||||
|
|
||||||
|
### Normal HDMI Monitors
|
||||||
|
if test "\${display_autodetect}" = "true"; then hdmitx edid; fi
|
||||||
|
if test "\${hdmimode}" = "custombuilt"; then setenv cmode "modeline=\${modeline}"; fi
|
||||||
|
if test "\${cec}" = "true"; then setenv cec_enable "hdmitx=cec3f"; fi
|
||||||
|
if test "\${disable_vu7}" = "false"; then setenv hid_quirks "usbhid.quirks=0x0eef:0x0005:0x0004"; fi
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# The boot.ini file format only supports a single entry
|
||||||
|
# as far as I can tell.
|
||||||
|
addEntry $default default >>$tmpFile
|
||||||
|
|
||||||
|
cat >>$tmpFile <<EOF
|
||||||
|
if test "x{overlays}" != "x"; then
|
||||||
|
fdt resize \${overlay_resize}
|
||||||
|
for overlay in \${overlays}; do
|
||||||
|
load mmc \${devno}:1 \${dtbo_addr_r} amlogic/overlays/\${board}/\${overlay}.dtbo \
|
||||||
|
&& fdt apply \${dtbo_addr_r}
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# unzip the kernel
|
||||||
|
unzip \${k_addr} \${loadaddr}
|
||||||
|
# boot
|
||||||
|
booti \${loadaddr} \${initrd_loadaddr} \${dtb_loadaddr}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
mv -f $tmpFile $target/boot.ini
|
||||||
|
cp -f @configIni@ $target/config.ini
|
||||||
|
# Remove obsolete files from $target/nixos.
|
||||||
|
for fn in $target/nixos/*; do
|
||||||
|
if ! test "${filesCopied[$fn]}" = 1; then
|
||||||
|
echo "Removing no longer needed boot file: $fn"
|
||||||
|
chmod +w -- "$fn"
|
||||||
|
rm -rf -- "$fn"
|
||||||
|
fi
|
||||||
|
done
|
101
hardware/odroid-hc4/uboot/config.ini
Executable file
101
hardware/odroid-hc4/uboot/config.ini
Executable file
|
@ -0,0 +1,101 @@
|
||||||
|
[generic]
|
||||||
|
; Auto Detection of Monitor settings based on your Screen information
|
||||||
|
display_autodetect=true
|
||||||
|
|
||||||
|
; HDMI Mode
|
||||||
|
; Resolution Configuration
|
||||||
|
; Symbol | Resolution
|
||||||
|
; ----------------------+-------------
|
||||||
|
; "480x272p60hz" | 480x272 Progressive 60Hz
|
||||||
|
; "480x320p60hz" | 480x320 Progressive 60Hz
|
||||||
|
; "480p60hz" | 720x480 Progressive 60Hz
|
||||||
|
; "576p50hz" | 720x576 Progressive 50Hz
|
||||||
|
; "720p60hz" | 1280x720 Progressive 60Hz
|
||||||
|
; "720p50hz" | 1280x720 Progressive 50Hz
|
||||||
|
; "1080p60hz" | 1920x1080 Progressive 60Hz
|
||||||
|
; "1080p50hz" | 1920x1080 Progressive 50Hz
|
||||||
|
; "1080p30hz" | 1920x1080 Progressive 30Hz
|
||||||
|
; "1080p24hz" | 1920x1080 Progressive 24Hz
|
||||||
|
; "1080i60hz" | 1920x1080 Interlaced 60Hz
|
||||||
|
; "1080i50hz" | 1920x1080 Interlaced 50Hz
|
||||||
|
; "2160p60hz" | 3840x2160 Progressive 60Hz
|
||||||
|
; "2160p50hz" | 3840x2160 Progressive 50Hz
|
||||||
|
; "2160p30hz" | 3840x2160 Progressive 30Hz
|
||||||
|
; "2160p25hz" | 3840x2160 Progressive 25Hz
|
||||||
|
; "2160p24hz" | 3840x2160 Progressive 24Hz
|
||||||
|
; "smpte24hz" | 3840x2160 Progressive 24Hz SMPTE
|
||||||
|
; "2160p60hz420" | 3840x2160 Progressive 60Hz YCbCr 4:2:0
|
||||||
|
; "2160p50hz420" | 3840x2160 Progressive 50Hz YCbCr 4:2:0
|
||||||
|
; "640x480p60hz" | 640x480 Progressive 60Hz
|
||||||
|
; "800x480p60hz" | 800x480 Progressive 60Hz
|
||||||
|
; "800x600p60hz" | 800x600 Progressive 60Hz
|
||||||
|
; "1024x600p60hz" | 1024x600 Progressive 60Hz
|
||||||
|
; "1024x768p60hz" | 1024x768 Progressive 60Hz
|
||||||
|
; "1280x800p60hz" | 1280x800 Progressive 60Hz
|
||||||
|
; "1280x1024p60hz" | 1280x1024 Progressive 60Hz
|
||||||
|
; "1360x768p60hz" | 1360x768 Progressive 60Hz
|
||||||
|
; "1440x900p60hz" | 1440x900 Progressive 60Hz
|
||||||
|
; "1600x900p60hz" | 1600x900 Progressive 60Hz
|
||||||
|
; "1600x1200p60hz" | 1600x1200 Progressive 60Hz
|
||||||
|
; "1680x1050p60hz" | 1680x1050 Progressive 60Hz
|
||||||
|
; "1920x1200p60hz" | 1920x1200 Progressive 60Hz
|
||||||
|
; "2560x1080p60hz" | 2560x1080 Progressive 60Hz
|
||||||
|
; "2560x1440p60hz" | 2560x1440 Progressive 60Hz
|
||||||
|
; "2560x1600p60hz" | 2560x1600 Progressive 60Hz
|
||||||
|
; "3440x1440p60hz" | 3440x1440 Progressive 60Hz
|
||||||
|
hdmimode=1080p60hz
|
||||||
|
|
||||||
|
; Monitor output
|
||||||
|
; Controls if HDMI PHY should output anything to the monitor
|
||||||
|
monitor_onoff=false
|
||||||
|
|
||||||
|
; Overscan percentage
|
||||||
|
; This value scales down the actual screen size by the percentage below
|
||||||
|
; valid range is 80 to 100
|
||||||
|
overscan=100
|
||||||
|
|
||||||
|
; SDR/HDR Configuration
|
||||||
|
; This forces SDR or HDR modes
|
||||||
|
; valid options are: sdr hdr auto
|
||||||
|
sdrmode=auto
|
||||||
|
|
||||||
|
; voutmode : hdmi or dvi
|
||||||
|
; hdmi / dvi
|
||||||
|
voutmode=hdmi
|
||||||
|
|
||||||
|
; HPD enable/disable option
|
||||||
|
; false / true
|
||||||
|
disablehpd=false
|
||||||
|
|
||||||
|
; Enable/Disable CEC
|
||||||
|
cec=true
|
||||||
|
|
||||||
|
; Hardkernel ODROID-VU7 support
|
||||||
|
; By default VU7 support is disabled
|
||||||
|
disable_vu7=true
|
||||||
|
|
||||||
|
; Maximum CPU frequency
|
||||||
|
; 100/250/500/667/1000/1200/1404/1500/1608/1704/1800/1908 (stock)/2016/2100
|
||||||
|
; max_freq_a55=1800
|
||||||
|
|
||||||
|
|
||||||
|
; Maximum number of CPU cores
|
||||||
|
maxcpus=4
|
||||||
|
|
||||||
|
; Wake-On-Lan support (0=disable, 1=enable)
|
||||||
|
; enable_wol=1
|
||||||
|
|
||||||
|
|
||||||
|
; Device Tree Overlay
|
||||||
|
overlay_resize=16384
|
||||||
|
overlay_profile=
|
||||||
|
overlays="spi0 i2c0 i2c1 uart0"
|
||||||
|
|
||||||
|
[overlay_custom]
|
||||||
|
overlays="i2c0 i2c1"
|
||||||
|
|
||||||
|
[overlay_hktft32]
|
||||||
|
overlays="hktft32"
|
||||||
|
|
||||||
|
[overlay_hktft35]
|
||||||
|
overlays="hktft35"
|
54
hardware/odroid-hc4/uboot/hardkernel-uboot.nix
Normal file
54
hardware/odroid-hc4/uboot/hardkernel-uboot.nix
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
blCfg = config.boot.loader;
|
||||||
|
dtCfg = config.hardware.deviceTree;
|
||||||
|
cfg = blCfg.hardkernel-uboot;
|
||||||
|
|
||||||
|
timeoutStr = if blCfg.timeout == null then "-1" else toString blCfg.timeout;
|
||||||
|
|
||||||
|
# The builder used to write during system activation
|
||||||
|
builder = import ./boot-ini-builder.nix { inherit pkgs; };
|
||||||
|
# The builder exposed in populateCmd, which runs on the build architecture
|
||||||
|
populateBuilder = import ./boot-ini-builder.nix { pkgs = pkgs.buildPackages; };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
boot.loader.hardkernel-uboot = {
|
||||||
|
enable = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Whether to generate an extlinux-compatible configuration file
|
||||||
|
under <literal>/boot/extlinux.conf</literal>. For instance,
|
||||||
|
U-Boot's generic distro boot support uses this file format.
|
||||||
|
See <link xlink:href="http://git.denx.de/?p=u-boot.git;a=blob;f=doc/README.distro;hb=refs/heads/master">U-boot's documentation</link>
|
||||||
|
for more information.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
populateCmd = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
readOnly = true;
|
||||||
|
description = ''
|
||||||
|
Contains the builder command used to populate an image,
|
||||||
|
honoring all options except the <literal>-c <path-to-default-configuration></literal>
|
||||||
|
argument.
|
||||||
|
Useful to have for sdImage.populateRootCommands
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config =
|
||||||
|
let
|
||||||
|
builderArgs = "-t ${timeoutStr}" + lib.optionalString (dtCfg.name != null) " -n ${dtCfg.name}";
|
||||||
|
in
|
||||||
|
mkIf cfg.enable {
|
||||||
|
system.build.installBootLoader = "${builder} ${builderArgs} -c";
|
||||||
|
system.boot.loader.id = "hardkernel-uboot";
|
||||||
|
boot.loader.hardkernel-uboot.populateCmd = "${populateBuilder} ${builderArgs}";
|
||||||
|
};
|
||||||
|
}
|
31
hosts/ceilidh.nix
Normal file
31
hosts/ceilidh.nix
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# NixOps configuration for pàidh-tri
|
||||||
|
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
../hardware/odroid-hc4
|
||||||
|
];
|
||||||
|
|
||||||
|
# Comment out deployment when building the SD Image.
|
||||||
|
deployment.targetHost = "10.42.0.121";
|
||||||
|
networking.hostName = "ceilidh"; # Define your hostname.
|
||||||
|
|
||||||
|
# Ensure the right package architecture is used
|
||||||
|
nixpkgs = {
|
||||||
|
config = {
|
||||||
|
allowUnfree = true;
|
||||||
|
allowUnsupportedSystem = true;
|
||||||
|
};
|
||||||
|
localSystem = {
|
||||||
|
system = "aarch64-linux";
|
||||||
|
config = "aarch64-unknown-linux-gnu";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
gnupg # GPL OpenPGP implementation
|
||||||
|
];
|
||||||
|
|
||||||
|
system.stateVersion = "21.05"; # The version of NixOS originally installed
|
||||||
|
}
|
Loading…
Reference in a new issue