diff --git a/projects/plftool/build.c b/projects/plftool/build.c index de433de..62d1742 100644 --- a/projects/plftool/build.c +++ b/projects/plftool/build.c @@ -21,9 +21,12 @@ * along with this program. If not, see . */ +#define _GNU_SOURCE + #include #include #include +#include #include "plf.h" #include "build.h" #include "ini.h" @@ -35,7 +38,6 @@ # endif #endif - #define BUILD_TYPE_KERNEL 1 #define BUILD_TYPE_ARCHIVE 2 @@ -51,8 +53,38 @@ typedef struct s_exec_sect_config_tag { const char* input_file; u32 load_addr; + } s_exec_sect_config; +typedef struct s_load_config_tag +{ + u32 entry_point; + u32 hdr_version; + + struct + { + u32 major; + u32 minor; + u32 bugfix; + } version; + + struct + { + u32 plat; + u32 appl; + } target; + + u32 hw_compat; + u32 lang_zone; + + s_exec_sect_config bootloader; + s_exec_sect_config installer; + s_exec_sect_config volume_config; + s_exec_sect_config main_boot; + const char* facts_input; + +} s_load_config; + typedef struct s_kernel_config_tag { u32 entry_point; @@ -80,6 +112,19 @@ typedef struct s_kernel_config_tag } s_kernel_config; +const char* read_archive_config(const s_ini_handle* ini_file, const char* sect_name) +{ + const s_ini_section* ini_sect; + if (ini_file == 0 || sect_name == 0) + return NULL; + + ini_sect = ini_get_section(ini_file, sect_name ); + if (!ini_sect) + return NULL; + + return ini_get_string(ini_file, "file", ini_sect, 0); +} + int read_exec_sect_config(s_exec_sect_config* cfg, const s_ini_handle* ini_file, const char* sect_name) { const s_ini_section* ini_sect; @@ -108,7 +153,7 @@ int write_plf_exec_sect(const s_exec_sect_config* cfg, int fileIdx, int type) void* buffer; if (cfg == 0 || fileIdx < 0) return -1; - + fp = fopen(cfg->input_file, "rb"); if (fp == 0) { @@ -116,8 +161,6 @@ int write_plf_exec_sect(const s_exec_sect_config* cfg, int fileIdx, int type) return -1; } - - sectIdx = plf_begin_section(fileIdx); if (sectIdx < 0) { @@ -159,6 +202,41 @@ int write_plf_exec_sect(const s_exec_sect_config* cfg, int fileIdx, int type) } +int write_file_actions(const s_load_config* payload, int fileIdx) +{ + s_exec_sect_config* cfg; + struct dirent **entrylist; + char * file_path; + int n, i; + + n = scandir(payload->facts_input, &entrylist, NULL, versionsort); + if (n < 0) { + printf("Unable to open directory entry!\n"); + return -1; + } else { + for (i = 0; i < n; i++) { + if (!strcmp (entrylist[i]->d_name, ".")) + continue; + if (!strcmp (entrylist[i]->d_name, "..")) + continue; + + file_path = (char *)malloc(strlen(payload->facts_input) + strlen(entrylist[i]->d_name) + 1); + sprintf(file_path, "%s/%s", payload->facts_input, entrylist[i]->d_name); + cfg = (s_exec_sect_config *)malloc(sizeof(s_exec_sect_config)); + + cfg->load_addr = 0; + cfg->input_file = file_path; + + write_plf_exec_sect(cfg, fileIdx, 9); + free(cfg); + free(entrylist[i]); + } + } + + free(entrylist); + return 0; +} + int verify_kernel_config(const s_kernel_config* cfg) { int error = 0; @@ -177,7 +255,7 @@ int verify_kernel_config(const s_kernel_config* cfg) ++error; } - if (cfg->hdr_version < 10 || cfg->hdr_version > 11) + if (cfg->hdr_version < 10 || cfg->hdr_version > 14) { printf("!!! unsupported header version"); ++error; @@ -186,6 +264,114 @@ int verify_kernel_config(const s_kernel_config* cfg) return 0-error; } +int build_load(const s_ini_handle* ini_file) +{ + const s_ini_section* ini_sect; + s_load_config payload; + //int has_file_action = 0; + int plf_file_idx; + s_plf_file* plf_file_hdr; + int tmp_val; + + /* 1. Section file */ + __GET_SECT_SAFE(ini_sect, ini_file, "file"); + payload.entry_point = ini_get_int(ini_file, "entrypoint", ini_sect, 0); + payload.version.major = ini_get_int(ini_file, "versionmajor", ini_sect, 0); + payload.version.minor = ini_get_int(ini_file, "versionminor", ini_sect, 0); + payload.version.bugfix = ini_get_int(ini_file, "versionbugfix", ini_sect, 0); + payload.hdr_version = ini_get_int(ini_file, "hdrversion", ini_sect, 10); /* Fixed to 10 if not defined */ + payload.target.plat = ini_get_int(ini_file, "targetplat", ini_sect, 0); + payload.target.appl = ini_get_int(ini_file, "targetappl", ini_sect, 0); + payload.hw_compat = ini_get_int(ini_file, "hwcompatibility", ini_sect, 0); + payload.lang_zone = ini_get_int(ini_file, "languagezone", ini_sect, 0); + + /* 2. Section volume_config */ + if (read_exec_sect_config(&(payload.volume_config), ini_file, "volume_config") != 0) + { + printf("Section volume_config not found!\n"); + return -1; + } + /* 3. Section installer.plf */ + if (read_exec_sect_config(&(payload.installer), ini_file, "installer") != 0) + { + printf("Section installer.plf not found!\n"); + return -1; + } + /* 4. Section bootloader */ + if (read_exec_sect_config(&(payload.bootloader), ini_file, "bootloader") != 0) + { + printf("Section bootloader not found!\n"); + return -1; + } + /* 5. Section main_boot */ + if (read_exec_sect_config(&(payload.main_boot), ini_file, "main_boot") != 0) + { + printf("Section main_boot.plf not found!\n"); + return -1; + } + /* 6. Sections file_action */ + payload.facts_input = read_archive_config(ini_file, "file_actions"); + if (!payload.facts_input) + { + printf("Directory for file_actions not found!\n"); + return -1; + } + + printf("Creating %s ...\n", command_args.output); + + /* Creation starts */ + plf_file_idx = plf_create_file(command_args.output); + if (plf_file_idx < 0) + { + printf("!!! plf_create_file failed\n"); + return -1; + } + + /* Set file header */ + plf_file_hdr = plf_get_file_header(plf_file_idx); + plf_file_hdr->dwFileType = BUILD_TYPE_ARCHIVE; /* ARCHIVE TYPE */ + plf_file_hdr->dwEntryPoint = payload.entry_point; + plf_file_hdr->dwHdrVersion = payload.hdr_version; + plf_file_hdr->dwVersionMajor = payload.version.major; + plf_file_hdr->dwVersionMinor = payload.version.minor; + plf_file_hdr->dwVersionBugfix = payload.version.bugfix; + plf_file_hdr->dwTargetAppl = payload.target.appl; + plf_file_hdr->dwTargetPlat = payload.target.plat; + plf_file_hdr->dwHwCompat = payload.hw_compat; + plf_file_hdr->dwLangZone = payload.lang_zone; + + /* Create sections */ + printf("Writting sections...\n"); + tmp_val = 0; + tmp_val += write_plf_exec_sect(&(payload.volume_config), plf_file_idx, 11); + tmp_val += write_plf_exec_sect(&(payload.installer), plf_file_idx, 12); + tmp_val += write_plf_exec_sect(&(payload.bootloader), plf_file_idx, 7); + tmp_val += write_plf_exec_sect(&(payload.main_boot), plf_file_idx, 3); + tmp_val += write_file_actions(&payload, plf_file_idx); + + if (tmp_val < 0) + { + printf("!!! some sections could not be written.. aborting\n"); + return -1; + } + printf("Sections written\n"); + + plf_close(plf_file_idx); + + /* Verify */ + plf_file_idx = plf_open_file(command_args.output); + tmp_val = plf_verify(plf_file_idx); + plf_close(plf_file_idx); + if (tmp_val < 0) + { + printf("plf_verify failed: %d\n", tmp_val); + return -1; + } + + + return 0; +} + int build_kernel(const s_ini_handle* ini_file) { const s_ini_section* ini_sect; @@ -274,7 +460,7 @@ int build_kernel(const s_ini_handle* ini_file) /* Set file header */ plf_file_hdr = plf_get_file_header(plf_file_idx); - plf_file_hdr->dwFileType = 1; + plf_file_hdr->dwFileType = BUILD_TYPE_KERNEL; plf_file_hdr->dwEntryPoint = kernel.entry_point; plf_file_hdr->dwHdrVersion = kernel.hdr_version; plf_file_hdr->dwVersionMajor = kernel.version.major; @@ -365,9 +551,9 @@ int build(void) } if (stricmp(ini_parm->value, "kernel") == 0) - { ret_val = build_kernel(ini_file); - } + else if (stricmp(ini_parm->value, "payload") == 0) + ret_val = build_load(ini_file); else { printf("!!! unkown value %s for parameter type\n", ini_parm->value); diff --git a/projects/plftool/ini.c b/projects/plftool/ini.c index 5088304..32aa842 100644 --- a/projects/plftool/ini.c +++ b/projects/plftool/ini.c @@ -82,15 +82,15 @@ const s_ini_handle* ini_open(const char* filename) retval->sections = 0; retval->parameters = 0; - read_bytes = fread(retval->buffer, file_size, 1, fp); + read_bytes = fread(retval->buffer, 1, file_size, fp); fclose(fp); - if (read_bytes != file_size) - { - free(retval->buffer); - free(retval); - return 0; - } + if (read_bytes != file_size) + { + free(retval->buffer); + free(retval); + return 0; + } ini_read_ini(retval); free(retval->buffer); diff --git a/projects/plftool/samples/payload.ini b/projects/plftool/samples/payload.ini new file mode 100644 index 0000000..1980b23 --- /dev/null +++ b/projects/plftool/samples/payload.ini @@ -0,0 +1,28 @@ +[file] +Type=payload +EntryPoint=0 +HdrVersion=14 +VersionMajor=3 +VersionMinor=47 +VersionBugfix=0 +TargetPlat=0x4 +TargetAppl=0x54 +HwCompatibility=0x0f9059c5 +LanguageZone=0 + +[volume_config] +LoadAddr=0 +File=volume_config + +[installer] +LoadAddr=0 +File=installer.plf + +[bootloader] +LoadAddr=0 +File=bootloader.bin + +[main_boot] +LoadAddr=0 +File=main_boot.plf +