Skip to content

Commit

Permalink
Generate binaries for loaders supporting separate binary loading
Browse files Browse the repository at this point in the history
Generate three binaries tee-header_v2.bin, tee-pager_v2.bin and
tee-pageable_v2.bin for loaders supporting separate binary loading.
This kind of loader loads and parses header binary first and then
loads rest two binaries under specified manners header information
implies. Generic loaders who don't support separate binary loading
just ignore these binaries.

Signed-off-by: Summer Qin <[email protected]>
Acked-by: Etienne Carriere <[email protected]>
Reviewed-by: Jerome Forissier <[email protected]>
Reviewed-by: Jens Wiklander <[email protected]>
  • Loading branch information
Summer-ARM committed Jun 28, 2017
1 parent 70bb1a1 commit 3c1d40f
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 29 deletions.
37 changes: 28 additions & 9 deletions core/arch/arm/kernel/link.mk
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,14 @@ $(link-out-dir)/tee-init_mem_usage.txt: $(link-out-dir)/tee.elf
@echo -n 0x > $@
$(q)$(NMcore) $< | grep ' __init_mem_usage' | sed 's/ .*$$//' >> $@

all: $(link-out-dir)/tee.bin
cleanfiles += $(link-out-dir)/tee.bin
$(link-out-dir)/tee.bin: $(link-out-dir)/tee-pager.bin \
$(link-out-dir)/tee-pageable.bin \
$(link-out-dir)/tee-init_size.txt \
$(link-out-dir)/tee-init_load_addr.txt \
$(link-out-dir)/tee-init_mem_usage.txt \
gen_hash_bin_deps := $(link-out-dir)/tee-pager.bin \
$(link-out-dir)/tee-pageable.bin \
$(link-out-dir)/tee-init_size.txt \
$(link-out-dir)/tee-init_load_addr.txt \
$(link-out-dir)/tee-init_mem_usage.txt \
./scripts/gen_hashed_bin.py

define gen_hash_bin_cmd
@$(cmd-echo-silent) ' GEN $@'
$(q)load_addr=`cat $(link-out-dir)/tee-init_load_addr.txt` && \
./scripts/gen_hashed_bin.py \
Expand All @@ -218,9 +218,28 @@ $(link-out-dir)/tee.bin: $(link-out-dir)/tee-pager.bin \
--init_load_addr_lo $$(($$load_addr & 0xffffffff)) \
--init_mem_usage `cat $(link-out-dir)/tee-init_mem_usage.txt` \
--tee_pager_bin $(link-out-dir)/tee-pager.bin \
--tee_pageable_bin $(link-out-dir)/tee-pageable.bin \
--out $@
--tee_pageable_bin $(link-out-dir)/tee-pageable.bin
endef

all: $(link-out-dir)/tee.bin
cleanfiles += $(link-out-dir)/tee.bin
$(link-out-dir)/tee.bin: $(gen_hash_bin_deps)
$(gen_hash_bin_cmd) --out $@

all: $(link-out-dir)/tee-header_v2.bin
cleanfiles += $(link-out-dir)/tee-header_v2.bin
$(link-out-dir)/tee-header_v2.bin: $(gen_hash_bin_deps)
$(gen_hash_bin_cmd) --out_header_v2 $@

all: $(link-out-dir)/tee-pager_v2.bin
cleanfiles += $(link-out-dir)/tee-pager_v2.bin
$(link-out-dir)/tee-pager_v2.bin: $(gen_hash_bin_deps)
$(gen_hash_bin_cmd) --out_pager_v2 $@

all: $(link-out-dir)/tee-pageable_v2.bin
cleanfiles += $(link-out-dir)/tee-pageable_v2.bin
$(link-out-dir)/tee-pageable_v2.bin: $(gen_hash_bin_deps)
$(gen_hash_bin_cmd) --out_pageable_v2 $@

all: $(link-out-dir)/tee.symb_sizes
cleanfiles += $(link-out-dir)/tee.symb_sizes
Expand Down
50 changes: 50 additions & 0 deletions documentation/optee_design.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,56 @@ OP-TEE to be able to initialize at all. The loader supplies in `r0/x0` the
address of the first byte following what was not copied and jumps to the load
address to start OP-TEE.

In addition to overall binary with partitions inside described as above, extra
three binaries are generated simultaneously during build process for loaders
who support loading separate binaries:
```
+----------+
| Header |
+----------+
+----------+
| Init |
+----------+
| Hashes |
+----------+
+----------+
| Pageable |
+----------+
```
In this case, loaders load header binary first to get image list and information
of each image; and then load each of them into specific load address assigned
in structure. These binaries are named with v2 suffix to distinguish from the
existing binaries. Header format is updated to help loaders loading binaries
efficiently:
```c
#define OPTEE_IMAGE_ID_PAGER 0
#define OPTEE_IMAGE_ID_PAGED 1

struct optee_image {
uint32_t load_addr_hi;
uint32_t load_addr_lo;
uint32_t image_id;
uint32_t size;
};

struct optee_header_v2 {
uint32_t magic;
uint8_t version;
uint8_t arch;
uint16_t flags;
uint32_t nb_images;
struct optee_image optee_image[];
};
```

Magic number and architecture are identical as original. Version is increased
to 2. `load_addr_hi` and `load_addr_lo` may be 0xFFFFFFFF for pageable binary
since pageable part may get loaded by loader into dynamic available position.
`image_id` indicates how loader handles current binary.
Loaders who don't support separate loading just ignore all v2 binaries.

## Initializing the pager
The pager is initialized as early as possible during boot in order to minimize
the "init" area. The global variable `tee_mm_vcore` describes the virtual memory
Expand Down
90 changes: 70 additions & 20 deletions scripts/gen_hashed_bin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
# Copyright (c) 2014, Linaro Limited
# Copyright (c) 2014-2017, Linaro Limited
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -34,15 +34,28 @@
import hashlib

arch_id = {'arm32': 0, 'arm64': 1}
image_id = {'pager': 0, 'paged': 1}

def write_header(outf, init_size, args, paged_size):
def write_header_v1(outf, init_size, args, paged_size):
magic = 0x4554504f # 'OPTE'
version = 1;
outf.write(struct.pack('<IBBHIIIII', \
magic, version, arch_id[args.arch], args.flags, init_size, \
args.init_load_addr_hi, args.init_load_addr_lo, \
args.init_mem_usage, paged_size))


def write_header_v2(outf, init_size, args, paged_size):
magic = 0x4554504f # 'OPTE'
version = 2
nb_images = 1 if paged_size == 0 else 2
outf.write(struct.pack('<IBBHI', \
magic, version, arch_id[args.arch], args.flags, nb_images))
outf.write(struct.pack('<IIII', \
args.init_load_addr_hi, args.init_load_addr_lo, \
image_id['pager'], init_size))
if nb_images == 2:
outf.write(struct.pack('<IIII', \
0xffffffff, 0xffffffff, image_id['paged'], paged_size))

def append_to(outf, start_offs, in_fname, max_bytes=0xffffffff):
#print "Appending %s@0x%x 0x%x bytes at position 0x%x" % \
Expand Down Expand Up @@ -117,32 +130,69 @@ def get_args():
help='The input tee_pageable.bin')

parser.add_argument('--out', \
required=True, type=argparse.FileType('wb'), \
required=False, type=argparse.FileType('wb'), \
help='The output tee.bin')

parser.add_argument('--out_header_v2', \
required=False, type=argparse.FileType('wb'), \
help='The output tee_header_v2.bin')

parser.add_argument('--out_pager_v2', \
required=False, type=argparse.FileType('wb'), \
help='The output tee_pager_v2.bin')

parser.add_argument('--out_pageable_v2', \
required=False, type=argparse.FileType('wb'), \
help='The output tee_pageable_v2.bin')

return parser.parse_args();

def main():
args = get_args()
init_bin_size = args.init_size
tee_pager_fname = args.tee_pager_bin
tee_pageable_fname = args.tee_pageable_bin
outf = args.out

write_header(outf, 0, args, 0)
header_size = outf.tell();
append_to(outf, 0, tee_pager_fname)
append_to(outf, 0, tee_pageable_fname, init_bin_size)
append_hashes(outf, tee_pageable_fname)
init_size = outf.tell() - header_size;
append_to(outf, init_bin_size, tee_pageable_fname)
paged_size = outf.tell() - init_size - header_size;

outf.seek(0)
#print "init_size 0x%x" % init_size
write_header(outf, init_size, args, paged_size)

outf.close()
pager_input_size = os.path.getsize(tee_pager_fname);
paged_input_size = os.path.getsize(tee_pageable_fname);
hash_size = paged_input_size / (4 * 1024) * \
hashlib.sha256().digest_size

if paged_input_size % (4 * 1024) != 0:
print("Error: pageable size not a multiple of 4K:" + \
repr(paged_input_size))
sys.exit(1)

init_size = pager_input_size + \
min(init_bin_size, paged_input_size) + \
hash_size
paged_size = paged_input_size - \
min(init_bin_size, paged_input_size)

if args.out is not None:
outf = args.out
write_header_v1(outf, init_size, args, paged_size)
append_to(outf, 0, tee_pager_fname)
append_to(outf, 0, tee_pageable_fname, init_bin_size)
append_hashes(outf, tee_pageable_fname)
append_to(outf, init_bin_size, tee_pageable_fname)
outf.close()

if args.out_header_v2 is not None:
outf = args.out_header_v2
write_header_v2(outf, init_size, args, paged_size)
outf.close()

if args.out_pager_v2 is not None:
outf = args.out_pager_v2
append_to(outf, 0, tee_pager_fname)
append_to(outf, 0, tee_pageable_fname, init_bin_size)
append_hashes(outf, tee_pageable_fname)
outf.close()

if args.out_pageable_v2 is not None:
outf = args.out_pageable_v2
append_to(outf, init_bin_size, tee_pageable_fname)
outf.close()

if __name__ == "__main__":
main()

0 comments on commit 3c1d40f

Please sign in to comment.