1 /*
2 * Copyright (c) 2024 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <app_api.h>
8
9 #include <zephyr/kernel.h>
10 #include <zephyr/llext/llext.h>
11 #include <zephyr/llext/buf_loader.h>
12 #include <zephyr/app_memory/mem_domain.h>
13
14 #ifdef LOAD_AND_RUN_EXTENSION
15 static const unsigned char extension_llext[] = {
16 #include <extension.inc>
17 };
18 static const size_t extension_llext_len = ARRAY_SIZE(extension_llext);
19 #endif
20
21 #define STACK_SIZE 1024
22 #define HEAP_SIZE 1024
23
24 #ifdef LOAD_AND_RUN_EXTENSION
25 struct k_thread kernel_thread, user_thread;
26
27 K_THREAD_STACK_DEFINE(stack_kernel, STACK_SIZE);
28 K_THREAD_STACK_DEFINE(stack_user, STACK_SIZE);
29
30 K_HEAP_DEFINE(heap_kernel, HEAP_SIZE);
31 K_HEAP_DEFINE(heap_user, HEAP_SIZE);
32
thread_entry(void * p1,void * p2,void * p3)33 static void thread_entry(void *p1, void *p2, void *p3)
34 {
35 int bar;
36 int (*start_fn)(int) = p1;
37
38 printk("Calling extension from %s\n",
39 k_is_user_context() ? "user" : "kernel");
40
41 if (k_is_user_context()) {
42 bar = 42;
43 } else {
44 bar = 43;
45 }
46
47 start_fn(bar);
48 }
49
load_and_run_extension(int thread_flags,struct k_thread * thread,struct k_mem_domain * domain,k_thread_stack_t * stack,struct k_heap * heap,struct llext ** ext)50 void load_and_run_extension(int thread_flags, struct k_thread *thread,
51 struct k_mem_domain *domain,
52 k_thread_stack_t *stack, struct k_heap *heap,
53 struct llext **ext)
54 {
55 struct llext_buf_loader buf_loader = LLEXT_BUF_LOADER(extension_llext,
56 extension_llext_len);
57 struct llext_loader *loader = &buf_loader.loader;
58 struct llext_load_param ldr_parm = LLEXT_LOAD_PARAM_DEFAULT;
59 int (*start_fn)(int bar);
60
61 llext_load(loader, "extension", ext, &ldr_parm);
62 start_fn = llext_find_sym(&(*ext)->exp_tab, "start");
63
64 llext_add_domain(*ext, domain);
65
66 k_thread_create(thread, stack, STACK_SIZE,
67 thread_entry, start_fn, NULL, NULL, -1,
68 K_INHERIT_PERMS | thread_flags,
69 K_FOREVER);
70 k_mem_domain_add_thread(domain, thread);
71 k_thread_heap_assign(thread, heap);
72
73 k_thread_start(thread);
74 k_thread_join(thread, K_FOREVER);
75
76 llext_unload(ext);
77 }
78 #endif
79
main(void)80 int main(void)
81 {
82 #ifdef LOAD_AND_RUN_EXTENSION
83 struct k_mem_domain domain_kernel, domain_user;
84 struct llext *ext_kernel, *ext_user;
85
86 k_mem_domain_init(&domain_kernel, 0, NULL);
87 k_mem_domain_init(&domain_user, 0, NULL);
88
89 load_and_run_extension(0, &kernel_thread, &domain_kernel,
90 stack_kernel, &heap_kernel, &ext_kernel);
91 load_and_run_extension(K_USER, &user_thread, &domain_user,
92 stack_user, &heap_user, &ext_user);
93
94 printk("Done\n");
95 #else
96 printk("Extension not loaded\n");
97 #endif
98 return 0;
99 }
100