Index: EcnlProtoTool/trunk/ntshell/src/main.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/main.c	(revision 442)
+++ EcnlProtoTool/trunk/ntshell/src/main.c	(revision 443)
@@ -75,4 +75,5 @@
 #include "netcmd.h"
 #endif
+#include "../musl-1.1.18/include/elf.h"
 
 ID ws_api_mailboxid = MAIN_DATAQUEUE;
@@ -122,4 +123,6 @@
 static void main_timeout(struct main_obj_t *obj, bool_t wakeup);
 static int execute_command(struct main_obj_t *obj, int wait);
+static const Elf32_Ehdr *load_elf(const uint8_t *file);
+static void execute_elf(const Elf32_Ehdr *, long *args);
 static int usrcmd_ntopt_callback(long *args, void *extobj);
 #ifndef NTSHELL_NO_SOCKET
@@ -134,5 +137,5 @@
 int shellcmd_exit_code;
 volatile int shellcmd_state;
-typedef void (*PowerOn_Reset_t)(long *args);
+typedef void (*elf_entry_t)(long *args);
 jmp_buf shellcmd_exit;
 
@@ -549,6 +552,9 @@
 
 	if ((found == 0) && setjmp(shellcmd_exit) == 0) {
-		found = 1;
-		(*((PowerOn_Reset_t *)0x18200000))(args);
+		const Elf32_Ehdr *elf = load_elf((const uint8_t *)0x18200000);
+		if (elf != NULL) {
+			found = 1;
+			execute_elf(elf, args);
+		}
 	}
 
@@ -643,2 +649,83 @@
 }
 
+const Elf32_Ehdr *load_elf(const uint8_t *file)
+{
+	Elf32_Ehdr Ehdr;
+
+	memcpy(&Ehdr, &file[0], sizeof(Elf32_Ehdr));
+
+	// Magic
+	if ((Ehdr.e_ident[EI_MAG0] != ELFMAG0)
+		|| (Ehdr.e_ident[EI_MAG1] != ELFMAG1)
+		|| (Ehdr.e_ident[EI_MAG2] != ELFMAG2)
+		|| (Ehdr.e_ident[EI_MAG3] != ELFMAG3))
+		return NULL;
+
+	// Class
+	if (Ehdr.e_ident[EI_CLASS] != ELFCLASS32)
+		return NULL;
+
+	// Byte order
+	if (Ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
+		return NULL;
+
+	// ELF Version
+	if (Ehdr.e_ident[EI_VERSION] != EV_CURRENT)
+		return NULL;
+
+	// type
+	if (Ehdr.e_type != ET_EXEC)
+		return NULL;
+
+	// Machine
+	if (Ehdr.e_machine != EM_ARM)
+		return NULL;
+
+	if (Ehdr.e_version != EV_CURRENT)
+		return NULL;
+
+	return (const Elf32_Ehdr *)file;
+}
+
+void execute_elf(const Elf32_Ehdr *Ehdr, long *args)
+{
+	const uint8_t *file = (const uint8_t *)Ehdr;
+	Elf32_Shdr StringShdr;
+	memcpy(&StringShdr, &file[Ehdr->e_shoff + (Ehdr->e_shstrndx * Ehdr->e_shentsize)], sizeof(StringShdr));
+
+	if (Ehdr->e_shoff > 0) {
+		Elf32_Shdr Shdr;
+		for (int i = 0; i < Ehdr->e_shnum; i++) {
+			memcpy(&Shdr, (Elf32_Shdr *)&file[Ehdr->e_shoff + (i * Ehdr->e_shentsize)], sizeof(Elf32_Shdr));
+			Shdr.sh_size -= Shdr.sh_addr;
+
+			char *name;
+			if (Shdr.sh_name > 0) {
+				name = (char *)&file[StringShdr.sh_offset + Shdr.sh_name];
+			}
+			else {
+				name = NULL;
+			}
+
+			if ((Shdr.sh_flags & SHF_ALLOC) == 0) {
+				// skip
+			}
+			else if (Shdr.sh_type == SHT_PROGBITS) {
+				if ((Shdr.sh_flags & SHF_WRITE) == 0) {
+					// inplace
+				}
+				else {
+					memcpy(Shdr.sh_addr, Shdr.sh_offset, Shdr.sh_size);
+				}
+			}
+			else if (Shdr.sh_type == SHT_NOBITS) {
+				memset(Shdr.sh_addr, 0, Shdr.sh_size);
+			}
+			else {
+				// skip
+			}
+		}
+	}
+
+	((elf_entry_t)Ehdr->e_entry)(args);
+}
Index: EcnlProtoTool/trunk/ntshell/src/main.cfg
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/main.cfg	(revision 442)
+++ EcnlProtoTool/trunk/ntshell/src/main.cfg	(revision 443)
@@ -80,5 +80,5 @@
 CRE_DTQ(MAIN_DATAQUEUE, { TA_TFIFO, NUM_MAIN_DATAQUEUE, NULL });
 
-CRE_TSK(SHELLCMD_TASK, { TA_FPU, 0, shellcmd_task, SHELLCMD_PRIORITY, SHELLCMD_STACK_SIZE, (void *)0x20100000 });
+CRE_TSK(SHELLCMD_TASK, { TA_FPU, 0, shellcmd_task, SHELLCMD_PRIORITY, SHELLCMD_STACK_SIZE, SHELLCMD_STACK_ADDR });
 CRE_FLG(FLG_SELECT_WAIT, { TA_WMUL, 0x00 });
 CRE_SEM(SEM_FILEDESC, { TA_TPRI, 1, 1 });
Index: EcnlProtoTool/trunk/ntshell/src/main.h
===================================================================
--- EcnlProtoTool/trunk/ntshell/src/main.h	(revision 442)
+++ EcnlProtoTool/trunk/ntshell/src/main.h	(revision 443)
@@ -60,4 +60,5 @@
 #define MAIN_STACK_SIZE	2048		/* メインタスクのスタック領域のサイズ */
 #define SHELLCMD_STACK_SIZE	0x00800000	/* shellcmdタスクのスタック領域のサイズ */
+#define SHELLCMD_STACK_ADDR	((void *)&__CmdBase)
 
 #define NUM_MAIN_DATAQUEUE	1		/* メインタスクで待ち受けているデータキューのサイズ */
@@ -68,4 +69,7 @@
  */
 #ifndef TOPPERS_MACRO_ONLY
+
+extern uint8_t __CmdBase;
+extern uint8_t __CmdLimit;
 
 typedef struct task_base_t {
Index: EcnlProtoTool/trunk/prototool/src/elf.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/elf.c	(revision 443)
+++ EcnlProtoTool/trunk/prototool/src/elf.c	(revision 443)
@@ -0,0 +1,169 @@
+/*
+ *  TOPPERS PROJECT Home Network Working Group Software
+ *
+ *  Copyright (C) 2020 Cores Co., Ltd. Japan
+ *
+ *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
+ *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
+ *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
+ *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
+ *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
+ *      スコード中に含まれていること．
+ *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
+ *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
+ *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
+ *      の無保証規定を掲載すること．
+ *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
+ *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
+ *      と．
+ *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
+ *        作権表示，この利用条件および下記の無保証規定を掲載すること．
+ *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
+ *        報告すること．
+ *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
+ *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
+ *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
+ *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
+ *      免責すること．
+ *
+ *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
+ *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
+ *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
+ *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
+ *  の責任を負わない．
+ *
+ *  @(#) $Id$
+ */
+
+#include <string.h>
+#include <elf.h>
+
+#define FVECT_SECT          __attribute__ ((section (".proginf")))
+
+void _start_c(long *args);
+extern int __start_text, __end_text;
+extern int __start_rodata, __end_rodata;
+extern int __start_data, __end_data, __start_idata;
+extern int __start_bss, __end_bss;
+
+typedef struct TProgInf {
+	Elf32_Ehdr ehdr;
+	Elf32_Phdr phdr[3];
+	Elf32_Shdr shdr[4];
+	Elf32_Shdr str_shdr;
+	char shstrtab[sizeof("\0.text\0.rodata\0.data\0.bss\0.shstrtab")];
+} TProgInf;
+
+const TProgInf ProgInf FVECT_SECT = {
+	{
+		.e_ident = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS32, ELFDATA2LSB, EV_CURRENT },
+		.e_type = ET_EXEC,
+		.e_machine = EM_ARM,
+		.e_version = EV_CURRENT,
+		.e_entry = (Elf32_Addr)&_start_c,
+		.e_phoff = (Elf32_Off)&((TProgInf *)0)->phdr,
+		.e_shoff = (Elf32_Off)&((TProgInf *)0)->shdr,
+		.e_flags = (Elf32_Word)(EF_ARM_EABI_VER5 | NT_ARM_VFP),
+		.e_ehsize = (Elf32_Half)sizeof(Elf32_Ehdr),
+		.e_phentsize = (Elf32_Half)sizeof(Elf32_Phdr),
+		.e_phnum = (Elf32_Half)(sizeof(ProgInf.phdr) / sizeof(Elf32_Phdr)),
+		.e_shentsize = (Elf32_Half)sizeof(Elf32_Shdr),
+		.e_shnum = (Elf32_Half)(sizeof(ProgInf.shdr) / sizeof(Elf32_Shdr)) + 1,
+		.e_shstrndx = (Elf32_Half)(sizeof(ProgInf.shdr) / sizeof(Elf32_Shdr)),
+	},
+	{
+		{
+			.p_type = (Elf32_Word)PT_LOAD,
+			.p_offset = (Elf32_Off)&((TProgInf *)0)->phdr[0],
+			.p_vaddr = (Elf32_Addr)&__start_text,
+			.p_paddr = (Elf32_Addr)&__start_text,
+			.p_filesz = (Elf32_Word)&__end_text/* - (Elf32_Addr)&__start_text*/,
+			.p_memsz = (Elf32_Word)&__end_text/* - (Elf32_Addr)&__start_text*/,
+			.p_flags = (Elf32_Word)(PF_X | PF_R),
+			.p_align = (Elf32_Word)8,
+		},
+		{
+			.p_type = (Elf32_Word)PT_LOAD,
+			.p_offset = (Elf32_Off)&((TProgInf *)0)->phdr[1],
+			.p_vaddr = (Elf32_Addr)&__start_rodata,
+			.p_paddr = (Elf32_Addr)&__start_rodata,
+			.p_filesz = (Elf32_Word)&__end_rodata/* - (Elf32_Addr)&__start_rodata*/,
+			.p_memsz = (Elf32_Word)&__end_rodata/* - (Elf32_Addr)&__start_rodata*/,
+			.p_flags = (Elf32_Word)(PF_R),
+			.p_align = (Elf32_Word)8,
+		},
+		{
+			.p_type = (Elf32_Word)PT_LOAD,
+			.p_offset = (Elf32_Off)&((TProgInf *)0)->phdr[2],
+			.p_vaddr = (Elf32_Addr)&__start_data,
+			.p_paddr = (Elf32_Addr)&__start_idata,
+			.p_filesz = (Elf32_Word)&__end_data/* - (Elf32_Addr)&__start_data*/,
+			.p_memsz = (Elf32_Word)&__end_data/* - (Elf32_Addr)&__start_data*/,
+			.p_flags = (Elf32_Word)(PF_W | PF_R),
+			.p_align = (Elf32_Word)8,
+		}
+	},
+	{
+		{
+			.sh_name = (Elf32_Word)1,
+			.sh_type = (Elf32_Word)SHT_PROGBITS,
+			.sh_flags = (Elf32_Word)(SHF_ALLOC | SHF_EXECINSTR),
+			.sh_addr = (Elf32_Addr)&__start_text,
+			.sh_offset = (Elf32_Off)&__start_text/* - (Elf32_Off)&ProgInf*/,
+			.sh_size = (Elf32_Word)&__end_text/* - (Elf32_Off)&__start_text*/,
+			.sh_link = (Elf32_Word)0,
+			.sh_info = (Elf32_Word)0,
+			.sh_addralign = (Elf32_Word)8,
+			.sh_entsize = (Elf32_Word)0,
+		},
+		{
+			.sh_name = (Elf32_Word)7,
+			.sh_type = (Elf32_Word)SHT_PROGBITS,
+			.sh_flags = (Elf32_Word)(SHF_ALLOC),
+			.sh_addr = (Elf32_Addr)&__start_rodata,
+			.sh_offset = (Elf32_Off)&__start_rodata/* - (Elf32_Off)&ProgInf*/,
+			.sh_size = (Elf32_Word)&__end_rodata/* - (Elf32_Off)&__start_rodata*/,
+			.sh_link = (Elf32_Word)0,
+			.sh_info = (Elf32_Word)0,
+			.sh_addralign = (Elf32_Word)8,
+			.sh_entsize = (Elf32_Word)0,
+		},
+		{
+			.sh_name = (Elf32_Word)15,
+			.sh_type = (Elf32_Word)SHT_PROGBITS,
+			.sh_flags = (Elf32_Word)(SHF_ALLOC | SHF_WRITE),
+			.sh_addr = (Elf32_Addr)&__start_data,
+			.sh_offset = (Elf32_Off)&__start_idata/* - (Elf32_Off)&ProgInf*/,
+			.sh_size = (Elf32_Word)&__end_data/* - (Elf32_Off)&__start_data*/,
+			.sh_link = (Elf32_Word)0,
+			.sh_info = (Elf32_Word)0,
+			.sh_addralign = (Elf32_Word)8,
+			.sh_entsize = (Elf32_Word)0,
+		},
+		{
+			.sh_name = (Elf32_Word)21,
+			.sh_type = (Elf32_Word)SHT_NOBITS,
+			.sh_flags = (Elf32_Word)(SHF_ALLOC | SHF_WRITE),
+			.sh_addr = (Elf32_Addr)&__start_bss,
+			.sh_offset = (Elf32_Off)&__start_bss/* - (Elf32_Off)&ProgInf*/,
+			.sh_size = (Elf32_Word)&__end_bss/* - (Elf32_Off)&__start_bss*/,
+			.sh_link = (Elf32_Word)0,
+			.sh_info = (Elf32_Word)0,
+			.sh_addralign = (Elf32_Word)8,
+			.sh_entsize = (Elf32_Word)0,
+		}
+	},
+	{
+		.sh_name = (Elf32_Word)26,
+		.sh_type = (Elf32_Word)SHT_STRTAB,
+		.sh_flags = (Elf32_Word)0,
+		.sh_addr = (Elf32_Addr)0,
+		.sh_offset = (Elf32_Off)&((TProgInf *)0)->shstrtab,
+		.sh_size = (Elf32_Word)sizeof(ProgInf.shstrtab),
+		.sh_link = (Elf32_Word)0,
+		.sh_info = (Elf32_Word)0,
+		.sh_addralign = (Elf32_Word)1,
+		.sh_entsize = (Elf32_Word)0,
+	},
+	"\0.text\0.rodata\0.data\0.bss\0.shstrtab"
+};
Index: EcnlProtoTool/trunk/prototool/src/linker_scriptDebug.ld
===================================================================
--- EcnlProtoTool/trunk/prototool/src/linker_scriptDebug.ld	(revision 442)
+++ EcnlProtoTool/trunk/prototool/src/linker_scriptDebug.ld	(revision 443)
@@ -22,7 +22,10 @@
 	} > BOOT_LOADER
 
+	.proginf : {
+		KEEP(*(.proginf))
+	} > ROM
+
 	.text : {
 		__start_text = .;
-		KEEP(*(.vector))
 		*(.text*)
 		*(.glue_7t)
@@ -30,5 +33,5 @@
 		KEEP(*(.init))
 		KEEP(*(.fini))
-		__end_kernel = .;
+		__end_text = .;
 	} > ROM
 	_etext = .;
@@ -40,4 +43,5 @@
 		__end_rodata = .;
 	} > ROM
+
 	.preinit_array ALIGN(4) : {
 		PROVIDE_HIDDEN (__preinit_array_start = .);
Index: EcnlProtoTool/trunk/prototool/src/main.c
===================================================================
--- EcnlProtoTool/trunk/prototool/src/main.c	(revision 442)
+++ EcnlProtoTool/trunk/prototool/src/main.c	(revision 443)
@@ -521,20 +521,2 @@
 	return (&__start_rodata <= p && p < &__end_rodata);
 }
-
-void _start_c(long *p);
-extern int __start_idata, __start_data, __end_data;
-extern int __start_bss, __end_bss;
-
-void _PowerON_Reset(long *args)
-{
-	memcpy(&__start_data, &__start_idata, (size_t)&__end_data - (size_t)&__start_data);
-	memset(&__start_bss, 0, (size_t)&__end_bss - (size_t)&__start_bss);
-
-	_start_c(args);
-}
-
-#define FVECT_SECT          __attribute__ ((section (".vector")))
-const void *HardwareVectors[] FVECT_SECT = {
-	_PowerON_Reset,
-	mrdb_break,
-};
