Subversion Repositories QNX 8.QNX8 IFS tool

Rev

Rev 33 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
16 pmbaty 1
#ifndef IFSFILE_H
2
#define IFSFILE_H
3
 
4
 
5
#ifdef __cplusplus
6
extern "C" {
7
#endif
8
 
9
 
10
// standard C includes
11
#include <stdint.h>
12
#include <stdlib.h>
13
 
14
 
15
// compiler-specific glue
16
#ifdef _WIN32
17
#ifndef __BYTE_ORDER__
18
#define __ORDER_BIG_ENDIAN__    4321
19
#define __ORDER_LITTLE_ENDIAN__ 1234
20
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ // all Windows machines are little endian
21
#endif // !__BYTE_ORDER__
22
#ifndef __builtin_bswap64
23
#ifdef _MSC_VER
24
#define __builtin_bswap64(x) _byteswap_uint64 ((unsigned long long) (x))
25
#endif // _MSC_VER
26
#endif // !__builtin_bswap64
27
#ifndef __builtin_bswap32
28
#ifdef _MSC_VER
29
#define __builtin_bswap32(x) _byteswap_ulong ((unsigned long) (x))
30
#endif // _MSC_VER
31
#endif // !__builtin_bswap32
32
#ifndef __builtin_bswap16
33
#ifdef _MSC_VER
34
#define __builtin_bswap16(x) _byteswap_ushort ((unsigned short) (x))
35
#endif // _MSC_VER
36
#endif // !__builtin_bswap32
37
#endif // _WIN32
38
#ifdef _MSC_VER
39
#define START_OF_PACKED_STRUCT() __pragma(pack(push)) __pragma(pack(1))
40
#define END_OF_PACKED_STRUCT() __pragma(pack(pop))
41
#define PACKED(thing) thing
42
#else // !_MSC_VER
43
#define START_OF_PACKED_STRUCT()
44
#define END_OF_PACKED_STRUCT()
45
#define PACKED(thing) thing __attribute__((packed))
46
#endif // _MSC_VER
47
 
48
 
49
// bitmapped flags used in the flags1 member of the startup header
50
#define STARTUP_HDR_FLAGS1_VIRTUAL        (1 << 0)
51
#define STARTUP_HDR_FLAGS1_BIGENDIAN      (1 << 1)
26 pmbaty 52
#define STARTUP_HDR_FLAGS1_COMPRESS_NONE  ((0 << 4) | (0 << 3) | (0 << 2))
53
#define STARTUP_HDR_FLAGS1_COMPRESS_ZLIB  ((0 << 4) | (0 << 3) | (1 << 2)) // deprecated in mkifs
54
#define STARTUP_HDR_FLAGS1_COMPRESS_LZO   ((0 << 4) | (1 << 3) | (0 << 2)) // TODO: add this compression scheme with liblzo
55
#define STARTUP_HDR_FLAGS1_COMPRESS_UCL   ((0 << 4) | (1 << 3) | (1 << 2))
56
#define STARTUP_HDR_FLAGS1_COMPRESS_MASK  ((1 << 4) | (1 << 3) | (1 << 2))
16 pmbaty 57
#define STARTUP_HDR_FLAGS1_TRAILER_V2     (1 << 5) // if set, then a struct startup_trailer_v2 follows the startup. If the image is compressed, then the compressed imagefs is followed by a struct image_trailer_v2
58
 
59
 
60
// bitmapped flags used in the flags member of the image header
61
#define IMAGE_FLAGS_BIGENDIAN  (1 << 0) // header, trailer, dirents in big-endian format
62
#define IMAGE_FLAGS_READONLY   (1 << 1) // do not try to write to image (rom/flash)
63
#define IMAGE_FLAGS_INO_BITS   (1 << 2) // inode bits valid
64
#define IMAGE_FLAGS_SORTED     (1 << 3) // dirent section is sorted (by pathname)
65
#define IMAGE_FLAGS_TRAILER_V2 (1 << 4) // image uses struct image_trailer_v2
66
 
67
 
68
// bitmapped flags superposed to a filesystem entry's inode number
22 pmbaty 69
#define IFS_INO_PROCESSED_ELF (1 << 31)
70
#define IFS_INO_RUNONCE_ELF   (1 << 30)
71
#define IFS_INO_BOOTSTRAP_EXE (1 << 29)
16 pmbaty 72
 
73
 
22 pmbaty 74
// compiled boot script command types
75
#define SCRIPTCMD_TYPE_EXTERNAL        "\x00"
76
#define SCRIPTCMD_TYPE_WAITFOR         "\x01"
77
#define SCRIPTCMD_TYPE_REOPEN          "\x02"
78
#define SCRIPTCMD_TYPE_DISPLAY_MSG     "\x03"
79
#define SCRIPTCMD_TYPE_PROCMGR_SYMLINK "\x04"
80
#define SCRIPTCMD_TYPE_EXTSCHED_APS    "\x05"
16 pmbaty 81
 
82
 
22 pmbaty 83
// compiled boot script external command flags
84
#define SCRIPTCMD_FLAG_EXTSCHED   (1 << 0)
85
#define SCRIPTCMD_FLAG_SESSION    (1 << 1)
86
#define SCRIPTCMD_FLAG_SCHED_SET  (1 << 2)
87
#define SCRIPTCMD_FLAG_CPU_SET    (1 << 3)
88
#define SCRIPTCMD_FLAG_UNKNOWN1   (1 << 4) // ???
89
#define SCRIPTCMD_FLAG_BACKGROUND (1 << 5)
90
#define SCRIPTCMD_FLAG_KDEBUG     (1 << 6)
91
#define SCRIPTCMD_FLAG_UNKNOWN2   (1 << 7) // ???
16 pmbaty 92
 
93
 
22 pmbaty 94
// compiled boot script external command scheduling policies
95
#define SCRIPTCMD_SCHEDULERPOLICY_FIFO 1
96
#define SCRIPTCMD_SCHEDULERPOLICY_RR   2
16 pmbaty 97
 
98
 
99
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
100
typedef PACKED (struct) fsentry_s
101
{
102
   PACKED (struct) fsentry_header_s
103
   {
104
      uint16_t size; // size of dirent
105
      uint16_t extattr_offset; // if zero, no extattr data
106
      uint32_t ino; // if zero, skip entry
107
      uint32_t mode; // mode and perms of entry
108
      uint32_t gid;
109
      uint32_t uid;
110
      uint32_t mtime;
111
   } header;
112
   PACKED (union) fsentry_specific_u
113
   {
114
      PACKED (struct) fsentry_file_s // when (mode & S_IFMT) == S_IFREG
115
      {
116
         uint32_t offset; // offset from header
117
         uint32_t size;
118
         char *path; // null terminated path (no leading slash)
119
      } file;
120
      PACKED (struct) fsentry_dir_s // when (mode & S_IFMT) == S_IFDIR
121
      {
122
         char *path; // null terminated path (no leading slash)
123
      } dir;
124
      PACKED (struct) fsentry_symlink_s // when (mode & S_IFMT) == S_IFLNK
125
      {
126
         uint16_t sym_offset; // offset to 'contents' from 'path'
127
         uint16_t sym_size; // strlen (contents)
128
         char *path; // null terminated path (no leading slash)
129
         char *contents; // null terminated symlink contents
130
      } symlink;
131
      PACKED (struct) fsentry_device_s // when (mode & S_IFMT) == S_IF<CHR|BLK|FIFO|NAM|SOCK>
132
      {
133
         uint32_t dev;
134
         uint32_t rdev;
135
         char *path; // null terminated path (no leading slash)
136
      } device;
137
   } u;
34 pmbaty 138
   uint8_t *UNSAVED_databuf; // file data blob buffer (convenience pointer, NOT SAVED IN THE IFS)
139
   int UNSAVED_lineno; // line in the IFS build file at which this entry was defined (convenience member, NOT SAVED IN THE IFS)
16 pmbaty 140
   bool UNSAVED_was_data_written; // whether this entry's data was written to the image (convenience member, NOT SAVED IN THE IFS)
141
} fsentry_t;
142
END_OF_PACKED_STRUCT () // restore default alignment
143
 
144
 
145
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
146
typedef PACKED (struct) startup_header_s // size 256 bytes
147
{
148
   // I - used by the QNX IPL
149
   // S - used by the startup program
150
   uint8_t signature[4];   // [I ] Header signature, "\xeb\x7e\xff\x00"
151
   uint16_t version;       // [I ] Header version, i.e. 1
152
   uint8_t flags1;         // [IS] Misc flags, 0x21 (= 0x20 | STARTUP_HDR_FLAGS1_VIRTUAL)
153
   uint8_t flags2;         // [  ] No flags defined yet (0)
154
   uint16_t header_size;   // [ S] sizeof(struct startup_header), i.e. 256
155
   uint16_t machine;       // [IS] Machine type from elfdefinitions.h, i.e. 0x003E --> _ELF_DEFINE_EM(EM_X86_64, 62, "AMD x86-64 architecture")
156
   uint32_t startup_vaddr; // [I ] Virtual Address to transfer to after IPL is done, here 0x01403008 (appears in "Entry" column for "startup.*")
157
   uint32_t paddr_bias;    // [ S] Value to add to physical address to get a value to put into a pointer and indirected through, here 0 (no indirections)
158
   uint32_t image_paddr;   // [IS] Physical address of image, here 0x01400f30 (appears in "Offset" column for "startup-header" which is the first entry/start of file)
159
   uint32_t ram_paddr;     // [IS] Physical address of RAM to copy image to (startup_size bytes copied), here 0x01400f30 (same as above)
160
   uint32_t ram_size;      // [ S] Amount of RAM used by the startup program and executables contained in the file system, here 0x00cd6128 i.e. 13 459 752 dec. which is 13 Mb. i.e. IFS file size minus 0x9eee
161
   uint32_t startup_size;  // [I ] Size of startup (never compressed), here 0x02f148 or 192 840 bytes
162
   uint32_t stored_size;   // [I ] Size of entire image, here 0x00cd6128 (same as ram_size)
163
   uint32_t imagefs_paddr; // [IS] Set by IPL to where the imagefs is when startup runs (0)
164
   uint32_t imagefs_size;  // [ S] Size of uncompressed imagefs, here 0x00ca6fe0 or 13 266 912 bytes
165
   uint16_t preboot_size;  // [I ] Size of loaded before header, here 0xf30 or 3888 bytes (size of "bios.boot" file))
166
   uint16_t zero0;         // [  ] Zeros
167
   uint32_t zero[1];       // [  ] Zeros
168
   uint64_t addr_off;      // [ S] Offset to add to startup_vaddr, image_paddr, ram_paddr, and imagefs_paddr members, here zero (0)
169
   uint32_t info[48];      // [IS] Array of startup_info* structures (zero filled)
170
} startup_header_t;
171
END_OF_PACKED_STRUCT () // restore default alignment
172
 
173
 
174
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
175
typedef PACKED (struct) startup_trailer_s
176
{
177
   uint32_t cksum; // checksum from start of header to start of trailer
178
} startup_trailer_v1_t;
179
END_OF_PACKED_STRUCT () // restore default alignment
180
 
181
 
182
// NOTE: The checksums in this trailer will only be valid prior to entering startup.
183
// Because the startup binary is executed in-place, its data segment will change once the program is running.
184
// Hence, any checksum validation would need to be done by the boot loader / IFS.
185
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
186
typedef PACKED (struct) startup_trailer_v2_s
187
{
188
   uint8_t sha512[64]; // SHA512 from start of header to start of trailer
189
   uint32_t cksum; // checksum from start of header to start of this member
190
} startup_trailer_v2_t;
191
END_OF_PACKED_STRUCT () // restore default alignment
192
 
193
 
194
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
195
typedef PACKED (struct) image_header_s
196
{
197
   uint8_t signature[7]; // image filesystem signature, i.e. "imagefs"
198
   uint8_t flags; // endian neutral flags, 0x1c
199
   uint32_t image_size; // size from start of header to end of trailer (here 0xca6fe0 or 13 266 912)
200
   uint32_t hdr_dir_size; // size from start of header to last dirent (here 0x12b8 or 4792)
201
   uint32_t dir_offset; // offset from start of header to start of first dirent (here 0x5c or 92)
202
   uint32_t boot_ino[4]; // inode of files for bootstrap pgms (here 0xa0000002, 0, 0, 0)
203
   uint32_t script_ino; // inode of file for script (here 3)
204
   uint32_t chain_paddr; // offset to next filesystem signature (0)
205
   uint32_t spare[10]; // zerofill
206
   uint32_t mountflags; // default _MOUNT_* from sys/iomsg.h (0)
207
   char mountpoint[4]; // default mountpoint for image ("/" + "\0\0\0")
208
} image_header_t;
209
END_OF_PACKED_STRUCT () // restore default alignment
210
 
211
 
212
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
213
typedef PACKED (struct) image_trailer_v1_s
214
{
215
   uint32_t cksum; // checksum from start of header to start of trailer
216
} image_trailer_v1_t; // NOTE: this is the same structure as startup_trailer_v1_t
217
END_OF_PACKED_STRUCT () // restore default alignment
218
 
219
 
220
// NOTE: the checksums in this trailer will only be valid until the first non-startup bootstrap binary (e.g., startup-verifier, procnto, ...) is invoked.
221
// Because bootstrap binaries execute in-place, their data segments will change once the programs are running.
222
// Hence, any checksum validation would need to be done either by the boot loader / IFS or by the startup.
223
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
224
typedef PACKED (struct) image_trailer_v2_s
225
{
226
   uint8_t sha512[64]; // SHA512 from start of image header to start of trailer
227
   uint32_t cksum; // checksum from start of header to start of this member
228
} image_trailer_v2_t; // NOTE: this is the same structure as startup_trailer_v2_t
229
END_OF_PACKED_STRUCT () // restore default alignment
230
 
231
 
20 pmbaty 232
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
233
typedef PACKED (struct) bootargs_entry_s
234
{
235
   uint8_t size_lo; // includes entire structure
236
   uint8_t size_hi;
237
   uint8_t argc; // number of C-style strings that make up argv[] in args
238
   uint8_t envc; // number of C-style strings that make up envp[] in args after argv[]
239
   // if the actual startup header address cannot be represented in 32 bits, then shdr_addr is set to 0xFFFFFFFF and a uint64_t with the REAL shdr_address
240
   // immediately follows the last byte of the variable-length <args>. It will be included in the advertised <size_*> and is located at <bootargs_addr>+<size>-8
241
   uint32_t shdr_addr;
242
   //char *args; // variable length
243
} bootargs_entry_t;
244
END_OF_PACKED_STRUCT () // restore default alignment
245
 
246
 
33 pmbaty 247
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
34 pmbaty 248
typedef PACKED (struct) uefi64_header_s
33 pmbaty 249
{
250
   PACKED (struct) dos_header_s // size 64 bytes
251
   {
252
      uint8_t signature[2]; // magic number, "MZ"
253
      uint16_t bytes_in_last_page; // number of bytes on last 512-byte page of file (144 in our case)
254
      uint16_t number_of_pages; // 512-byte pages in file (3 in our case, which is a minimum)
255
      uint16_t number_of_relocations; // relocations (zero in our case)
256
      uint16_t header_size_in_paragraphs; // Size of this header in 16-byte paragraphs (4, i.e. 64 / 16)
257
      uint16_t required_paragraphs; // minimum extra paragraphs needed (0)
258
      uint16_t requested_paragraphs; // maximum extra paragraphs needed (0xffff)
259
      uint16_t initial_relative_relocatable_segment_address_for_ss; // Initial (relative) SS value (zero)
260
      uint16_t initial_stack_pointer_value; // Initial SP value (0xb8 or 184 for use with our DOS stub program code)
261
      uint16_t unused_checksum; // checksum (zero). Normally, value to add to the sum of all other words in the file except this one to reach zero.
262
      uint16_t initial_instruction_pointer_value; // initial IP value (zero in our case)
263
      uint16_t initial_relative_relocatable_segment_address_for_cs; // initial (relative) CS value (zero)
264
      uint16_t absolute_offset_to_relocation_table; // file address of relocation table (typically just after this header, i.e. 0x40 or 64 decimal)
265
      uint16_t overlay_number; // overlay number (zero, i.e. this is the main executable)
266
      uint16_t reserved_words1[4]; // reserved words (zerofilled)
267
      uint16_t oem_identifier; // OEM identifier for e_oeminfo (zero)
268
      uint16_t oem_info; // OEM information, oem_identifier specific (zero)
269
      uint16_t reserved_words2[10]; // reserved words (zerofilled)
270
      uint32_t absolute_offset_to_pe_header; // file address of PE header (typically just after the DOS stub program bytes, i.e. 0x80 or 128 decimal)
271
   } dos_header;
272
   uint8_t dos_stub_bytes[64]; // DOS stub program bytes: "\x0E\x1F\xBA\x0E\x00\xB4\x09\xCD\x21\xB8\x01\x4C\xCD\x21" "This program cannot be run in DOS mode.\r\r\n" "\x24\x00\x00\x00\x00\x00\x00\x00"
273
   PACKED (struct) pe_header_s
274
   {
275
      uint8_t signature[4]; // magic value, "PE\0\0"
276
      uint16_t machine_type; // machine type (0x8664 for AMD64)
277
      uint16_t number_of_sections; // number of sections (1 in our case)
278
      uint32_t epoch_timestamp; // number of seconds since UNIX Epoch
279
      uint32_t offset_to_symbols_table; // offset to symbols table (zero)
280
      uint32_t number_of_symbols; // number of symbols in symbols table (zero)
281
      uint16_t size_of_optional_header; // size of optional header (typically 240)
282
      uint16_t characteristics_bitmap; // bitmapped PE characteristics (0x223, or 547 decimal = executable, uses large addresses, relocs stripped, debug info stripped)
283
   } pe_header;
284
   PACKED (struct) pe_image_optional_header64_s
285
   {
286
      uint8_t signature[2]; // magic value, "\x0b\x02"
287
      uint8_t linker_version_major; // major version of the Microsoft linker used to produce this file (zero in our case)
288
      uint8_t linker_version_minor; // minor version of the Microsoft linker used to produce this file (zero in our case)
34 pmbaty 289
      uint32_t code_size; // size of the code section, in bytes, or the sum of all such sections if there are multiple code sections (total size of IFS minus 512 bytes for the UEFI boot header with padding, i.e. size of startup blob plus size of image)
33 pmbaty 290
      uint32_t size_of_initialized_data; // size of the initialized data section, in bytes, or the sum of all such sections if there are multiple initialized data sections (zero in our case)
291
      uint32_t size_of_uninitialized_data; // size of the uninitialized data section, in bytes, or the sum of all such sections if there are multiple uninitialized data sections (zero in our case)
292
      uint32_t entrypoint_address; // offset to the entry point function, relative to the image base address 
293
      uint32_t code_base; // offset to the beginning of the code section, relative to the image base (zero in our case)
34 pmbaty 294
      uint64_t image_base; // preferred address of the first byte of the image when it is loaded in memory, multiple of 64K bytes
33 pmbaty 295
      uint32_t section_alignment; // alignment of sections loaded in memory in bytes ; must be greater than or equal to file_alignment, defaults to system page size (4096 for AMD64)
296
      uint32_t file_alignment; // alignment of the raw data of sections in the image file, in bytes ; should be a power of 2 between 512 and 64K (inclusive) corresponding I suppose to to the minimal supported underlying filesystem block size (mkifs sets 512 here)
297
      uint16_t os_version_major; // major version number of the required operating system (zero for UEFI)
298
      uint16_t os_version_minor; // minor version number of the required operating system (zero for UEFI)
299
      uint16_t image_version_major; // major version number of this image (mkifs sets zero here)
300
      uint16_t image_version_minor; // minor version number of this image (mkifs sets zero here)
301
      uint16_t subsystem_version_major; // major version number of the required subsystem (zero for UEFI)
302
      uint16_t subsystem_version_minor; // minor version number of the required subsystem (zero for UEFI)
303
      uint32_t win32_version_value; // Microsoft says: "reserved, must be zero" -- so be it
304
      uint32_t image_size; // total IFS file size
305
      uint32_t size_of_headers; // size of the UEFI boot header, must be a multiple of file_alignment (mkifs sets 512 here)
306
      uint32_t unused_checksum; // zero
307
      uint16_t subsystem_type; // image subsystem type (0x0a or 10 decimal i.e. IMAGE_SUBSYSTEM_EFI_APPLICATION)
308
      uint16_t dll_characteristics_bitmap; // bitmapped DLL characteristics (0 in our case)
309
      uint64_t stack_reserve_size; // maximal number of bytes to reserve (i.e. allocate on demand, one page at a time) for the stack (mkifs sets one system page here, i.e. 4096 for AMD64)
310
      uint64_t stack_commit_size; // number of bytes to commit (i.e. allocate at startup) for the stack (mkifs sets one system page here, i.e. 4096 for AMD64)
311
      uint64_t heap_reserve_size; // maximal number of bytes to reserve (i.e. allocate on demand, one page at a time) for the local heap (mkifs sets zero here)
312
      uint64_t heap_commit_size; // number of bytes to commit (i.e. allocate at startup) for the local heap (mkifs sets zero here)
313
      uint32_t unused_loader_flags; // zero
314
      uint32_t number_of_data_directories; // number of directory entries in the remainder of the optional header, each entry made of a location and a size (mkifs sets 16 directory entries)
315
      PACKED (struct) pe_image_data_directory_s
316
      {
317
         uint32_t virtual_address; // relative virtual address of the table
318
         uint32_t size; // size of the table, in bytes
319
      } data_directories[16]; // 16 directory entries (zerofilled)
320
   } optional_header64;
321
   PACKED (struct) pe_image_section_header_s
322
   {
323
      uint8_t section_name[8]; // section name, here "image\0\0\0"
324
      uint32_t virtual_size; // total size of the section when loaded into memory, in bytes ; same as pe_image_optional_header64.code_size
325
      uint32_t virtual_address; // address of the first byte of the section when loaded into memory, relative to the image base (first file_alignment multiple after pe_image_optional_header64.size_of_headers, i.e. 512 in our case)
326
      uint32_t rawdata_size; // size of the initialized data on disk in bytes, multiple of file_alignment (same as virtual_size in our case)
327
      uint32_t rawdata_offset; // offset to the first page within the COFF file (same as virtual_address in our case)
328
      uint32_t offset_to_relocations; // offset to the beginning of the relocation entries in this section (zero in our case)
329
      uint32_t offset_to_linenos; // offset to the beginning of the line-number entries in this section (zero in our case)
330
      uint16_t relocation_count; // number of relocation entries in this section (zero in our case)
331
      uint16_t lineno_count; // number of line number entries in this section (zero in our case)
332
      uint32_t characteristics_bitmap; // bitmapped PE section characteristics (0x60, or 96 decimal, for: image contains code, image contains initialized data)
333
   } unique_section;
34 pmbaty 334
} uefi64_header_t;
33 pmbaty 335
END_OF_PACKED_STRUCT () // restore default alignment
336
#define UEFI_DOS_STUB_PROGRAM_BYTES "\x0E\x1F\xBA\x0E\x00\xB4\x09\xCD\x21\xB8\x01\x4C\xCD\x21" "This program cannot be run in DOS mode.\r\r\n" "\x24\x00\x00\x00\x00\x00\x00\x00" // 64 bytes
337
 
338
 
16 pmbaty 339
// undefine the helpers we no longer need
340
#undef START_OF_PACKED_STRUCT
341
#undef END_OF_PACKED_STRUCT
342
#undef PACKED
343
 
344
 
345
#ifdef __cplusplus
346
}
347
#endif
348
 
349
 
350
#endif // IFSFILE_H