diff options
author | Vishal Bhoj <vishal.bhoj@linaro.org> | 2016-06-09 10:02:07 +0100 |
---|---|---|
committer | Dmitry Shmidt <dimitrysh@google.com> | 2016-07-13 11:23:02 -0700 |
commit | b7a135fe1aaea3ac45cfb35228623bffa5bc7ddb (patch) | |
tree | 216a0c8ef862ad10ae6e45284ed87e59398c050e | |
parent | c4ac11a7147235822a217eb943bdf27372884eca (diff) | |
download | hikey-b7a135fe1aaea3ac45cfb35228623bffa5bc7ddb.tar.gz |
hikey: Add wrapper script to build uefi
Booloader sources are located under device/linaro/bootloader
Change-Id: I8b35f9a292f5037eac2e0a281f5345921a313b93
Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
-rw-r--r-- | bootloader/Makefile | 29 | ||||
-rw-r--r-- | bootloader/README.md | 10 | ||||
-rw-r--r-- | l-loader/.gitignore | 3 | ||||
-rw-r--r-- | l-loader/COPYING | 25 | ||||
-rw-r--r-- | l-loader/Makefile | 27 | ||||
-rw-r--r-- | l-loader/README.md | 6 | ||||
-rwxr-xr-x | l-loader/gen_loader.py | 268 | ||||
-rwxr-xr-x | l-loader/generate_ptable.sh | 87 | ||||
-rw-r--r-- | l-loader/l-loader.lds | 32 | ||||
-rw-r--r-- | l-loader/start.S | 100 | ||||
-rwxr-xr-x | uefi-tools/atf-build.sh | 222 | ||||
-rw-r--r-- | uefi-tools/common-functions | 86 | ||||
-rwxr-xr-x | uefi-tools/opteed-build.sh | 158 | ||||
-rwxr-xr-x | uefi-tools/parse-platforms.py | 81 | ||||
-rw-r--r-- | uefi-tools/platforms.config | 245 | ||||
-rwxr-xr-x | uefi-tools/tos-build.sh | 88 | ||||
-rwxr-xr-x | uefi-tools/uefi-build.sh | 331 | ||||
-rw-r--r-- | uefi-tools/uefi-build.sh.bash_completion | 24 |
18 files changed, 1822 insertions, 0 deletions
diff --git a/bootloader/Makefile b/bootloader/Makefile new file mode 100644 index 00000000..4d0f031b --- /dev/null +++ b/bootloader/Makefile @@ -0,0 +1,29 @@ +AARCH64_TOOLCHAIN=GCC49 +EDK2_DIR=$(ANDROID_BUILD_TOP)/device/linaro/bootloader/edk2 +UEFI_TOOLS_DIR=$(ANDROID_BUILD_TOP)/device/linaro/hikey/uefi-tools +ATF_DIR=$(ANDROID_BUILD_TOP)/device/linaro/bootloader/arm-trusted-firmware +PRODUCT_OUT?=out/target/product/hikey +DIST_DIR?=$(ANDROID_BUILD_TOP)/out/dist + +all: $(DIST_DIR)/fip.bin $(DIST_DIR)/l-loader.bin + +$(DIST_DIR)/fip.bin: + cd $(EDK2_DIR) && \ + rm -rf Conf/tools_def.txt Conf/BuildEnv.sh Conf/build_rule.txt Conf/target.txt Conf/tools_def.txt && \ + export CROSS_COMPILE_32=arm-linux-androideabi- && \ + export CROSS_COMPILE_64=aarch64-linux-android- && \ + rm -rf OpenPlatformPkg && \ + ln -sf $(EDK2_DIR)/../OpenPlatformPkg OpenPlatformPkg && \ + rm -rf $(EDK2_DIR)/Build/ && \ + mkdir -p $(EDK2_DIR)/Build/ && \ + mkdir -p $(DIST_DIR) && \ + mkdir -p $(ANDROID_BUILD_TOP)/$(PRODUCT_OUT)/obj/uefi && \ + ln -sf $(ANDROID_BUILD_TOP)/$(PRODUCT_OUT)/obj/uefi $(EDK2_DIR)/Build/HiKey && \ + $(UEFI_TOOLS_DIR)/uefi-build.sh -b RELEASE -D EDK2_OUT_DIR=$(ANDROID_BUILD_TOP)/$(PRODUCT_OUT)/obj/uefi -a $(ATF_DIR) hikey && \ + cp $(EDK2_DIR)/Build/HiKey/RELEASE_GCC49/FV/fip.bin $(DIST_DIR)/ + +$(DIST_DIR)/l-loader.bin: $(DIST_DIR)/fip.bin + cd $(ANDROID_BUILD_TOP)/device/linaro/hikey/l-loader && \ + ln -sf $(EDK2_DIR)/Build/HiKey/RELEASE_GCC49/FV//bl1.bin && \ + make CROSS_COMPILE=arm-linux-androideabi- l-loader.bin && \ + mv l-loader.bin $(DIST_DIR)/ diff --git a/bootloader/README.md b/bootloader/README.md new file mode 100644 index 00000000..1271cfd4 --- /dev/null +++ b/bootloader/README.md @@ -0,0 +1,10 @@ +Bootloader is build with ArmTF and UEFI from sources located at: + device/linaro/bootloader +To build fip.bin and l-loader.bin do: + $ cd device/linaro/hikey/bootloader + $ make +Results will be in out/dist + +We can also generate ptable (needs root privilege) with below commands: + $ cd device/linaro/hikey/l-loader/ + $ make ptable.img diff --git a/l-loader/.gitignore b/l-loader/.gitignore new file mode 100644 index 00000000..b282a0e1 --- /dev/null +++ b/l-loader/.gitignore @@ -0,0 +1,3 @@ +/*.o +/*.img +/*.bin diff --git a/l-loader/COPYING b/l-loader/COPYING new file mode 100644 index 00000000..4ad3f200 --- /dev/null +++ b/l-loader/COPYING @@ -0,0 +1,25 @@ +Copyright (c) 2014-2016, Linaro Ltd. 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. + +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. diff --git a/l-loader/Makefile b/l-loader/Makefile new file mode 100644 index 00000000..93afcd1a --- /dev/null +++ b/l-loader/Makefile @@ -0,0 +1,27 @@ +CROSS_COMPILE?=arm-linux-gnueabihf- +CC=$(CROSS_COMPILE)gcc +CFLAGS=-march=armv7-a +LD=$(CROSS_COMPILE)ld +OBJCOPY=$(CROSS_COMPILE)objcopy +BL1=bl1.bin +PTABLE_LST:=aosp-4g aosp-8g linux-4g linux-8g + +all: l-loader.bin ptable.img + +%.o: %.S $(DEPS) + $(CC) $(CFLAGS) -c -o $@ $< + +l-loader.bin: start.o $(BL1) + $(LD) -Bstatic -Tl-loader.lds -Ttext 0xf9800800 start.o -o loader + $(OBJCOPY) -O binary loader temp + python gen_loader.py -o $@ --img_loader=temp --img_bl1=$(BL1) + rm -f loader temp + +ptable.img: + for ptable in $(PTABLE_LST); do \ + sudo PTABLE=$${ptable} bash -x generate_ptable.sh;\ + python gen_loader.py -o ptable-$${ptable}.img --img_prm_ptable=prm_ptable.img;\ + done + +clean: + rm -f *.o *.img l-loader.bin diff --git a/l-loader/README.md b/l-loader/README.md new file mode 100644 index 00000000..e5dcd990 --- /dev/null +++ b/l-loader/README.md @@ -0,0 +1,6 @@ +# l-loader + +Used to switch from aarch32 to aarch64 and boot. First image to be flashed +when in recovery mode. + +HiKey specific. diff --git a/l-loader/gen_loader.py b/l-loader/gen_loader.py new file mode 100755 index 00000000..2d763ca9 --- /dev/null +++ b/l-loader/gen_loader.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python + +import os +import os.path +import sys, getopt +import binascii +import struct +import string + +class generator(object): + # + # struct l_loader_head { + # unsigned int first_instr; + # unsigned char magic[16]; @ BOOTMAGICNUMBER! + # unsigned int l_loader_start; + # unsigned int l_loader_end; + # }; + file_header = [0, 0, 0, 0, 0, 0, 0] + + # + # struct entry_head { + # unsigned char magic[8]; @ ENTY + # unsigned char name[8]; @ loader/bl1 + # unsigned int start_lba; + # unsigned int count_lba; + # unsigned int flag; @ boot partition or not + # }; + + s1_entry_name = ['loader', 'bl1'] + s2_entry_name = ['primary', 'second'] + + block_size = 512 + + stage = 0 + + # set in self.add() + idx = 0 + + # set in self.parse() + ptable_lba = 0 + stable_lba = 0 + + # file pointer + p_entry = 0 + p_file = 0 + + def __init__(self, out_img): + try: + self.fp = open(out_img, "wb+") + except IOError, e: + print "*** file open error:", e + sys.exit(3) + else: + self.entry_hd = [[0 for col in range(7)] for row in range(5)] + + def __del__(self): + self.fp.close() + + # parse partition from the primary ptable + def parse(self, fname): + try: + fptable = open(fname, "rb") + except IOError, e: + print "*** file open error:", e + sys.exit(3) + else: + # skip the first block in primary partition table + # that is MBR protection information + fptable.read(self.block_size) + # check whether it's a primary paritition table + data = struct.unpack("8s", fptable.read(8)) + efi_magic = 'EFI PART' + if cmp("EFI PART", data[0]): + print "It's not partition table image." + fptable.close() + sys.exit(4) + # skip 16 bytes + fptable.read(16) + # get lba of both primary partition table and secondary partition table + data = struct.unpack("QQQQ", fptable.read(32)) + self.ptable_lba = data[0] - 1 + self.stable_lba = data[3] + 1 + # skip 24 bytes + fptable.read(24) + data = struct.unpack("i", fptable.read(4)) + pentries = data[0] + # skip the reset in this block + fptable.read(self.block_size - 84) + + for i in range(1, pentries): + # name is encoded as UTF-16 + d0,lba,d2,name = struct.unpack("32sQ16s72s", fptable.read(128)) + plainname = unicode(name, "utf-16") + if (not cmp(plainname[0:7], 'l-loader'[0:7])): + print 'bl1_lba: ', lba + self.bl1_lba = lba + sys.exit(1) + + fptable.close() + + def add(self, lba, fname): + try: + fsize = os.path.getsize(fname) + except IOError, e: + print "*** file open error:", e + sys.exit(4) + else: + blocks = (fsize + self.block_size - 1) / self.block_size + if (self.stage == 1): + # Boot Area1 in eMMC + bootp = 1 + if self.idx == 0: + self.p_entry = 28 + elif (self.stage == 2): + # User Data Area in eMMC + bootp = 0 + # create an empty block only for stage2 + # This empty block is used to store entry head + print 'p_file: ', self.p_file, 'p_entry: ', self.p_entry + if self.idx == 0: + self.fp.seek(self.p_file) + for i in range (0, self.block_size): + zero = struct.pack('x') + self.fp.write(zero) + self.p_file += self.block_size + self.p_entry = 0 + else: + print "wrong stage ", stage, "is specified" + sys.exit(4) + # Maybe the file size isn't aligned. So pad it. + if (self.idx == 0) and (self.stage == 1): + if fsize > 2048: + print 'loader size exceeds 2KB. file size: ', fsize + sys.exit(4) + else: + left_bytes = 2048 - fsize + else: + left_bytes = fsize % self.block_size + if left_bytes: + left_bytes = self.block_size - left_bytes + print 'lba: ', lba, 'blocks: ', blocks, 'bootp: ', bootp, 'fname: ', fname + # write images + fimg = open(fname, "rb") + for i in range (0, blocks): + buf = fimg.read(self.block_size) + self.fp.seek(self.p_file) + self.fp.write(buf) + # p_file is the file pointer of the new binary file + # At last, it means the total block size of the new binary file + self.p_file += self.block_size + + if (self.idx == 0) and (self.stage == 1): + self.p_file = 2048 + print 'p_file: ', self.p_file, 'last block is ', fsize % self.block_size, 'bytes', ' tell: ', self.fp.tell(), 'left_bytes: ', left_bytes + if left_bytes: + for i in range (0, left_bytes): + zero = struct.pack('x') + self.fp.write(zero) + print 'p_file: ', self.p_file, ' pad to: ', self.fp.tell() + + # write entry information at the header + if self.stage == 1: + byte = struct.pack('8s8siii', 'ENTRYHDR', self.s1_entry_name[self.idx], lba, blocks, bootp) + elif self.stage == 2: + byte = struct.pack('8s8siii', 'ENTRYHDR', self.s2_entry_name[self.idx], lba, blocks, bootp) + self.fp.seek(self.p_entry) + self.fp.write(byte) + self.p_entry += 28 + self.idx += 1 + + fimg.close() + + def hex2(self, data): + return data > 0 and hex(data) or hex(data & 0xffffffff) + + def end(self): + if self.stage == 1: + self.fp.seek(20) + start,end = struct.unpack("ii", self.fp.read(8)) + print "start: ", self.hex2(start), 'end: ', self.hex2(end) + end = start + self.p_file + print "start: ", self.hex2(start), 'end: ', self.hex2(end) + self.fp.seek(24) + byte = struct.pack('i', end) + self.fp.write(byte) + self.fp.close() + + def create_stage1(self, img_loader, img_bl1, output_img): + print '+-----------------------------------------------------------+' + print ' Input Images:' + print ' loader: ', img_loader + print ' bl1: ', img_bl1 + print ' Ouput Image: ', output_img + print '+-----------------------------------------------------------+\n' + + self.stage = 1 + + # The first 2KB is reserved + # The next 2KB is for loader image + self.add(4, img_loader) # img_loader doesn't exist in partition table + print 'self.idx: ', self.idx + # bl1.bin starts from 4KB + self.add(8, img_bl1) # img_bl1 doesn't exist in partition table + + def create_stage2(self, img_prm_ptable, img_sec_ptable, output_img): + print '+-----------------------------------------------------------+' + print ' Input Images:' + print ' primary partition table: ', img_prm_ptable + print ' secondary partition table: ', img_sec_ptable + print ' Ouput Image: ', output_img + print '+-----------------------------------------------------------+\n' + + self.stage = 2 + self.parse(img_prm_ptable) + self.add(self.ptable_lba, img_prm_ptable) + if (cmp(img_sec_ptable, 'secondary partition table')): + # Doesn't match. It means that secondary ptable is specified. + self.add(self.stable_lba, img_sec_ptable) + else: + print 'Don\'t need secondary partition table' + +def main(argv): + stage1 = 0 + stage2 = 0 + img_prm_ptable = "primary partition table" + img_sec_ptable = "secondary partition table" + try: + opts, args = getopt.getopt(argv,"ho:",["img_loader=","img_bl1=","img_prm_ptable=","img_sec_ptable="]) + except getopt.GetoptError: + print 'gen_loader.py -o <l-loader.bin> --img_loader <l-loader> --img_bl1 <bl1.bin> --img_prm_ptable <prm_ptable.img> --img_sec_ptable <sec_ptable.img>' + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + print 'gen_loader.py -o <l-loader.bin> --img_loader <l-loader> --img_bl1 <bl1.bin> --img_prm_ptable <prm_ptable.img> --img_sec_ptable <sec_ptable.img>' + sys.exit(1) + elif opt == '-o': + output_img = arg + elif opt in ("--img_loader"): + img_loader = arg + stage1 = 1 + elif opt in ("--img_bl1"): + img_bl1 = arg + stage1 = 1 + elif opt in ("--img_prm_ptable"): + img_prm_ptable = arg + stage2 = 1 + elif opt in ("--img_sec_ptable"): + img_sec_ptable = arg + + loader = generator(output_img) + loader.idx = 0 + + if (stage1 == 1) and (stage2 == 1): + print 'There are only loader & BL1 in stage1.' + print 'And there are primary partition table, secondary partition table and FIP in stage2.' + sys.exit(1) + elif (stage1 == 0) and (stage2 == 0): + print 'No input images are specified.' + sys.exit(1) + elif stage1 == 1: + loader.create_stage1(img_loader, img_bl1, output_img) + elif stage2 == 1: + loader.create_stage2(img_prm_ptable, img_sec_ptable, output_img) + + loader.end() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/l-loader/generate_ptable.sh b/l-loader/generate_ptable.sh new file mode 100755 index 00000000..3bc232ee --- /dev/null +++ b/l-loader/generate_ptable.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# Generate partition table for HiKey eMMC +# +# tiny: for testing purpose. +# aosp: 10 entries (same as linux with userdata). +# linux: 9 entries (same as aosp without userdata). + +PTABLE=${PTABLE:-aosp} +SECTOR_SIZE=512 +TEMP_FILE=$(mktemp /tmp/${PTABLE}.XXXXXX) + +case ${PTABLE} in + tiny) + SECTOR_NUMBER=81920 + ;; + aosp-4g|linux-4g) + SECTOR_NUMBER=7471104 + ;; + aosp-8g|linux-8g) + SECTOR_NUMBER=15269888 + ;; +esac + +BK_PTABLE_LBA=$(expr ${SECTOR_NUMBER} - 33) +echo ${BK_PTABLE_LBA} + +# get the partition table +case ${PTABLE} in + tiny) + dd if=/dev/zero of=${TEMP_FILE} bs=${SECTOR_SIZE} count=${SECTOR_NUMBER} + sgdisk -U -R -v ${TEMP_FILE} + sgdisk -n 1:2048:4095 -t 1:0700 -u 1:F9F21F01-A8D4-5F0E-9746-594869AEC3E4 -c 1:"vrl" -p ${TEMP_FILE} + sgdisk -n 2:4096:6143 -t 2:0700 -u 2:F9F21F02-A8D4-5F04-9746-594869AEC3E4 -c 2:"vrl_backup" -p ${TEMP_FILE} + ;; + aosp*) + dd if=/dev/zero of=${TEMP_FILE} bs=${SECTOR_SIZE} count=${SECTOR_NUMBER} + sgdisk -U 2CB85345-6A91-4043-8203-723F0D28FBE8 -v ${TEMP_FILE} + #[1: vrl: 1M-2M] + sgdisk -n 1:0:+1M -t 1:0700 -u 1:496847AB-56A1-4CD5-A1AD-47F4ACF055C9 -c 1:"vrl" ${TEMP_FILE} + #[2: vrl_backup: 2M-3M] + sgdisk -n 2:0:+1M -t 2:0700 -u 2:61A36FC1-8EFB-4899-84D8-B61642EFA723 -c 2:"vrl_backup" ${TEMP_FILE} + #[3: mcuimage: 3M-4M] + sgdisk -n 3:0:+1M -t 3:0700 -u 3:65007411-962D-4781-9B2C-51DD7DF22CC3 -c 3:"mcuimage" ${TEMP_FILE} + #[4: fastboot: 4M-12M] + sgdisk -n 4:0:+8M -t 4:EF02 -u 4:496847AB-56A1-4CD5-A1AD-47F4ACF055C9 -c 4:"fastboot" ${TEMP_FILE} + #[5: nvme: 12M-14M] + sgdisk -n 5:0:+2M -t 5:0700 -u 5:00354BCD-BBCB-4CB3-B5AE-CDEFCB5DAC43 -c 5:"nvme" ${TEMP_FILE} + #[6: boot: 14M-78M] + sgdisk -n 6:0:+64M -t 6:EF00 -u 6:5C0F213C-17E1-4149-88C8-8B50FB4EC70E -c 6:"boot" ${TEMP_FILE} + #[7: reserved: 78M-334M] + sgdisk -n 7:0:+256M -t 7:0700 -u 7:BED8EBDC-298E-4A7A-B1F1-2500D98453B7 -c 7:"reserved" ${TEMP_FILE} + #[8: cache: 334M-590M] + sgdisk -n 8:0:+256M -t 8:8301 -u 8:A092C620-D178-4CA7-B540-C4E26BD6D2E2 -c 8:"cache" ${TEMP_FILE} + #[9: system: 590M-2126M] + sgdisk -n 9:0:+1536M -t 9:8300 -u 9:FC56E345-2E8E-49AE-B2F8-5B9D263FE377 -c 9:"system" ${TEMP_FILE} + #[10: userdata: 2126M-End] + sgdisk -n -E -t 10:8300 -u 10:064111F6-463B-4CE1-876B-13F3684CE164 -c 10:"userdata" -p ${TEMP_FILE} + ;; + linux*) + dd if=/dev/zero of=${TEMP_FILE} bs=${SECTOR_SIZE} count=${SECTOR_NUMBER} + sgdisk -U 2CB85345-6A91-4043-8203-723F0D28FBE8 -v ${TEMP_FILE} + #[1: vrl: 1M-2M] + sgdisk -n 1:0:+1M -t 1:0700 -u 1:496847AB-56A1-4CD5-A1AD-47F4ACF055C9 -c 1:"vrl" ${TEMP_FILE} + #[2: vrl_backup: 2M-3M] + sgdisk -n 2:0:+1M -t 2:0700 -u 2:61A36FC1-8EFB-4899-84D8-B61642EFA723 -c 2:"vrl_backup" ${TEMP_FILE} + #[3: mcuimage: 3M-4M] + sgdisk -n 3:0:+1M -t 3:0700 -u 3:65007411-962D-4781-9B2C-51DD7DF22CC3 -c 3:"mcuimage" ${TEMP_FILE} + #[4: fastboot: 4M-12M] + sgdisk -n 4:0:+8M -t 4:EF02 -u 4:496847AB-56A1-4CD5-A1AD-47F4ACF055C9 -c 4:"fastboot" ${TEMP_FILE} + #[5: nvme: 12M-14M] + sgdisk -n 5:0:+2M -t 5:0700 -u 5:00354BCD-BBCB-4CB3-B5AE-CDEFCB5DAC43 -c 5:"nvme" ${TEMP_FILE} + #[6: boot: 14M-78M] + sgdisk -n 6:0:+64M -t 6:EF00 -u 6:5C0F213C-17E1-4149-88C8-8B50FB4EC70E -c 6:"boot" ${TEMP_FILE} + #[7: reserved: 78M-334M] + sgdisk -n 7:0:+256M -t 7:0700 -u 7:BED8EBDC-298E-4A7A-B1F1-2500D98453B7 -c 7:"reserved" ${TEMP_FILE} + #[8: cache: 334M-590M] + sgdisk -n 8:0:+256M -t 8:8301 -u 8:A092C620-D178-4CA7-B540-C4E26BD6D2E2 -c 8:"cache" ${TEMP_FILE} + #[9: system: 590M-End] + sgdisk -n -E -t 9:8300 -u 9:FC56E345-2E8E-49AE-B2F8-5B9D263FE377 -c 9:"system" ${TEMP_FILE} + ;; +esac + +# get the main and the backup parts of the partition table +dd if=${TEMP_FILE} of=prm_ptable.img bs=${SECTOR_SIZE} count=34 +dd if=${TEMP_FILE} of=sec_ptable.img skip=${BK_PTABLE_LBA} bs=${SECTOR_SIZE} count=33 + +rm -f ${TEMP_FILE} diff --git a/l-loader/l-loader.lds b/l-loader/l-loader.lds new file mode 100644 index 00000000..41eb16f5 --- /dev/null +++ b/l-loader/l-loader.lds @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014 Linaro Ltd. + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0xf9800800; + LLOADER_START = .; + + .text : + { + *(.text) + *(.rodata) + } + + .data ALIGN(4): + { + *(.data) + } + + . = ALIGN(4); + + .bss ALIGN(4): + { + *(.bss) + } + + LLOADER_BL1_BIN = 0xf9801000; +} diff --git a/l-loader/start.S b/l-loader/start.S new file mode 100644 index 00000000..a0d838a3 --- /dev/null +++ b/l-loader/start.S @@ -0,0 +1,100 @@ + .text + +/* + * The head of l-loader is defined in below. + * struct l_loader_head { + * unsigned int first_instr; + * unsigned char magic[16]; @ BOOTMAGICNUMBER! + * unsigned int l_loader_start; + * unsigned int l_loader_end; + * }; + */ + +#define CPU0_CTRL_OFFSET 0x100 +#define CPU7_CTRL_OFFSET 0x800 +#define CPU0_RVBARADDR_OFFSET 0x158 +#define CPU7_RVBARADDR_OFFSET 0x858 + +#define CPU_CTRL_AARCH64_MODE (1 << 7) + +#define SC_PERIPH_CLKEN3 0x230 +#define SC_PERIPH_RSTDIS3 0x334 + .global _start +_start: + b reset +@ Android magic number: "BOOTMAGICNUMBER!" +android_magic: + .word 0x544f4f42 + .word 0x4947414d + .word 0x4d554e43 + .word 0x21524542 + .word LLOADER_START @ LLOADER_START in RAM + .word 0 @ LLOADER_END in RAM + +entries: + @ 5 entries with 7 words + .space 140 + + .align 7 + +reset: + ldr r8, =(0xf9800000 + 0x700) + str r0, [r8] @ download mode (1:usb,2:uart,0:boot) + + ldr r4, =0xf6504000 @ ACPU_CTRL register base + @ set RVBAR for cpu0 + ldr r5, =CPU0_RVBARADDR_OFFSET + ldr r6, =LLOADER_BL1_BIN + mov r6, r6, lsr #2 + str r6, [r4, r5] +1: + ldr r0, [r4, r5] + cmp r0, r6 + bne 1b + + mov r5, #CPU0_CTRL_OFFSET + mov r6, #CPU7_CTRL_OFFSET +2: + ldr r0, [r4, r5] @ Load ACPU_SC_CPUx_CTRL + orr r0, r0, #CPU_CTRL_AARCH64_MODE + str r0, [r4, r5] @ Save to ACPU_SC_CPUx_CTRL + ldr r0, [r4, r5] + + add r5, r5, #0x100 @ Iterate ACPU_SC_CPUx_CTRL + cmp r5, r6 + ble 2b + + /* + * Prepare UART2 & UART3 without baud rate initialization. + * So always output on UART0 in l-loader. + */ + ldr r4, =0xf70100e0 @ UART2_RXD IOMG register + mov r0, #0 + str r0, [r4] + str r0, [r4, #4] @ UART2_TXD IOMG register + ldr r0, [r4] + + ldr r4, =0xf7010188 @ UART3_RXD IOMG register + mov r0, #1 + str r0, [r4] + str r0, [r4, #4] @ UART3_TXD IOMG register + ldr r1, [r4] + + ldr r4, =0xf7030000 @ PERI_CTRL register base + @ By default, CLK_TXCO is the parent of CLK_UART3 in SC_CLK_SEL0 + + ldr r5, =SC_PERIPH_RSTDIS3 @ unreset + ldr r6, =SC_PERIPH_CLKEN3 @ enable PCLK + mov r0, #(3 << 6) @ bit'6' & bit'7' (UART2 & UART3) + str r0, [r4, r5] + str r0, [r4, r6] + + @ execute warm reset to switch aarch64 + mov r2, #3 + mcr p15, 0, r2, c12, c0, 2 + wfi +panic: + b panic + +str_aarch64: + .asciz "\nSwitch to aarch64 mode. CPU0 executes at 0x" diff --git a/uefi-tools/atf-build.sh b/uefi-tools/atf-build.sh new file mode 100755 index 00000000..0c4c09c6 --- /dev/null +++ b/uefi-tools/atf-build.sh @@ -0,0 +1,222 @@ +#!/bin/bash +# +# Builds ARM Trusted Firmware, and generates FIPs with UEFI and optionally +# Trusted OS for the supported platforms. +# Not intended to be called directly, invoked from uefi-build.sh. +# +# Board configuration is extracted from +# parse-platforms.py and platforms.config. +# + +TOOLS_DIR="`dirname $0`" +. "$TOOLS_DIR"/common-functions +OUTPUT_DIR="$PWD"/uefi-build + +ATF_BUILDVER=1 + +function usage +{ + echo "usage:" + echo "atf-build.sh -e <EDK2 source directory> -t <UEFI build profile/toolchain> <platform>" + echo +} + +function check_atf_buildver +{ + MAJOR=`grep "^VERSION_MAJOR" Makefile | sed 's/.*:= *\([0-9]*\).*/\1/'` + [ $? -ne 0 ] && return 1 + MINOR=`grep "^VERSION_MINOR" Makefile | sed 's/.*:= *\([0-9]*\).*/\1/'` + [ $? -ne 0 ] && return 1 + + if [ "$MAJOR" -eq 1 -a "$MINOR" -ge 2 ]; then + ATF_BUILDVER=2 + fi +} + +function build_platform +{ + if [ X"$EDK2_DIR" = X"" ];then + echo "EDK2_DIR not set!" >&2 + return 1 + fi + + check_atf_buildver || return 1 + + BUILD_ATF="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o build_atf`" + if [ X"$BUILD_ATF" = X"" ]; then + echo "Platform '$1' is not configured to build ARM Trusted Firmware." + return 0 + fi + + ATF_PLATFORM="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o atf_platform`" + if [ X"$ATF_PLATFORM" = X"" ]; then + ATF_PLATFORM=$1 + fi + + # + # Read platform configuration + # + PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o longname`" + PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o arch`" + PLATFORM_IMAGE_DIR="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o uefi_image_dir`" + PLATFORM_BUILDFLAGS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o atf_buildflags`" + + if [ $VERBOSE -eq 1 ]; then + echo "PLATFORM_NAME=$PLATFORM_NAME" + echo "PLATFORM_ARCH=$PLATFORM_ARCH" + echo "PLATFORM_IMAGE_DIR=$PLATFORM_IMAGE_DIR" + echo "PLATFORM_BUILDFLAGS=$PLATFORM_BUILDFLAGS" + fi + + unset BL30 BL31 BL32 BL33 + BL30="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o scp_bin`" + if [ $ATF_BUILDVER -gt 1 ]; then + unset SCP_BL2 + SCP_BL2="$EDK2_DIR/$BL30" + fi + BL31="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o el3_bin`" + BL33="$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o uefi_bin`" + + # + # Set up cross compilation variables (if applicable) + # + set_cross_compile + CROSS_COMPILE="$TEMP_CROSS_COMPILE" + echo "Building ARM Trusted Firmware for $PLATFORM_NAME - $BUILD_PROFILE" + echo "CROSS_COMPILE=\"$TEMP_CROSS_COMPILE\"" + + if [ X"$BL30" != X"" ]; then + BL30="${EDK2_DIR}"/"${BL30}" + fi + if [ X"$BL31" != X"" ]; then + BL31="${EDK2_DIR}"/"${BL31}" + fi + + # + # BL32 requires more attention + # If TOS_DIR is not set, we assume user does not want a Trusted OS, + # even if the source directory and/or binary for it exists + # + if [ X"$TOS_DIR" != X"" ]; then + SPD="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o atf_spd`" + + TOS_BIN="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o tos_bin`" + if [ X"$TOS_BIN" != X"" ]; then + BL32=$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/$TOS_BIN + fi + + if [ X"$SPD" != X"" ] && [ X"$BL32" != X"" ]; then + # + # Since SPD cannot be exported or undefined, + # we parametrise it here + # + SPD_OPTION="SPD=$SPD" + else + echo "WARNING: Proceeding without Trusted OS!" + echo " Please specify both ATF_SPD and TOS_BIN" + echo " if you wish to use a Trusted OS!" + fi + fi + + # + # Debug extraction handling + # + case "$BUILD_ATF" in + debug*) + DEBUG=1 + BUILD_TYPE="debug" + ;; + *) + DEBUG=0 + BUILD_TYPE="release" + ;; + esac + + export BL30 BL31 BL32 BL33 + + echo "BL30=$BL30" + if [ $ATF_BUILDVER -gt 1 ]; then + export SCP_BL2 + echo "SCP_BL2=$BL30" + fi + echo "BL31=$BL31" + echo "BL32=$BL32" + echo "BL33=$BL33" + echo "$SPD_OPTION" + echo "BUILD_TYPE=$BUILD_TYPE" + + # + # If a build was done with BL32, and followed by another without, + # the BL32 component remains in fip.bin, so we delete the build dir + # contents before calling make + # + rm -rf build/"$ATF_PLATFORM/$BUILD_TYPE"/* + + # + # Build ARM Trusted Firmware and create FIP + # + if [ $VERBOSE -eq 1 ]; then + echo "Calling ARM Trusted Firmware build:" + echo "CROSS_COMPILE="$CROSS_COMPILE" make -j$NUM_THREADS PLAT="$ATF_PLATFORM" $SPD_OPTION DEBUG=$DEBUG ${PLATFORM_BUILDFLAGS} all fip" + fi + CROSS_COMPILE="$CROSS_COMPILE" make -j$NUM_THREADS PLAT="$ATF_PLATFORM" $SPD_OPTION DEBUG=$DEBUG ${PLATFORM_BUILDFLAGS} all fip + if [ $? -eq 0 ]; then + # + # Copy resulting images to UEFI image dir + # + if [ $VERBOSE -eq 1 ]; then + echo "Copying bl1.bin and fip.bin to "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/"" + fi + cp -a build/"$ATF_PLATFORM/$BUILD_TYPE"/{bl1,fip}.bin "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/" + else + return 1 + fi +} + +# Check to see if we are in a trusted firmware directory +# refuse to continue if we aren't +if [ ! -d bl32 ] +then + echo "ERROR: we aren't in the arm-trusted-firmware directory." + usage + exit 1 +fi + +build= + +if [ $# = 0 ] +then + usage + exit 1 +else + while [ "$1" != "" ]; do + case $1 in + "-e" ) + shift + EDK2_DIR="$1" + ;; + "/h" | "/?" | "-?" | "-h" | "--help" ) + usage + exit + ;; + "-t" ) + shift + BUILD_PROFILE="$1" + ;; + * ) + build="$1" + ;; + esac + shift + done +fi + +if [ X"$build" = X"" ]; then + echo "No platform specified!" >&2 + echo + usage + exit 1 +fi + +build_platform $build +exit $? diff --git a/uefi-tools/common-functions b/uefi-tools/common-functions new file mode 100644 index 00000000..08f4fbf5 --- /dev/null +++ b/uefi-tools/common-functions @@ -0,0 +1,86 @@ +#!/bin/bash + +RESULT_BUF=`echo -e ------------------------------------------------------------` +RESULT_PASS_COUNT=0 +RESULT_FAIL_COUNT=0 + +TOOLS_DIR="`dirname $0`" + +function result_log +{ + if [ $1 -eq 0 ]; then + RESULT_BUF="`printf \"%s\n%55s\tpass\" \"$RESULT_BUF\" \"$2\"`" + RESULT_PASS_COUNT=$(($RESULT_PASS_COUNT + 1)) + else + RESULT_BUF="`printf \"%s\n%55s\tfail\" \"$RESULT_BUF\" \"$2\"`" + RESULT_FAIL_COUNT=$(($RESULT_FAIL_COUNT + 1)) + fi +} + +function result_print +{ + printf "%s" "$RESULT_BUF" + echo -e "\n------------------------------------------------------------" + printf "pass\t$RESULT_PASS_COUNT\n" + printf "fail\t$RESULT_FAIL_COUNT\n" + + exit $RESULT_FAIL_COUNT +} + +function get_build_arch +{ + case `uname -m` in + arm*) + BUILD_ARCH=ARM;; + aarch64*) + BUILD_ARCH=AARCH64;; + *) + BUILD_ARCH=other;; + esac +} + +function set_cross_compile +{ + get_build_arch + + echo "Target: $PLATFORM_ARCH" + echo "Build: $BUILD_ARCH" + if [ "$PLATFORM_ARCH" = "$BUILD_ARCH" ]; then + TEMP_CROSS_COMPILE= + elif [ "$PLATFORM_ARCH" == "AARCH64" ]; then + if [ X"$CROSS_COMPILE_64" != X"" ]; then + TEMP_CROSS_COMPILE="$CROSS_COMPILE_64" + else + TEMP_CROSS_COMPILE=aarch64-linux-gnu- + fi + elif [ "$PLATFORM_ARCH" == "ARM" ]; then + if [ X"$CROSS_COMPILE_32" != X"" ]; then + TEMP_CROSS_COMPILE="$CROSS_COMPILE_32" + else + TEMP_CROSS_COMPILE=arm-linux-gnueabihf- + fi + else + echo "Unsupported target architecture '$PLATFORM_ARCH'!" >&2 + fi +} + +function get_gcc_version +{ + gcc_version=$($1 -dumpversion) + case $gcc_version in + 4.6*|4.7*|4.8*|4.9*) + echo GCC$(echo ${gcc_version} | awk -F. '{print $1$2}') + ;; + *) + echo "Unknown toolchain version '$gcc_version'" >&2 + echo "Attempting to build using GCC49 profile." >&2 + echo GCC49 + ;; + esac +} + +function get_clang_version +{ + clang_version=`$1 --version | head -1 | sed 's/^.*version\s*\([0-9]*\).\([0-9]*\).*/\1\2/g'` + echo "CLANG$clang_version" +} diff --git a/uefi-tools/opteed-build.sh b/uefi-tools/opteed-build.sh new file mode 100755 index 00000000..3c759eb3 --- /dev/null +++ b/uefi-tools/opteed-build.sh @@ -0,0 +1,158 @@ +#!/bin/bash +# +# Builds OP-TEE Trusted OS. +# Not intended to be called directly, invoked from tos-build.sh. +# +# Board configuration is extracted from +# parse-platforms.py and platforms.config. +# + +TOOLS_DIR="`dirname $0`" +. "$TOOLS_DIR"/common-functions + +export CFG_TEE_CORE_LOG_LEVEL=2 # 0=none 1=err 2=info 3=debug 4=flow + +function usage +{ + echo "usage:" + echo "opteed-build.sh -e <EDK2 source directory> -t <UEFI build profile/toolchain> <platform>" + echo +} + +function build_platform +{ + unset CFG_ARM64_core PLATFORM PLATFORM_FLAVOR DEBUG + TOS_PLATFORM="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o tos_platform`" + if [ X"$TOS_PLATFORM" = X"" ]; then + TOS_PLATFORM="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o atf_platform`" + if [ X"$TOS_PLATFORM" = X"" ]; then + TOS_PLATFORM=$1 + fi + fi + TOS_PLATFORM_FLAVOR="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o tos_platform_flavor`" + + # + # Read platform configuration + # + PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o arch`" + PLATFORM_IMAGE_DIR="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o uefi_image_dir`" + PLATFORM_BUILDFLAGS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o tos_buildflags`" + + if [ $VERBOSE -eq 1 ]; then + echo "PLATFORM_ARCH=$PLATFORM_ARCH" + echo "PLATFORM_IMAGE_DIR=$PLATFORM_IMAGE_DIR" + echo "PLATFORM_BUILDFLAGS=$PLATFORM_BUILDFLAGS" + fi + + # + # Set up cross compilation variables (if applicable) + # + # OP-TEE requires both 64- and 32-bit compilers for a 64-bit build + # For details, visit + # https://github.com/OP-TEE/optee_os/blob/master/documentation/build_system.md#cross_compile-cross-compiler-selection + # + set_cross_compile + if [ "$PLATFORM_ARCH" = "AARCH64" ]; then + export CFG_ARM64_core=y + export CROSS_COMPILE_core="$TEMP_CROSS_COMPILE" + export CROSS_COMPILE_ta_arm64="$TEMP_CROSS_COMPILE" + PLATFORM_ARCH="ARM" + set_cross_compile + PLATFORM_ARCH="AARCH64" + echo "CFG_ARM64_core=$CFG_ARM64_core" + echo "CROSS_COMPILE_ta_arm64=$CROSS_COMPILE_ta_arm64" + else + export CFG_ARM64_core=n + fi + export CROSS_COMPILE="$TEMP_CROSS_COMPILE" + echo "CROSS_COMPILE=$CROSS_COMPILE" + echo "CROSS_COMPILE_core=$CROSS_COMPILE_core" + + # + # Set up build variables + # + BUILD_TOS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o build_tos`" + case "$BUILD_TOS" in + debug*) + export DEBUG=1 + echo "PROFILE=DEBUG" + ;; + *) + export DEBUG=0 + echo "PROFILE=RELEASE" + ;; + esac + + export PLATFORM=$TOS_PLATFORM + export PLATFORM_FLAVOR=$TOS_PLATFORM_FLAVOR + echo "PLATFORM=$PLATFORM" + echo "PLATFORM_FLAVOR=$PLATFORM_FLAVOR" + echo "CFG_TEE_CORE_LOG_LEVEL=$CFG_TEE_CORE_LOG_LEVEL" + + # + # Build OP-TEE + # + if [ $VERBOSE -eq 1 ]; then + echo "Calling OP-TEE build:" + fi + make -j$NUM_THREADS ${PLATFORM_BUILDFLAGS} + if [ $? -eq 0 ]; then + # + # Copy resulting images to UEFI image dir + # + if [ $VERBOSE -eq 1 ]; then + echo "Copying tee.bin to "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/"" + fi + cp -a out/arm-plat-"$TOS_PLATFORM"/core/tee.bin "$EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/" + else + return 1 + fi +} + +# Check to see if we are in a trusted OS directory +# refuse to continue if we aren't +if [ ! -f documentation/optee_design.md ] +then + echo "ERROR: we aren't in the optee_os directory." + usage + exit 1 +fi + +build= + +if [ $# = 0 ] +then + usage + exit 1 +else + while [ "$1" != "" ]; do + case $1 in + "-e" ) + shift + EDK2_DIR="$1" + ;; + "/h" | "/?" | "-?" | "-h" | "--help" ) + usage + exit + ;; + "-t" ) + shift + BUILD_PROFILE="$1" + ;; + * ) + build="$1" + ;; + esac + shift + done +fi + +if [ X"$build" = X"" ]; then + echo "No platform specified!" >&2 + echo + usage + exit 1 +fi + +build_platform $build +exit $? diff --git a/uefi-tools/parse-platforms.py b/uefi-tools/parse-platforms.py new file mode 100755 index 00000000..af440387 --- /dev/null +++ b/uefi-tools/parse-platforms.py @@ -0,0 +1,81 @@ +#!/usr/bin/python + +import sys, os, argparse, ConfigParser + +default_filename='platforms.config' + +def list_platforms(): + for p in platforms: print p + +def shortlist_platforms(): + for p in platforms: print p, + +def get_images(): + if args.platform: + try: + value = config.get(args.platform, "EXTRA_FILES") + print value, + except: + pass + try: + value = config.get(args.platform, "BUILD_ATF") + if value == "yes": + print "bl1.bin fip.bin" + return True + except: + try: + value = config.get(args.platform, "UEFI_BIN") + print value + return True + except: + print "No images found!" + else: + print "No platform specified!" + + return False + +def get_option(): + if args.platform: + if args.option: + try: + value = config.get(args.platform, args.option) + if value: + print value + return True + except: + return True # Option not found, return True, and no output + else: + print "No option specified!" + else: + print "No platform specified!" + return False + +parser = argparse.ArgumentParser(description='Parses platform configuration for Linaro UEFI build scripts.') +parser.add_argument('-c', '--config-file', help='Specify a non-default platform config file.', required=False) +parser.add_argument('-p', '--platform', help='Read configuration for PLATFORM only.', required=False) +parser.add_argument('command', action="store", help='Action to perform') +parser.add_argument('-o', '--option', help='Option to retreive') + +args = parser.parse_args() +if args.config_file: + config_filename = args.config_file +else: + config_filename = os.path.dirname(os.path.realpath(sys.argv[0])) + '/' + default_filename + +config = ConfigParser.ConfigParser() +config.read(config_filename) + +platforms = config.sections() + +commands = {"shortlist": shortlist_platforms, + "list": list_platforms, + "images": get_images, + "get": get_option} + +try: + retval = commands[args.command]() +except: + print ("Unrecognized command '%s'" % args.command) + +if retval != True: + sys.exit(1) diff --git a/uefi-tools/platforms.config b/uefi-tools/platforms.config new file mode 100644 index 00000000..adaf6c03 --- /dev/null +++ b/uefi-tools/platforms.config @@ -0,0 +1,245 @@ +# Platform build configurations for Linaro EDK2 builds +# ==================================================== +# The configuration file format is extremely simplistic: +# - Each platform has a short name. +# - A platform entry starts by the short name held in square brackets, '[]' +# - Within each entry, all options are described in a NAME=VALUE scheme, +# with the name being whatever comes before the first '=' on the line, +# and the value being everything that comes after it. +# +# Mandatory options: +# - LONGNAME A more descriptive name of the platform. +# - DSC Pointer to the EDK2 build description file. (The +# pandaboard is excused, all other ports must have this.) +# - ARCH String describing the architecture to build for. +# Currently supported are AARCH32 and AARCH64. +# - UEFI_BIN Name of executable image produced. +# - UEFI_IMAGE_DIR Build output directory name, relative to 'Build'. +# +# Options for Trusted OS +# Note that OP-TEE (https://github.com/OP-TEE/optee_os) is the only currently +# supported Trusted OS +# - BUILD_TOS Set to "yes" if the build should automatically build +# Trusted OS, mainly for ARM Trusted Firmware. +# If this is set, you must also set ATF_SPD! +# Else we will not know which specific Trusted OS to +# build. +# Set to "debug" to create a debug build. +# - TOS_PLATFORM Platform name for Trusted OS build, if +# different from ARM Trusted Firmware platform +# or UEFI platform name. +# - TOS_PLATFORM_FLAVOR If a core platform has multiple flavors, specify which +# flavor here. +# +# Options for ARM Trusted Firmware platforms +# - BUILD_ATF Set to "yes" if the build should automatically build +# ARM Trusted Firmware and a fip containing UEFI image. +# Set to "debug" to create a debug build. +# - ATF_PLATFORM Platform name for ARM Trusted Firmware build, if +# different from UEFI platform name. +# - SCP_BIN SCP image to pass to ARM Trusted Firmware. +# - TOS_BIN Trusted OS image to pass to ARM Trusted Firmware. +# The path is relative to +# $EDK2_DIR/Build/$PLATFORM_IMAGE_DIR/$BUILD_PROFILE/FV/. +# To actually build the Trusted OS, you must also set +# ATF_SPD. +# - ATF_SPD Name of Secure Payload Dispatcher +# To actually build the Trusted OS, you must also set +# TOS_BIN. +# +# Optional options: +# - BUILDFLAGS Any special flags you want to pass to the build command. +# - ATF_BUILDFLAGS Any special flags you want to pass to the ARM Trusted +# Firmware build command. +# - TOS_BUILDFLAGS Any special flags you want to pass to the Trusted OS +# build command. +# - EXTRA_FILES Any additional files to be copied to output dir. +# - PREBUILD_CMDS Any commands you want to execute before the build step. +# - POSTBUILD_CMDS Any commands you want to execute after the build step. +# - PACKAGES_PATH Additional directories to search for packages under. +# +# Special options: +# - BUILDCMD Command to call instead of the normal build command. +# Only for pandaboard, not to be used for new ports. +# + +[juno] +LONGNAME=aarch64 Juno +DSC=OpenPlatformPkg/Platforms/ARM/Juno/ArmJuno.dsc +BUILDFLAGS= +ARCH=AARCH64 +BUILD_ATF=yes +UEFI_BIN=BL33_AP_UEFI.fd +UEFI_IMAGE_DIR=ArmJuno +SCP_BIN=OpenPlatformPkg/Platforms/ARM/Juno/Binary/bl30.bin +EXTRA_FILES=../../../../OpenPlatformPkg/Platforms/ARM/Juno/Binary/bl0.bin ../../../../OpenPlatformPkg/Platforms/ARM/Juno/Binary/Copying.txt + +# ARM FVP BASE AEMv8-A model +[fvp_full] +LONGNAME=aarch64 FVP RTSM with full perhiperhal set +DSC=OpenPlatformPkg/Platforms/ARM/VExpress/ArmVExpress-FVP-AArch64.dsc +BUILDFLAGS=-D EDK2_OUT_DIR=Build/ArmVExpress-FVP-AArch64-Full -D EDK2_ENABLE_SMSC_91X=1 -D EDK2_ENABLE_PL111=1 +ARCH=AARCH64 +UEFI_BIN=FVP_AARCH64_EFI.fd +UEFI_IMAGE_DIR=ArmVExpress-FVP-AArch64-Full + +[fvp] +LONGNAME=aarch64 FVP RTSM +DSC=OpenPlatformPkg/Platforms/ARM/VExpress/ArmVExpress-FVP-AArch64.dsc +BUILDFLAGS=-D EDK2_ENABLE_SMSC_91X=1 +ARCH=AARCH64 +BUILD_ATF=yes +UEFI_BIN=FVP_AARCH64_EFI.fd +UEFI_IMAGE_DIR=ArmVExpress-FVP-AArch64 + +[tc2] +LONGNAME=Versatile Express TC2 +BUILDFLAGS=-D ARM_BIGLITTLE_TC2=1 +DSC=OpenPlatformPkg/Platforms/ARM/VExpress/ArmVExpress-CTA15-A7.dsc +ARCH=ARM +UEFI_BIN=ARM_VEXPRESS_CTA15A7_EFI.fd +UEFI_IMAGE_DIR=ArmVExpress-CTA15-A7 + +[panda] +LONGNAME=TI Pandaboard +BUILDCMD=./PandaBoardPkg/build.sh +BUILDFLAGS= +ARCH=ARM +UEFI_BIN=MLO +UEFI_IMAGE_DIR=PandaBoard + +[beagle] +LONGNAME=BeagleBoard +BUILDFLAGS= +DSC=BeagleBoardPkg/BeagleBoardPkg.dsc +ARCH=ARM + +[d01] +LONGNAME=HiSilicon D01 Cortex-A15 16-cores +BUILDFLAGS=-D EDK2_ARMVE_STANDALONE=1 +DSC=HisiPkg/D01BoardPkg/D01BoardPkg.dsc +ARCH=ARM +UEFI_BIN=D01.fd +UEFI_IMAGE_DIR=D01 + +[d01-intelbds] +LONGNAME=HiSilicon D01 Cortex-A15 16-cores Intel Bds +BUILDFLAGS=-D EDK2_ARMVE_STANDALONE=1 -D INTEL_BDS -D NO_LINUX_LOADER -D EDK2_OUT_DIR=Build/D01-IntelBds +DSC=HisiPkg/D01BoardPkg/D01BoardPkg.dsc +ARCH=ARM +UEFI_BIN=D01.fd +UEFI_IMAGE_DIR=D01 + +[bbb] +LONGNAME=Texas Instruments BeagleBone Black +BUILDFLAGS= +DSC=TexasInstrumentsPkg/BeagleBoneBlackPkg/BeagleBoneBlackPkg.dsc +ARCH=ARM +UEFI_BIN=BEAGLEBONEBLACK_EFI.fd +UEFI_IMAGE_DIR=BeagleBoneBlack + +[qemu] +LONGNAME=QEMU ARM Emulator +BUILDFLAGS=-D INTEL_BDS +DSC=ArmVirtPkg/ArmVirtQemu.dsc +ARCH=ARM +UEFI_BIN=QEMU_EFI.fd +UEFI_IMAGE_DIR=ArmVirtQemu-ARM + +[qemu64] +LONGNAME=QEMU AArch64 Emulator +BUILDFLAGS=-D INTEL_BDS +DSC=ArmVirtPkg/ArmVirtQemu.dsc +ARCH=AARCH64 +UEFI_BIN=QEMU_EFI.fd +UEFI_IMAGE_DIR=ArmVirtQemu-AARCH64 + +[mustang] +LONGNAME=APM XGene Mustang +BUILDFLAGS= +DSC=ArmPlatformPkg/APMXGenePkg/APMXGene-Mustang.dsc +ARCH=AARCH64 +UEFI_BIN=APMXGENE-MUSTANG.fd SEC_APMXGENE-MUSTANG.fd +UEFI_IMAGE_DIR=APMXGene-Mustang + +[overdrive] +LONGNAME=AMD Overdrive +BUILDFLAGS=-D INTEL_BDS +DSC=OpenPlatformPkg/Platforms/AMD/Styx/OverdriveBoard/OverdriveBoard.dsc +ARCH=AARCH64 +PACKAGES_PATH=OpenPlatformPkg/Platforms/AMD/Styx/Binary +UEFI_BIN=STYX_ROM.fd +UEFI_IMAGE_DIR=Overdrive + +[cello] +LONGNAME=LeMaker Cello +BUILDFLAGS=-D INTEL_BDS +DSC=OpenPlatformPkg/Platforms/AMD/Styx/CelloBoard/CelloBoard.dsc +ARCH=AARCH64 +PACKAGES_PATH=OpenPlatformPkg/Platforms/AMD/Styx/Binary +UEFI_BIN=STYX_ROM.fd +UEFI_IMAGE_DIR=Cello + +[hikey] +LONGNAME=CircuitCo HiKey +DSC=OpenPlatformPkg/Platforms/Hisilicon/HiKey/HiKey.dsc +ARCH=AARCH64 +UEFI_BIN=BL33_AP_UEFI.fd +UEFI_IMAGE_DIR=HiKey +BUILD_ATF=yes +ATF_SPD=opteed +TOS_BIN=tee.bin +BUILD_TOS=yes +SCP_BIN=OpenPlatformPkg/Platforms/Hisilicon/HiKey/Binary/mcuimage.bin +# Uncomment this to use UART0 as the EDK2 console +#BUILDFLAGS=-DSERIAL_BASE=0xF8015000 +# Uncomment this to use UART0 as the ARM Trusted Firmware console +#ATF_BUILDFLAGS=CONSOLE_BASE=PL011_UART0_BASE CRASH_CONSOLE_BASE=PL011_UART0_BASE +# Uncomment this to use UART0 as the OP-TEE Trusted OS console +#TOS_BUILDFLAGS=CFG_CONSOLE_UART=0 + +[xen64] +LONGNAME=AArch64 Xen guest +BUILDFLAGS= +DSC=ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationXen.dsc +ARCH=AARCH64 +UEFI_BIN=XEN_EFI.fd +UEFI_IMAGE_DIR=ArmVirtualizationXen-AARCH64 + +[aarch64-shell] +LONGNAME=AArch64 EFI Shell +BUILDFLAGS=-D INCLUDE_TFTP_COMMAND +DSC=ShellPkg/ShellPkg.dsc +ARCH=AARCH64 + +[aarch64-shell-minimal] +LONGNAME=AArch64 EFI Shell (Minimal) +BUILDFLAGS=-D NO_SHELL_PROFILES +DSC=ShellPkg/ShellPkg.dsc +ARCH=AARCH64 + +[arm-shell] +LONGNAME=ARM EFI Shell +BUILDFLAGS=-D INCLUDE_TFTP_COMMAND +DSC=ShellPkg/ShellPkg.dsc +ARCH=ARM + +[arm-shell-minimal] +LONGNAME=ARM EFI Shell (Minimal) +BUILDFLAGS=-D NO_SHELL_PROFILES +DSC=ShellPkg/ShellPkg.dsc +ARCH=ARM + +[d02] +LONGNAME=Hisilicon D02 +DSC=OpenPlatformPkg/Platforms/Hisilicon/D02/Pv660D02.dsc +ARCH=AARCH64 +UEFI_BIN=PV660D02.fd +UEFI_IMAGE_DIR=Pv660D02 + +[d03] +LONGNAME=Hisilicon D03 +DSC=OpenPlatformPkg/Platforms/Hisilicon/D03/D03.dsc +ARCH=AARCH64 +UEFI_BIN=D03.fd +UEFI_IMAGE_DIR=D03 diff --git a/uefi-tools/tos-build.sh b/uefi-tools/tos-build.sh new file mode 100755 index 00000000..9dc4b2dc --- /dev/null +++ b/uefi-tools/tos-build.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# +# Builds Trusted OS, mainly for ARM Trusted Firmware. +# Calls $ATF_SPD-build.sh for the actual build of a specific Trusted OS. +# Not intended to be called directly, invoked from uefi-build.sh. +# +# Board configuration is extracted from +# parse-platforms.py and platforms.config. +# + +TOOLS_DIR="`dirname $0`" +. "$TOOLS_DIR"/common-functions + +function usage +{ + echo "usage:" + echo "tos-build.sh -e <EDK2 source directory> -t <UEFI build profile/toolchain> <platform>" + echo +} + +function build_platform +{ + if [ X"$EDK2_DIR" = X"" ];then + echo "EDK2_DIR not set!" >&2 + return 1 + fi + + if [ X"`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o build_tos`" = X"" ]; then + echo "Platform '$1' is not configured to build Trusted OS." + return 0 + fi + + # + # Build Trusted OS + # + ATF_SPD="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $1 get -o atf_spd`" + if [ -f $TOOLS_DIR/$ATF_SPD-build.sh ]; then + echo "Building $ATF_SPD Trusted OS" + if [ $VERBOSE -eq 1 ]; then + echo "$TOOLS_DIR/$ATF_SPD-build.sh -e "$EDK2_DIR" -t "$BUILD_PROFILE" $build" + fi + $TOOLS_DIR/$ATF_SPD-build.sh -e "$EDK2_DIR" -t "$BUILD_PROFILE" $build + return $? + else + echo "ERROR: missing Trusted OS build script." + echo " Or build script not named $ATF_SPD-build.sh" + return 1 + fi +} + +build= + +if [ $# = 0 ] +then + usage + exit 1 +else + while [ "$1" != "" ]; do + case $1 in + "-e" ) + shift + EDK2_DIR="$1" + ;; + "/h" | "/?" | "-?" | "-h" | "--help" ) + usage + exit + ;; + "-t" ) + shift + BUILD_PROFILE="$1" + ;; + * ) + build="$1" + ;; + esac + shift + done +fi + +if [ X"$build" = X"" ]; then + echo "No platform specified!" >&2 + echo + usage + exit 1 +fi + +build_platform $build +exit $? diff --git a/uefi-tools/uefi-build.sh b/uefi-tools/uefi-build.sh new file mode 100755 index 00000000..0fa50edf --- /dev/null +++ b/uefi-tools/uefi-build.sh @@ -0,0 +1,331 @@ +#!/bin/bash + +# +# Board Configuration Section +# =========================== +# +# Board configuration moved to parse-platforms.py and platforms.config. +# +# No need to edit below unless you are changing script functionality. +# + +unset WORKSPACE EDK_TOOLS_DIR MAKEFLAGS + +TOOLS_DIR="`dirname $0`" +. "$TOOLS_DIR"/common-functions +PLATFORM_CONFIG="" +VERBOSE=0 +ATF_DIR= +TOS_DIR= +TOOLCHAIN= +OPENSSL_CONFIGURED=FALSE + +# Number of threads to use for build +export NUM_THREADS=$((`getconf _NPROCESSORS_ONLN` + 1)) + +function build_platform +{ + PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname`" + PLATFORM_PREBUILD_CMDS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o prebuild_cmds`" + PLATFORM_BUILDFLAGS="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildflags`" + PLATFORM_BUILDFLAGS="$PLATFORM_BUILDFLAGS ${EXTRA_OPTIONS[@]}" + PLATFORM_BUILDCMD="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o buildcmd`" + PLATFORM_DSC="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o dsc`" + PLATFORM_ARCH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o arch`" + PLATFORM_PACKAGES_PATH="$PWD" + + TEMP_PACKAGES_PATH="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o packages_path`" + if [ -n "$TEMP_PACKAGES_PATH" ]; then + IFS=: + for path in "$TEMP_PACKAGES_PATH"; do + case "$path" in + /*) + PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$path" + ;; + *) + PLATFORM_PACKAGES_PATH="$PLATFORM_PACKAGES_PATH:$PWD/$path" + ;; + esac + done + unset IFS + fi + if [ $VERBOSE -eq 1 ]; then + echo "Setting build parallellism to $NUM_THREADS processes\n" + echo "PLATFORM_NAME=$PLATFORM_NAME" + echo "PLATFORM_PREBUILD_CMDS=$PLATFORM_PREBUILD_CMDS" + echo "PLATFORM_BUILDFLAGS=$PLATFORM_BUILDFLAGS" + echo "PLATFORM_BUILDCMD=$PLATFORM_BUILDCMD" + echo "PLATFORM_DSC=$PLATFORM_DSC" + echo "PLATFORM_ARCH=$PLATFORM_ARCH" + echo "PLATFORM_PACKAGES_PATH=$PLATFORM_PACKAGES_PATH" + fi + + set_cross_compile + CROSS_COMPILE="$TEMP_CROSS_COMPILE" + + echo "Building $PLATFORM_NAME - $PLATFORM_ARCH" + echo "CROSS_COMPILE=\"$TEMP_CROSS_COMPILE\"" + echo "$board"_BUILDFLAGS="'$PLATFORM_BUILDFLAGS'" + + if [ "$TARGETS" == "" ]; then + TARGETS=( RELEASE ) + fi + + case $TOOLCHAIN in + "gcc") + export TOOLCHAIN=`get_gcc_version "$CROSS_COMPILE"gcc` + ;; + "clang") + export TOOLCHAIN=`get_clang_version clang` + ;; + esac + echo "TOOLCHAIN is ${TOOLCHAIN}" + + export ${TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE + echo "Toolchain prefix: ${TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE" + + export PACKAGES_PATH="$PLATFORM_PACKAGES_PATH" + for target in "${TARGETS[@]}" ; do + if [ X"$PLATFORM_PREBUILD_CMDS" != X"" ]; then + echo "Run pre build commands" + eval ${PLATFORM_PREBUILD_CMDS} + fi + if [ X"$PLATFORM_BUILDCMD" == X"" ]; then + echo ${TOOLCHAIN}_${PLATFORM_ARCH}_PREFIX=$CROSS_COMPILE build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${TOOLCHAIN} -p "$PLATFORM_DSC" -b "$target" \ + ${PLATFORM_BUILDFLAGS} + build -n $NUM_THREADS -a "$PLATFORM_ARCH" -t ${TOOLCHAIN} -p "$PLATFORM_DSC" -b "$target" \ + ${PLATFORM_BUILDFLAGS} + else + ${PLATFORM_BUILDCMD} -b "$target" ${PLATFORM_BUILDFLAGS} + fi + RESULT=$? + if [ $RESULT -eq 0 ]; then + if [ X"$TOS_DIR" != X"" ]; then + pushd $TOS_DIR >/dev/null + if [ $VERBOSE -eq 1 ]; then + echo "$TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${TOOLCHAIN} $board" + fi + $TOOLS_DIR/tos-build.sh -e "$EDK2_DIR" -t "$target"_${TOOLCHAIN} $board + RESULT=$? + popd >/dev/null + fi + fi + if [ $RESULT -eq 0 ]; then + if [ X"$ATF_DIR" != X"" ]; then + pushd $ATF_DIR >/dev/null + if [ $VERBOSE -eq 1 ]; then + echo "$TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${TOOLCHAIN} $board" + fi + $TOOLS_DIR/atf-build.sh -e "$EDK2_DIR" -t "$target"_${TOOLCHAIN} $board + RESULT=$? + popd >/dev/null + fi + fi + result_log $RESULT "$PLATFORM_NAME $target" + done + unset PACKAGES_PATH +} + + +function uefishell +{ + BUILD_ARCH=`uname -m` + case $BUILD_ARCH in + arm*) + ARCH=ARM + ;; + aarch64) + ARCH=AARCH64 + ;; + *) + unset ARCH + ;; + esac + export ARCH + if [ $VERBOSE -eq 1 ]; then + echo "Building BaseTools" + fi + export EDK_TOOLS_PATH=`pwd`/BaseTools + . edksetup.sh BaseTools + make -C $EDK_TOOLS_PATH + if [ $? -ne 0 ]; then + echo " !!! UEFI BaseTools failed to build !!! " >&2 + exit 1 + fi +} + + +function usage +{ + echo "usage:" + echo -n "uefi-build.sh [-b DEBUG | RELEASE] [ all " + for board in "${boards[@]}" ; do + echo -n "| $board " + done + echo "]" + printf "%8s\tbuild %s\n" "all" "all supported platforms" + for board in "${boards[@]}" ; do + PLATFORM_NAME="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG -p $board get -o longname`" + printf "%8s\tbuild %s\n" "$board" "${PLATFORM_NAME}" + done +} + +# +# Since we do a command line validation on whether specified platforms exist or +# not, do a first pass of command line to see if there is an explicit config +# file there to read valid platforms from. +# +commandline=( "$@" ) +i=0 +for arg; +do + if [ $arg == "-c" ]; then + FILE_ARG=${commandline[i + 1]} + if [ ! -f "$FILE_ARG" ]; then + echo "ERROR: configuration file '$FILE_ARG' not found" >&2 + exit 1 + fi + case "$FILE_ARG" in + /*) + PLATFORM_CONFIG="-c \"$FILE_ARG\"" + ;; + *) + PLATFORM_CONFIG="-c `readlink -f \"$FILE_ARG\"`" + ;; + esac + echo "Platform config file: '$FILE_ARG'" + export PLATFORM_CONFIG + fi + i=$(($i + 1)) +done + +builds=() +boards=() +boardlist="`$TOOLS_DIR/parse-platforms.py $PLATFORM_CONFIG shortlist`" +for board in $boardlist; do + boards=(${boards[@]} $board) +done + +NUM_TARGETS=0 + +while [ "$1" != "" ]; do + case $1 in + all ) + builds=(${boards[@]}) + NUM_TARGETS=$(($NUM_TARGETS + 1)) + ;; + "/h" | "/?" | "-?" | "-h" | "--help" ) + usage + exit + ;; + "-v" ) + VERBOSE=1 + ;; + "-a" ) + shift + ATF_DIR="$1" + ;; + "-c" ) + # Already parsed above - skip this + option + shift + ;; + "-s" ) + shift + export TOS_DIR="$1" + ;; + "-b" | "--build" ) + shift + echo "Adding Build profile: $1" + TARGETS=( ${TARGETS[@]} $1 ) + ;; + "-D" ) + shift + echo "Adding option: -D $1" + EXTRA_OPTIONS=( ${EXTRA_OPTIONS[@]} "-D" $1 ) + ;; + "-T" ) + shift + echo "Setting toolchain to '$1'" + TOOLCHAIN="$1" + ;; + "-1" ) + NUM_THREADS=1 + ;; + * ) + MATCH=0 + for board in "${boards[@]}" ; do + if [ "$1" == $board ]; then + MATCH=1 + builds=(${builds[@]} "$board") + break + fi + done + + if [ $MATCH -eq 0 ]; then + echo "unknown arg $1" + usage + exit 1 + fi + NUM_TARGETS=$(($NUM_TARGETS + 1)) + ;; + esac + shift +done + +# If there were no args, use a menu to select a single board / all boards to build +if [ $NUM_TARGETS -eq 0 ] +then + read -p "$( + f=0 + for board in "${boards[@]}" ; do + echo "$((++f)): $board" + done + echo $((++f)): all + + echo -ne '> ' + )" selection + + if [ "$selection" -eq $((${#boards[@]} + 1)) ]; then + builds=(${boards[@]}) + else + builds="${boards[$((selection-1))]}" + fi +fi + +# Check to see if we are in a UEFI repository +# refuse to continue if we aren't +if [ ! -e BaseTools ] +then + echo "ERROR: we aren't in the UEFI directory." + echo " I can tell because I can't see the BaseTools directory" + exit 1 +fi + +EDK2_DIR="$PWD" +export VERBOSE + +if [[ "${EXTRA_OPTIONS[@]}" != *"FIRMWARE_VER"* ]]; then + if test -d .git && head=`git rev-parse --verify --short HEAD 2>/dev/null`; then + FIRMWARE_VER=`git rev-parse --short HEAD` + if ! git diff-index --quiet HEAD --; then + FIRMWARE_VER="${FIRMWARE_VER}-dirty" + fi + EXTRA_OPTIONS=( ${EXTRA_OPTIONS[@]} "-D" FIRMWARE_VER=$FIRMWARE_VER ) + if [ $VERBOSE -eq 1 ]; then + echo "FIRMWARE_VER=$FIRMWARE_VER" + echo "EXTRA_OPTIONS=$EXTRA_OPTIONS" + fi + fi +fi + +uefishell + +if [ X"$TOOLCHAIN" = X"" ]; then + TOOLCHAIN=gcc +fi + +for board in "${builds[@]}" ; do + build_platform +done + +result_print diff --git a/uefi-tools/uefi-build.sh.bash_completion b/uefi-tools/uefi-build.sh.bash_completion new file mode 100644 index 00000000..f0a5305a --- /dev/null +++ b/uefi-tools/uefi-build.sh.bash_completion @@ -0,0 +1,24 @@ +# bash completion for uefi-build.sh +# copy this file to /etc/bash_completion.d/uefi-build.s + +have uefi-build.sh && +_uefi-build.sh() +{ + local cur prev + + COMPREPLY=() + _get_comp_words_by_ref -n = cur + + _expand || return 0 + + COMPREPLY=( $( compgen -W '--help -b --build RELEASE DEBUG a5 a9 tc1 tc2 panda origen arndale rtsm_a9x4 rtsm_a15x1 rtsm_a15mpcore rtsm_aarch64 beagle all' -- "$cur" ) ) +} && +complete -F _uefi-build.sh uefi-build.sh + +# Local variables: +# mode: shell-script +# sh-basic-offset: 4 +# sh-indent-comment: t +# indent-tabs-mode: nil +# End: +# ex: ts=4 sw=4 et filetype=sh |