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

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

DHCPの機能はありで、固定IPにする設定を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 18.0 KB
Line 
1/*
2 * TOPPERS PROJECT Home Network Working Group Software
3 *
4 * Copyright (C) 2014-2019 Cores Co., Ltd. Japan
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>
45#include <setjmp.h>
46#include <string.h>
47#include "syssvc/serial.h"
48#include "syssvc/syslog.h"
49#include "target_syssvc.h"
50#include "kernel_cfg.h"
51#include "main.h"
52#include "mbed_retarget.h"
53#include "fdtable.h"
54#ifndef NTSHELL_NO_SOCKET
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"
69#include "core/ntshell.h"
70#include "core/ntlibc.h"
71#include "usrcmd.h"
72#include "util/ntopt.h"
73#include "netapp/dhcp4_cli.h"
74#include "ntp_cli.h"
75#include "netcmd.h"
76#endif
77#include "../musl-1.1.18/include/elf.h"
78
79ID ws_api_mailboxid = MAIN_DATAQUEUE;
80ID ws_mempoolid = MPF_NET_BUF_256;
81
82char command[NTOPT_TEXT_MAXLEN];
83
84const uint8_t mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
85
86enum main_state_t {
87 main_state_start,
88 main_state_idle,
89#ifndef NTSHELL_NO_SOCKET
90 main_state_start_dhcp,
91#endif
92 main_state_servey_cmd,
93};
94
95struct main_obj_t {
96 ntshell_t ntshell;
97 int timer;
98 enum main_state_t state;
99 SYSTIM prev, now;
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;
112};
113struct main_obj_t main_obj;
114
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
119static void main_initialize(struct main_obj_t *obj);
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);
125static const Elf32_Ehdr *load_elf(const uint8_t *file);
126static void execute_elf(const Elf32_Ehdr *, long *args);
127static void read_cmdlist_from_elf(const Elf32_Ehdr *Ehdr);
128static int usrcmd_ntopt_callback(long *args, void *extobj);
129#ifndef NTSHELL_NO_SOCKET
130static void ntp_cli_state_changed(ntp_cli_state_t state);
131#endif
132
133void stdio_open(ID portid);
134void stdio_input(unsigned char c);
135
136bool_t dhcp_enable;
137int ntshell_exit;
138int shellcmd_exit_code;
139volatile int shellcmd_state;
140typedef void (*elf_entry_t)(long *args);
141jmp_buf shellcmd_exit;
142
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
149int uart_read(char *buf, int cnt, void *extobj)
150{
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;
200}
201
202int uart_write(const char *buf, int cnt, void *extobj)
203{
204 return serial_wri_dat(SIO_PORTID, buf, cnt);
205}
206
207int cmd_execute(const char *text, void *extobj)
208{
209 if (text != NULL) {
210 strlcpy(command, text, sizeof(command));
211 }
212 ER ret;
213 ID tskid = 0;
214
215 ret = get_tid(&tskid);
216 if (ret != E_OK) {
217 syslog(LOG_ERROR, "get_tid %d", ret);
218 }
219
220 return execute_command(&main_obj, tskid == MAIN_TASK);
221}
222
223gpio_t led_blue, led_green, led_red, sw;
224
225/*
226 * メインタスク
227 */
228void main_task(intptr_t exinf)
229{
230 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
231
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
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);
259
260 main_finalize(obj);
261}
262
263/*
264 * 初期化
265 */
266static void main_initialize(struct main_obj_t *obj)
267{
268 ER ret;
269 ID tskid = 0;
270
271 ret = get_tid(&tskid);
272 if (ret != E_OK) {
273 syslog(LOG_ERROR, "get_tid %d", ret);
274 return;
275 }
276
277 obj->timer = 100000;
278 obj->state = main_state_start;
279
280 for (int i = 0; i < obj->task_count; i++) {
281 task_base_t *task = obj->tasks[i];
282 task->on_start(task, tskid);
283 }
284
285 gpio_write(&led_blue, 0);
286 gpio_write(&led_green, 0);
287
288 act_tsk(HTTPD1_TASK);
289 act_tsk(HTTPD2_TASK);
290
291 ret = get_tim(&obj->now);
292 if (ret != E_OK) {
293 syslog(LOG_ERROR, "get_tim");
294 ext_tsk();
295 return;
296 }
297}
298
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
307/*
308 * タイマー取得
309 */
310static int main_get_timer(struct main_obj_t *obj)
311{
312 int timer = obj->timer;
313
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
321 return timer;
322}
323
324/*
325 * 時間経過
326 */
327static void main_progress(struct main_obj_t *obj, int elapse)
328{
329 if (obj->timer != TMO_FEVR) {
330 obj->timer -= elapse;
331 if (obj->timer < 0) {
332 obj->timer = 0;
333 }
334 }
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 }
340}
341
342/*
343 * タイムアウト処理
344 */
345static void main_timeout(struct main_obj_t *obj, bool_t wakeup)
346{
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
358 if (!dhcp_enable) {
359 dhcp4c_rel_info();
360 in4_add_ifaddr(IPV4_ADDR_STAIC_LOCAL, IPV4_ADDR_STAIC_LOCAL_MASK);
361 }
362#endif
363 {
364 FILINFO fno;
365#if FF_USE_LFN
366 char lfn[FF_MAX_LFN + 1];
367 fno.lfname = lfn;
368 fno.lfsize = FF_MAX_LFN + 1;
369#endif
370 if (f_stat("1:/upload/main.mrb", &fno) != FR_OK) {
371 obj->exec = false;
372 }
373
374 if (obj->exec) {
375 cmd_execute("mruby -b 1:/upload/main.mrb", obj);
376 }
377 }
378 obj->state = main_state_idle;
379 obj->timer = TMO_FEVR;
380 break;
381#ifndef NTSHELL_NO_SOCKET
382 case main_state_start_dhcp:
383 ret = dhcp4c_renew_info();
384 if (ret == E_OK) {
385 obj->state = main_state_idle;
386 obj->timer = TMO_FEVR;
387 }
388 else {
389 obj->state = main_state_start_dhcp;
390 obj->timer = 1000000;
391 }
392 break;
393#endif
394 default:
395 obj->state = main_state_idle;
396 obj->timer = TMO_FEVR;
397 break;
398 }
399#ifndef NTSHELL_NO_SOCKET
400 if (obj->link) {
401 obj->link = 0;
402 event |= MAIN_EVENT_NETIF_CHANGED;
403 if (obj->link_up)
404 event |= MAIN_EVENT_LINK_UP;
405 if (obj->up)
406 event |= MAIN_EVENT_UP;
407
408 if (obj->link_up && obj->up)
409 ntp_cli_execute();
410
411 main_change_netif_link(obj->link_up, obj->up);
412 }
413 if (obj->ntp) {
414 obj->ntp = 0;
415 if (obj->ntp_state != NTP_CLI_STATE_SYNC)
416 event |= MAIN_EVENT_NTP_ASYNC;
417 else
418 event |= MAIN_EVENT_NTP_SYNC;
419 }
420#endif
421 for (int i = 0; i < obj->task_count; i++) {
422 task_base_t *task = obj->tasks[i];
423 task->process(task, event);
424 }
425}
426
427#ifndef NTSHELL_NO_SOCKET
428/* MACアドレスの設定時に呼ばれる */
429void mbed_mac_address(char *mac)
430{
431 memcpy(mac, mac_addr, 6);
432}
433
434void main_change_netif_link(uint8_t link_up, uint8_t up)
435{
436 FLGPTN flgptn;
437 T_RTSK rtsk;
438 ER ret;
439
440 ret = ref_tsk(SHELLCMD_TASK, &rtsk);
441 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
442 return;
443
444 FD_SET(0, (fd_set *)&flgptn);
445
446 set_flg(FLG_SELECT_WAIT, flgptn);
447}
448
449void netif_link_callback(T_IFNET *ether)
450{
451 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
452 uint8_t link_up = (ether->flags & IF_FLAG_LINK_UP) != 0;
453 uint8_t up = (ether->flags & IF_FLAG_UP) != 0;
454 bool_t wake = false;
455
456 if (dhcp_enable) {
457 if (!link_up)
458 dhcp4c_rel_info();
459 else if (!up) {
460 wake = dhcp4c_renew_info() != E_OK;
461 if (wake) {
462 obj->dhcp = 1;
463 }
464 }
465 }
466 else {
467 up = link_up;
468 }
469
470 if ((obj->link_up != link_up) || (obj->up != up)) {
471 obj->link = 1;
472 wake = true;
473 }
474
475 obj->link_up = link_up;
476 obj->up = up;
477
478 if (wake && (obj->event_req == obj->event_res)) {
479 obj->event_req++;
480 rel_wai(MAIN_TASK);
481 }
482}
483
484void ntp_cli_state_changed(ntp_cli_state_t state)
485{
486 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
487 bool_t wake = obj->ntp_state != state;
488
489 if (wake) {
490 obj->ntp_state = state;
491 obj->ntp = 1;
492
493 if (obj->event_req == obj->event_res) {
494 obj->event_req++;
495 rel_wai(MAIN_TASK);
496 }
497 }
498}
499#endif
500
501/*
502 * shellcmdタスク
503 */
504void shellcmd_task(intptr_t exinf)
505{
506 shellcmd_state = 1;
507
508 if (setjmp(shellcmd_exit) == 0) {
509 shellcmd_exit_code = ntopt_parse(command, usrcmd_ntopt_callback, NULL);
510 }
511
512 //fflush(stdout);
513 clean_fd();
514
515 shellcmd_state = 2;
516}
517
518static const cmd_table_t cmdlist[] = {
519 {"cd", "change directory", usrcmd_cd },
520 {"ls", "list files", usrcmd_ls },
521 {"cp", "copy file", usrcmd_cp },
522 {"rm", "remove file", usrcmd_rm },
523 {"mv", "move file", usrcmd_mv },
524 {"mkdir", "Make directory", usrcmd_mkdir},
525 {"hexdump", "Hex dump", usrcmd_hexdump},
526 {"date", "print date and time", usrcmd_date},
527#ifndef NTSHELL_NO_SOCKET
528 {"ping", "ping", usrcmd_ping},
529 {"dhcpc", "DHCP Client rel/renew/info", usrcmd_dhcp4c},
530 {"dnsc", "DNS client", usrcmd_dnsc },
531 {"ntpc", "NTP client", usrcmd_ntpc },
532#endif
533 {"info", "This is a description text string for info command.", usrcmd_info},
534 {"exit", "Exit Natural Tiny Shell", usrcmd_exit},
535 {"help", "This is a description text string for help command.", usrcmd_help},
536};
537const cmd_table_info_t cmd_table_info = { cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
538cmd_table_info_t elf_cmd_table_info;
539
540static int usrcmd_ntopt_callback(long *args, void *extobj)
541{
542 const cmd_table_t *p = cmd_table_info.table;
543 int result = 0;
544 int found = 0;
545
546 if (*args == 0)
547 return result;
548
549 if (strcmp((const char *)args[1], "help") == 0) {
550 found = 1;
551 result = usrcmd_help(args[0], (char **)&args[1]);
552 }
553 else for (int i = 0; i < cmd_table_info.count; i++) {
554 if (strcmp((const char *)args[1], p->cmd) == 0) {
555 found = 1;
556 result = p->func(args[0], (char **)&args[1]);
557 break;
558 }
559 p++;
560 }
561
562 if ((found == 0) && setjmp(shellcmd_exit) == 0) {
563 const Elf32_Ehdr *elf = load_elf((const uint8_t *)0x18200000);
564 if (elf != NULL) {
565 found = 1;
566 execute_elf(elf, args);
567 }
568 }
569
570 if ((found == 0) && (((const char *)args[1])[0] != '\0'))
571 printf("Unknown command found. %s \n", (const char *)args[1]);
572
573 return result;
574}
575
576int usrcmd_help(int argc, char **argv)
577{
578 const cmd_table_t *p, *q;
579 const Elf32_Ehdr *elf = load_elf((const uint8_t *)0x18200000);
580 if (elf != NULL) {
581 read_cmdlist_from_elf(elf);
582 }
583 else {
584 elf_cmd_table_info.count = 0;
585 }
586 p = cmd_table_info.table;
587 for (int i = 0; i < cmd_table_info.count - 3; i++, p++) {
588 printf("%s\t:%s\n", p->cmd, p->desc);
589 }
590 p = elf_cmd_table_info.table;
591 for (int i = 0; i < elf_cmd_table_info.count; i++, p++) {
592 printf("%s\t:%s\n", p->cmd, p->desc);
593 }
594 p = &cmd_table_info.table[cmd_table_info.count - 3];
595 for (int i = cmd_table_info.count - 3; i < cmd_table_info.count; i++, p++) {
596 printf("%s\t:%s\n", p->cmd, p->desc);
597 }
598 return 0;
599}
600
601void shellif_into()
602{
603 /* メインタスクの優先度より高くする */
604 chg_pri(SHELLCMD_PRIORITY, MAIN_PRIORITY + 1);
605}
606
607void shellif_outof()
608{
609 /* shellcmdタスクの優先度に戻す */
610 chg_pri(SHELLCMD_PRIORITY, SHELLCMD_PRIORITY);
611}
612
613int execute_command(struct main_obj_t *obj, int wait)
614{
615 T_RTSK rtsk;
616 ER ret;
617
618 ret = ter_tsk(SHELLCMD_TASK);
619 if ((ret != E_OK) && (ret != E_OBJ)) {
620 syslog(LOG_ERROR, "ter_tsk => %d", ret);
621 }
622
623 if (ret == E_OK)
624 tslp_tsk(100000);
625
626 clean_fd();
627
628 shellcmd_state = 0;
629 ret = act_tsk(SHELLCMD_TASK);
630 if (ret != E_OK) {
631 syslog(LOG_ERROR, "act_tsk => %d", ret);
632 }
633
634 if (wait == 0)
635 return 0;
636
637 do {
638 obj->state = main_state_servey_cmd;
639 obj->timer = 100000;
640
641 char c;
642 if (obj->ntshell.func_read(&c, sizeof(c), obj->ntshell.extobj) == 1) {
643 // Ctrl+Cが押された場合
644 if (c == 0x03) {
645 // コマンドタスクを終了
646 ret = ter_tsk(SHELLCMD_TASK);
647 if (ret != E_OK) {
648 syslog(LOG_ERROR, "ter_tsk => %d", ret);
649 }
650 shellcmd_exit_code = -1;
651 shellcmd_state = 4;
652 if (ret == E_OK)
653 tslp_tsk(100000);
654 break;
655 }
656
657 stdio_input(c);
658 }
659
660 ret = ref_tsk(SHELLCMD_TASK, &rtsk);
661 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
662 shellcmd_state = 3;
663 } while(shellcmd_state == 1);
664
665 obj->state = main_state_idle;
666 obj->timer = TMO_FEVR;
667
668 clean_fd();
669
670 return shellcmd_exit_code;
671}
672
673const Elf32_Ehdr *load_elf(const uint8_t *file)
674{
675 Elf32_Ehdr Ehdr;
676
677 memcpy(&Ehdr, &file[0], sizeof(Elf32_Ehdr));
678
679 // Magic
680 if ((Ehdr.e_ident[EI_MAG0] != ELFMAG0)
681 || (Ehdr.e_ident[EI_MAG1] != ELFMAG1)
682 || (Ehdr.e_ident[EI_MAG2] != ELFMAG2)
683 || (Ehdr.e_ident[EI_MAG3] != ELFMAG3))
684 return NULL;
685
686 // Class
687 if (Ehdr.e_ident[EI_CLASS] != ELFCLASS32)
688 return NULL;
689
690 // Byte order
691 if (Ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
692 return NULL;
693
694 // ELF Version
695 if (Ehdr.e_ident[EI_VERSION] != EV_CURRENT)
696 return NULL;
697
698 // type
699 if (Ehdr.e_type != ET_EXEC)
700 return NULL;
701
702 // Machine
703 if (Ehdr.e_machine != EM_ARM)
704 return NULL;
705
706 if (Ehdr.e_version != EV_CURRENT)
707 return NULL;
708
709 return (const Elf32_Ehdr *)file;
710}
711
712void execute_elf(const Elf32_Ehdr *Ehdr, long *args)
713{
714 const uint8_t *file = (const uint8_t *)Ehdr;
715 Elf32_Shdr StringShdr;
716 memcpy(&StringShdr, &file[Ehdr->e_shoff + (Ehdr->e_shstrndx * Ehdr->e_shentsize)], sizeof(StringShdr));
717
718 if (Ehdr->e_shoff > 0) {
719 Elf32_Shdr Shdr;
720 for (int i = 0; i < Ehdr->e_shnum; i++) {
721 memcpy(&Shdr, (Elf32_Shdr *)&file[Ehdr->e_shoff + (i * Ehdr->e_shentsize)], sizeof(Elf32_Shdr));
722 Shdr.sh_size -= Shdr.sh_addr;
723
724 if ((Shdr.sh_flags & SHF_ALLOC) == 0) {
725 // skip
726 }
727 else if (Shdr.sh_type == SHT_PROGBITS) {
728 if ((Shdr.sh_flags & SHF_WRITE) == 0) {
729 // inplace
730 }
731 else {
732 memcpy(Shdr.sh_addr, Shdr.sh_offset, Shdr.sh_size);
733 }
734 }
735 else if (Shdr.sh_type == SHT_NOBITS) {
736 memset(Shdr.sh_addr, 0, Shdr.sh_size);
737 }
738 else {
739 // skip
740 }
741 }
742 }
743
744 ((elf_entry_t)Ehdr->e_entry)(args);
745}
746
747void read_cmdlist_from_elf(const Elf32_Ehdr *Ehdr)
748{
749 const uint8_t *file = (const uint8_t *)Ehdr;
750 Elf32_Shdr StringShdr;
751 memcpy(&StringShdr, &file[Ehdr->e_shoff + (Ehdr->e_shstrndx * Ehdr->e_shentsize)], sizeof(StringShdr));
752
753 if (Ehdr->e_shoff > 0) {
754 Elf32_Shdr Shdr;
755 for (int i = 0; i < Ehdr->e_shnum; i++) {
756 memcpy(&Shdr, (Elf32_Shdr *)&file[Ehdr->e_shoff + (i * Ehdr->e_shentsize)], sizeof(Elf32_Shdr));
757 Shdr.sh_size -= Shdr.sh_addr;
758
759 char *name;
760 if (Shdr.sh_name > 0) {
761 name = (char *)&file[StringShdr.sh_offset + Shdr.sh_name];
762 }
763 else {
764 name = NULL;
765 }
766
767 if ((name != NULL) && (strcmp(name, ".cmdlist") == 0)) {
768 elf_cmd_table_info.table = (const cmd_table_t *)Shdr.sh_addr;
769 elf_cmd_table_info.count = Shdr.sh_size / sizeof(cmd_table_t);
770 }
771 }
772 }
773}
Note: See TracBrowser for help on using the repository browser.