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
+