Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split the optee image into three images to support optee pager in arm-tf #1589

Merged
merged 1 commit into from
Jun 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()