source: EcnlProtoTool/trunk/ntshell/src/main.c@ 446

Last change on this file since 446 was 446, checked in by coas-nagasima, 4 years ago

プログラムテーブルのセクションを追加しntshellで読みだしてHELPを表示するよう変更

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 17.9 KB
RevLine 
[279]1/*
[433]2 * TOPPERS PROJECT Home Network Working Group Software
[279]3 *
[433]4 * Copyright (C) 2014-2019 Cores Co., Ltd. Japan
[279]5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id$
36 */
37
38/*
39 * サンプルプログラム(1)の本体
40 */
41
42#include <kernel.h>
43#include <t_stdlib.h>
44#include <sil.h>
[331]45#include <setjmp.h>
[433]46#include <string.h>
[279]47#include "syssvc/serial.h"
48#include "syssvc/syslog.h"
[441]49#include "target_syssvc.h"
[279]50#include "kernel_cfg.h"
51#include "main.h"
[442]52#include "mbed_retarget.h"
[441]53#include "fdtable.h"
54#ifndef NTSHELL_NO_SOCKET
[279]55#include <tinet_config.h>
56#include <netinet/in.h>
57#include <netinet/in_itron.h>
58#include <tinet_nic_defs.h>
59#include <tinet_cfg.h>
60#include <netinet/in_var.h>
61#include <net/ethernet.h>
62#include <net/if6_var.h>
63#include <net/net.h>
64#include <net/if_var.h>
65#include <netinet/udp_var.h>
66#include "ffarch.h"
67#include "ff.h"
68#include "websocket_fbs.h"
[331]69#include "core/ntshell.h"
70#include "core/ntlibc.h"
[279]71#include "usrcmd.h"
[331]72#include "util/ntopt.h"
[441]73#include "netapp/dhcp4_cli.h"
74#include "ntp_cli.h"
75#include "netcmd.h"
76#endif
[443]77#include "../musl-1.1.18/include/elf.h"
[279]78
79ID ws_api_mailboxid = MAIN_DATAQUEUE;
80ID ws_mempoolid = MPF_NET_BUF_256;
81
82char command[NTOPT_TEXT_MAXLEN];
83
[331]84const uint8_t mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
[279]85
86enum main_state_t {
87 main_state_start,
88 main_state_idle,
[441]89#ifndef NTSHELL_NO_SOCKET
90 main_state_start_dhcp,
91#endif
92 main_state_servey_cmd,
[279]93};
94
[431]95struct main_obj_t {
[432]96 ntshell_t ntshell;
[441]97 int timer;
[279]98 enum main_state_t state;
99 SYSTIM prev, now;
[441]100 task_base_t **tasks;
101 int task_count;
102#ifndef NTSHELL_NO_SOCKET
103 uint8_t link;
104 uint8_t link_up;
105 uint8_t up;
106 uint8_t dhcp;
107 uint8_t ntp;
108 ntp_cli_state_t ntp_state;
109#endif
110 bool_t exec;
111 int event_req, event_res;
[279]112};
[431]113struct main_obj_t main_obj;
[279]114
[441]115#ifndef NTSHELL_NO_SOCKET
116static void netif_link_callback(T_IFNET *ether);
117static void main_change_netif_link(uint8_t link_up, uint8_t up);
118#endif
[432]119static void main_initialize(struct main_obj_t *obj);
[441]120static void main_finalize(struct main_obj_t *obj);
121static int main_get_timer(struct main_obj_t *obj);
122static void main_progress(struct main_obj_t *obj, int elapse);
123static void main_timeout(struct main_obj_t *obj, bool_t wakeup);
124static int execute_command(struct main_obj_t *obj, int wait);
[443]125static const Elf32_Ehdr *load_elf(const uint8_t *file);
126static void execute_elf(const Elf32_Ehdr *, long *args);
[446]127static void read_cmdlist_from_elf(const Elf32_Ehdr *Ehdr);
[431]128static int usrcmd_ntopt_callback(long *args, void *extobj);
[441]129#ifndef NTSHELL_NO_SOCKET
130static void ntp_cli_state_changed(ntp_cli_state_t state);
131#endif
[279]132
[441]133void stdio_open(ID portid);
134void stdio_input(unsigned char c);
135
136bool_t dhcp_enable;
137int ntshell_exit;
[431]138int shellcmd_exit_code;
139volatile int shellcmd_state;
[443]140typedef void (*elf_entry_t)(long *args);
[431]141jmp_buf shellcmd_exit;
142
[441]143void main_task_init(task_base_t **tasks, int task_count)
144{
145 main_obj.tasks = tasks;
146 main_obj.task_count = task_count;
147}
148
[279]149int uart_read(char *buf, int cnt, void *extobj)
150{
[441]151 struct main_obj_t *obj = (struct main_obj_t *)extobj;
152 int result;
153 ER ret;
154 int timer;
155 bool_t wakeup = false;
156
157 obj->prev = obj->now;
158
159 if (obj->event_req != obj->event_res) {
160 obj->event_res = obj->event_req;
161 wakeup = true;
162#ifndef NTSHELL_NO_SOCKET
163 if (obj->dhcp) {
164 obj->dhcp = 0;
165 obj->state = main_state_start_dhcp;
166 }
167#endif
168 obj->timer = 0;
169 }
170
171 /* タイマー取得 */
172 timer = main_get_timer(obj);
173
174 /* 待ち */
175 ret = serial_trea_dat(SIO_PORTID, buf, cnt, timer);
176 if ((ret < 0) && (ret != E_OK) && (ret != E_TMOUT) && (ret != E_RLWAI)) {
177 syslog(LOG_NOTICE, "tslp_tsk ret: %s %d", itron_strerror(ret), timer);
178 ntshell_exit = 1;
179 return -1;
180 }
181 if (ret != E_TMOUT)
182 wakeup = true;
183 result = (int)ret;
184
185 ret = get_tim(&obj->now);
186 if (ret != E_OK) {
187 syslog(LOG_NOTICE, "get_tim ret: %s", itron_strerror(ret));
188 ntshell_exit = 1;
189 return -1;
190 }
191
192 /* 時間経過 */
193 int elapse = obj->now - obj->prev;
194 main_progress(obj, elapse);
195
196 /* タイムアウト処理 */
197 main_timeout(obj, wakeup);
198
199 return result;
[279]200}
201
202int uart_write(const char *buf, int cnt, void *extobj)
203{
204 return serial_wri_dat(SIO_PORTID, buf, cnt);
205}
206
[432]207int cmd_execute(const char *text, void *extobj)
[279]208{
[431]209 if (text != NULL) {
[442]210 strlcpy(command, text, sizeof(command));
[431]211 }
212 ER ret;
213 ID tskid = 0;
[279]214
[431]215 ret = get_tid(&tskid);
216 if (ret != E_OK) {
217 syslog(LOG_ERROR, "get_tid %d", ret);
218 }
219
[441]220 return execute_command(&main_obj, tskid == MAIN_TASK);
[279]221}
222
[441]223gpio_t led_blue, led_green, led_red, sw;
224
[279]225/*
[441]226 * メインタスク
[279]227 */
228void main_task(intptr_t exinf)
229{
[432]230 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
[279]231
[441]232 gpio_init_out(&led_blue, LED_BLUE);
233 gpio_init_out(&led_green, LED_GREEN);
234 gpio_init_out(&led_red, LED_RED);
235 gpio_init_in(&sw, USER_BUTTON0);
236
237 obj->exec = gpio_read(&sw) == 1;
238
239 gpio_write(&led_blue, 1);
240 gpio_write(&led_green, obj->exec ? 1 : 0);
241 gpio_write(&led_red, 0);
242
243 ether_set_link_callback(main_change_netif_link);
244
245 /* 初期化 */
246 ffarch_init();
247
248 stdio_open(SIO_PORTID);
249
250#ifndef NTSHELL_NO_SOCKET
251 ntp_cli_set_state_changed_cb(ntp_cli_state_changed);
252#endif
253
[432]254 main_initialize(obj);
255
256 ntshell_init(&obj->ntshell, uart_read, uart_write, cmd_execute, obj);
257 ntshell_set_prompt(&obj->ntshell, "NTShell>");
258 ntshell_execute(&obj->ntshell);
[441]259
260 main_finalize(obj);
[279]261}
262
263/*
264 * 初期化
265 */
[432]266static void main_initialize(struct main_obj_t *obj)
[279]267{
[432]268 ER ret;
[441]269 ID tskid = 0;
[279]270
[441]271 ret = get_tid(&tskid);
272 if (ret != E_OK) {
273 syslog(LOG_ERROR, "get_tid %d", ret);
274 return;
275 }
[279]276
[441]277 obj->timer = 100000;
[432]278 obj->state = main_state_start;
[279]279
[441]280 for (int i = 0; i < obj->task_count; i++) {
281 task_base_t *task = obj->tasks[i];
282 task->on_start(task, tskid);
[279]283 }
284
[441]285 gpio_write(&led_blue, 0);
[279]286 gpio_write(&led_green, 0);
287
288 act_tsk(HTTPD1_TASK);
289 act_tsk(HTTPD2_TASK);
290
[432]291 ret = get_tim(&obj->now);
292 if (ret != E_OK) {
[279]293 syslog(LOG_ERROR, "get_tim");
294 ext_tsk();
295 return;
296 }
297}
298
[441]299static void main_finalize(struct main_obj_t *obj)
300{
301 for (int i = 0; i < obj->task_count; i++) {
302 task_base_t *task = obj->tasks[i];
303 task->on_end(task);
304 }
305}
306
[279]307/*
308 * タイマー取得
309 */
[441]310static int main_get_timer(struct main_obj_t *obj)
[279]311{
[441]312 int timer = obj->timer;
[279]313
[441]314 for (int i = 0; i < obj->task_count; i++) {
315 task_base_t *task = obj->tasks[i];
316 int timer2 = task->get_timer(task);
317 if ((timer == -1) || ((timer2 != -1) && (timer > timer2)))
318 timer = timer2;
319 }
320
[279]321 return timer;
322}
323
324/*
325 * 時間経過
326 */
[441]327static void main_progress(struct main_obj_t *obj, int elapse)
[279]328{
[432]329 if (obj->timer != TMO_FEVR) {
330 obj->timer -= elapse;
331 if (obj->timer < 0) {
332 obj->timer = 0;
[279]333 }
334 }
[441]335
336 for (int i = 0; i < obj->task_count; i++) {
337 task_base_t *task = obj->tasks[i];
338 task->progress(task, elapse);
339 }
[279]340}
341
342/*
343 * タイムアウト処理
344 */
[441]345static void main_timeout(struct main_obj_t *obj, bool_t wakeup)
[279]346{
[441]347 ER ret;
348 uint32_t event = wakeup ? MAIN_EVENT_WAKEUP : 0;
349
350 if (!wakeup && (obj->timer != 0))
351 return;
352
353 switch (obj->state) {
354 case main_state_start:
355#ifndef NTSHELL_NO_SOCKET
356 ether_set_link_callback(netif_link_callback);
357#endif
358 {
359 FILINFO fno;
360#if FF_USE_LFN
361 char lfn[FF_MAX_LFN + 1];
362 fno.lfname = lfn;
363 fno.lfsize = FF_MAX_LFN + 1;
364#endif
365 if (f_stat("1:/upload/main.mrb", &fno) != FR_OK) {
366 obj->exec = false;
367 }
368
369 if (obj->exec) {
370 cmd_execute("mruby -b 1:/upload/main.mrb", obj);
371 }
372 }
373 obj->state = main_state_idle;
374 obj->timer = TMO_FEVR;
375 break;
376#ifndef NTSHELL_NO_SOCKET
377 case main_state_start_dhcp:
378 ret = dhcp4c_renew_info();
379 if (ret == E_OK) {
380 obj->state = main_state_idle;
381 obj->timer = TMO_FEVR;
382 }
383 else {
384 obj->state = main_state_start_dhcp;
385 obj->timer = 1000000;
386 }
387 break;
388#endif
389 default:
390 obj->state = main_state_idle;
391 obj->timer = TMO_FEVR;
392 break;
393 }
394#ifndef NTSHELL_NO_SOCKET
395 if (obj->link) {
396 obj->link = 0;
397 event |= MAIN_EVENT_NETIF_CHANGED;
398 if (obj->link_up)
399 event |= MAIN_EVENT_LINK_UP;
400 if (obj->up)
401 event |= MAIN_EVENT_UP;
402
403 if (obj->link_up && obj->up)
404 ntp_cli_execute();
405
406 main_change_netif_link(obj->link_up, obj->up);
407 }
408 if (obj->ntp) {
409 obj->ntp = 0;
410 if (obj->ntp_state != NTP_CLI_STATE_SYNC)
411 event |= MAIN_EVENT_NTP_ASYNC;
412 else
413 event |= MAIN_EVENT_NTP_SYNC;
414 }
415#endif
416 for (int i = 0; i < obj->task_count; i++) {
417 task_base_t *task = obj->tasks[i];
418 task->process(task, event);
419 }
[279]420}
421
[441]422#ifndef NTSHELL_NO_SOCKET
[279]423/* MACアドレスの設定時に呼ばれる */
424void mbed_mac_address(char *mac)
425{
426 memcpy(mac, mac_addr, 6);
427}
428
[441]429void main_change_netif_link(uint8_t link_up, uint8_t up)
[279]430{
431 FLGPTN flgptn;
432 T_RTSK rtsk;
433 ER ret;
434
[431]435 ret = ref_tsk(SHELLCMD_TASK, &rtsk);
[279]436 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
437 return;
438
439 FD_SET(0, (fd_set *)&flgptn);
440
441 set_flg(FLG_SELECT_WAIT, flgptn);
442}
443
[441]444void netif_link_callback(T_IFNET *ether)
445{
446 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
447 uint8_t link_up = (ether->flags & IF_FLAG_LINK_UP) != 0;
448 uint8_t up = (ether->flags & IF_FLAG_UP) != 0;
449 bool_t wake = false;
450
451 if (dhcp_enable) {
452 if (!link_up)
453 dhcp4c_rel_info();
454 else if (!up) {
455 wake = dhcp4c_renew_info() != E_OK;
456 if (wake) {
457 obj->dhcp = 1;
458 }
459 }
460 }
461 else {
462 up = link_up;
463 }
464
465 if ((obj->link_up != link_up) || (obj->up != up)) {
466 obj->link = 1;
467 wake = true;
468 }
469
470 obj->link_up = link_up;
471 obj->up = up;
472
473 if (wake && (obj->event_req == obj->event_res)) {
474 obj->event_req++;
475 rel_wai(MAIN_TASK);
476 }
477}
478
479void ntp_cli_state_changed(ntp_cli_state_t state)
480{
481 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
482 bool_t wake = obj->ntp_state != state;
483
484 if (wake) {
485 obj->ntp_state = state;
486 obj->ntp = 1;
487
488 if (obj->event_req == obj->event_res) {
489 obj->event_req++;
490 rel_wai(MAIN_TASK);
491 }
492 }
493}
494#endif
495
[279]496/*
[431]497 * shellcmdタスク
[279]498 */
[431]499void shellcmd_task(intptr_t exinf)
[279]500{
[431]501 shellcmd_state = 1;
[441]502
503 if (setjmp(shellcmd_exit) == 0) {
504 shellcmd_exit_code = ntopt_parse(command, usrcmd_ntopt_callback, NULL);
505 }
506
507 //fflush(stdout);
508 clean_fd();
509
[431]510 shellcmd_state = 2;
[279]511}
512
[331]513static const cmd_table_t cmdlist[] = {
514 {"cd", "change directory", usrcmd_cd },
515 {"ls", "list files", usrcmd_ls },
516 {"cp", "copy file", usrcmd_cp },
517 {"rm", "remove file", usrcmd_rm },
518 {"mv", "move file", usrcmd_mv },
519 {"mkdir", "Make directory", usrcmd_mkdir},
520 {"hexdump", "Hex dump", usrcmd_hexdump},
[433]521 {"date", "print date and time", usrcmd_date},
[441]522#ifndef NTSHELL_NO_SOCKET
523 {"ping", "ping", usrcmd_ping},
524 {"dhcpc", "DHCP Client rel/renew/info", usrcmd_dhcp4c},
525 {"dnsc", "DNS client", usrcmd_dnsc },
526 {"ntpc", "NTP client", usrcmd_ntpc },
527#endif
[331]528 {"info", "This is a description text string for info command.", usrcmd_info},
[332]529 {"exit", "Exit Natural Tiny Shell", usrcmd_exit},
[446]530 {"help", "This is a description text string for help command.", usrcmd_help},
[331]531};
[446]532const cmd_table_info_t cmd_table_info = { cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
533cmd_table_info_t elf_cmd_table_info;
[331]534
535static int usrcmd_ntopt_callback(long *args, void *extobj)
536{
537 const cmd_table_t *p = cmd_table_info.table;
[432]538 int result = 0;
539 int found = 0;
540
541 if (*args == 0)
542 return result;
543
[442]544 if (strcmp((const char *)args[1], "help") == 0) {
[446]545 found = 1;
[441]546 result = usrcmd_help(args[0], (char **)&args[1]);
[331]547 }
548 else for (int i = 0; i < cmd_table_info.count; i++) {
[442]549 if (strcmp((const char *)args[1], p->cmd) == 0) {
[441]550 found = 1;
551 result = p->func(args[0], (char **)&args[1]);
552 break;
[331]553 }
554 p++;
555 }
[441]556
557 if ((found == 0) && setjmp(shellcmd_exit) == 0) {
[443]558 const Elf32_Ehdr *elf = load_elf((const uint8_t *)0x18200000);
559 if (elf != NULL) {
560 found = 1;
561 execute_elf(elf, args);
562 }
[279]563 }
[441]564
565 if ((found == 0) && (((const char *)args[1])[0] != '\0'))
[442]566 printf("Unknown command found. %s \n", (const char *)args[1]);
[441]567
568 return result;
[279]569}
570
[331]571int usrcmd_help(int argc, char **argv)
572{
[446]573 const cmd_table_t *p, *q;
574 const Elf32_Ehdr *elf = load_elf((const uint8_t *)0x18200000);
575 if (elf != NULL) {
576 read_cmdlist_from_elf(elf);
[331]577 }
[446]578 else {
579 elf_cmd_table_info.count = 0;
580 }
581 p = cmd_table_info.table;
582 for (int i = 0; i < cmd_table_info.count - 3; i++, p++) {
583 printf("%s\t:%s\n", p->cmd, p->desc);
584 }
585 p = elf_cmd_table_info.table;
586 for (int i = 0; i < elf_cmd_table_info.count; i++, p++) {
587 printf("%s\t:%s\n", p->cmd, p->desc);
588 }
589 p = &cmd_table_info.table[cmd_table_info.count - 3];
590 for (int i = cmd_table_info.count - 3; i < cmd_table_info.count; i++, p++) {
591 printf("%s\t:%s\n", p->cmd, p->desc);
592 }
[331]593 return 0;
594}
595
[279]596void shellif_into()
597{
598 /* メインタスクの優先度より高くする */
[431]599 chg_pri(SHELLCMD_PRIORITY, MAIN_PRIORITY + 1);
[279]600}
601
602void shellif_outof()
603{
[431]604 /* shellcmdタスクの優先度に戻す */
605 chg_pri(SHELLCMD_PRIORITY, SHELLCMD_PRIORITY);
[279]606}
607
[441]608int execute_command(struct main_obj_t *obj, int wait)
[279]609{
[441]610 T_RTSK rtsk;
[279]611 ER ret;
612
[431]613 ret = ter_tsk(SHELLCMD_TASK);
[279]614 if ((ret != E_OK) && (ret != E_OBJ)) {
615 syslog(LOG_ERROR, "ter_tsk => %d", ret);
616 }
617
[441]618 if (ret == E_OK)
619 tslp_tsk(100000);
[279]620
621 clean_fd();
622
[431]623 shellcmd_state = 0;
624 ret = act_tsk(SHELLCMD_TASK);
[279]625 if (ret != E_OK) {
626 syslog(LOG_ERROR, "act_tsk => %d", ret);
627 }
628
629 if (wait == 0)
630 return 0;
631
632 do {
[441]633 obj->state = main_state_servey_cmd;
634 obj->timer = 100000;
635
636 char c;
637 if (obj->ntshell.func_read(&c, sizeof(c), obj->ntshell.extobj) == 1) {
638 // Ctrl+Cが押された場合
639 if (c == 0x03) {
640 // コマンドタスクを終了
641 ret = ter_tsk(SHELLCMD_TASK);
642 if (ret != E_OK) {
643 syslog(LOG_ERROR, "ter_tsk => %d", ret);
644 }
645 shellcmd_exit_code = -1;
646 shellcmd_state = 4;
647 if (ret == E_OK)
648 tslp_tsk(100000);
649 break;
650 }
651
652 stdio_input(c);
653 }
654
655 ret = ref_tsk(SHELLCMD_TASK, &rtsk);
656 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
657 shellcmd_state = 3;
[431]658 } while(shellcmd_state == 1);
[279]659
[441]660 obj->state = main_state_idle;
661 obj->timer = TMO_FEVR;
662
663 clean_fd();
664
[431]665 return shellcmd_exit_code;
[279]666}
667
[443]668const Elf32_Ehdr *load_elf(const uint8_t *file)
669{
670 Elf32_Ehdr Ehdr;
671
672 memcpy(&Ehdr, &file[0], sizeof(Elf32_Ehdr));
673
674 // Magic
675 if ((Ehdr.e_ident[EI_MAG0] != ELFMAG0)
676 || (Ehdr.e_ident[EI_MAG1] != ELFMAG1)
677 || (Ehdr.e_ident[EI_MAG2] != ELFMAG2)
678 || (Ehdr.e_ident[EI_MAG3] != ELFMAG3))
679 return NULL;
680
681 // Class
682 if (Ehdr.e_ident[EI_CLASS] != ELFCLASS32)
683 return NULL;
684
685 // Byte order
686 if (Ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
687 return NULL;
688
689 // ELF Version
690 if (Ehdr.e_ident[EI_VERSION] != EV_CURRENT)
691 return NULL;
692
693 // type
694 if (Ehdr.e_type != ET_EXEC)
695 return NULL;
696
697 // Machine
698 if (Ehdr.e_machine != EM_ARM)
699 return NULL;
700
701 if (Ehdr.e_version != EV_CURRENT)
702 return NULL;
703
704 return (const Elf32_Ehdr *)file;
705}
706
707void execute_elf(const Elf32_Ehdr *Ehdr, long *args)
708{
709 const uint8_t *file = (const uint8_t *)Ehdr;
710 Elf32_Shdr StringShdr;
711 memcpy(&StringShdr, &file[Ehdr->e_shoff + (Ehdr->e_shstrndx * Ehdr->e_shentsize)], sizeof(StringShdr));
712
713 if (Ehdr->e_shoff > 0) {
714 Elf32_Shdr Shdr;
715 for (int i = 0; i < Ehdr->e_shnum; i++) {
716 memcpy(&Shdr, (Elf32_Shdr *)&file[Ehdr->e_shoff + (i * Ehdr->e_shentsize)], sizeof(Elf32_Shdr));
717 Shdr.sh_size -= Shdr.sh_addr;
718
719 if ((Shdr.sh_flags & SHF_ALLOC) == 0) {
720 // skip
721 }
722 else if (Shdr.sh_type == SHT_PROGBITS) {
723 if ((Shdr.sh_flags & SHF_WRITE) == 0) {
724 // inplace
725 }
726 else {
727 memcpy(Shdr.sh_addr, Shdr.sh_offset, Shdr.sh_size);
728 }
729 }
730 else if (Shdr.sh_type == SHT_NOBITS) {
731 memset(Shdr.sh_addr, 0, Shdr.sh_size);
732 }
733 else {
734 // skip
735 }
736 }
737 }
738
739 ((elf_entry_t)Ehdr->e_entry)(args);
740}
[446]741
742void read_cmdlist_from_elf(const Elf32_Ehdr *Ehdr)
743{
744 const uint8_t *file = (const uint8_t *)Ehdr;
745 Elf32_Shdr StringShdr;
746 memcpy(&StringShdr, &file[Ehdr->e_shoff + (Ehdr->e_shstrndx * Ehdr->e_shentsize)], sizeof(StringShdr));
747
748 if (Ehdr->e_shoff > 0) {
749 Elf32_Shdr Shdr;
750 for (int i = 0; i < Ehdr->e_shnum; i++) {
751 memcpy(&Shdr, (Elf32_Shdr *)&file[Ehdr->e_shoff + (i * Ehdr->e_shentsize)], sizeof(Elf32_Shdr));
752 Shdr.sh_size -= Shdr.sh_addr;
753
754 char *name;
755 if (Shdr.sh_name > 0) {
756 name = (char *)&file[StringShdr.sh_offset + Shdr.sh_name];
757 }
758 else {
759 name = NULL;
760 }
761
762 if ((name != NULL) && (strcmp(name, ".cmdlist") == 0)) {
763 elf_cmd_table_info.table = (const cmd_table_t *)Shdr.sh_addr;
764 elf_cmd_table_info.count = Shdr.sh_size / sizeof(cmd_table_t);
765 }
766 }
767 }
768}
Note: See TracBrowser for help on using the repository browser.