Skip to content

Commit 8dd4593

Browse files
committed
add tool to extract iort table from fw.
1 parent 4efac91 commit 8dd4593

File tree

2 files changed

+148
-2
lines changed

2 files changed

+148
-2
lines changed

CMakeLists.txt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,20 @@ target_include_directories(acpi_extractor PRIVATE
3434
${CMAKE_SOURCE_DIR}/include
3535
)
3636

37+
# Build iort_reader tool
38+
add_executable(iort_reader src/iort_reader.c lib/utils.c)
39+
target_include_directories(iort_reader PRIVATE
40+
${CMAKE_SOURCE_DIR}/include
41+
)
42+
43+
# Ensure tools are built by default
44+
add_custom_target(tools ALL DEPENDS acpi_extractor iort_reader)
45+
3746
# Define supported ACPI table types and their corresponding source files
3847
# Format: TABLE_NAME -> (header_file, source_file)
39-
set(ACPI_TABLE_TYPES "pptt;madt;mcfg")
48+
set(ACPI_TABLE_TYPES "pptt;madt;dbg2;mcfg")
49+
set(ACPI_TABLE_dbg2_HEADER "dbg2.h")
50+
set(ACPI_TABLE_dbg2_SOURCE "src/dummy/dbg2.c")
4051
set(ACPI_TABLE_pptt_HEADER "pptt.h")
4152
set(ACPI_TABLE_pptt_SOURCE "src/dummy/pptt.c")
4253
set(ACPI_TABLE_madt_HEADER "madt.h")
@@ -126,7 +137,7 @@ foreach(DEVICE_TARGET ${ALL_DEVICE_TARGETS})
126137
endforeach()
127138

128139
# Ensure acpi_extractor is built first
129-
add_dependencies(build_all_devices acpi_extractor)
140+
add_dependencies(build_all_devices acpi_extractor iort_reader)
130141

131142
# Collect all DSL files for testing
132143
set(ALL_DSL_FILES "")

src/iort_reader.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/* Locate magic and extract table from compiled binaries */
2+
#include "utils.h"
3+
#include <acpi.h>
4+
#include <common.h>
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <string.h>
8+
9+
int main(int argc, char **argv) {
10+
uint32_t table_size = 0;
11+
uint32_t table_start_offset = 0;
12+
ACPI_TABLE_HEADER *table_header = NULL;
13+
char *output_file_path = NULL;
14+
FileContent output_table = {0};
15+
FileContent input_binary = {0};
16+
17+
int ret = 0;
18+
19+
// Check args, one for input binary, one for output acpi table
20+
if (argc != 3 && argc != 2) {
21+
log_warn("Usage: %s <tz.mbn/hyp.mbn> <output path>", argv[0]);
22+
return -EINVAL;
23+
}
24+
25+
// Open input binary file
26+
input_binary.filePath = argv[1];
27+
28+
// Read buffer from input binary
29+
if (!get_file_size(&input_binary)) {
30+
log_err("Failed to get file size for %s", input_binary.filePath);
31+
return -EINVAL;
32+
}
33+
input_binary.fileBuffer = malloc(input_binary.fileSize);
34+
read_file_content(&input_binary);
35+
36+
// Locate magic in input binary
37+
char table_start_magic[] = {'2', 'K', 'D', 'E', 'M', 'O', 'C', 'Q'};
38+
for (size_t i = 0x10; i < input_binary.fileSize - sizeof(table_start_magic);
39+
i++) {
40+
if (memcmp(input_binary.fileBuffer + i, table_start_magic,
41+
sizeof(table_start_magic)) == 0) {
42+
table_start_offset = i - 0x10; // Adjust to table header start
43+
}
44+
}
45+
46+
// Check if table found
47+
if (table_start_offset == 0) {
48+
free(input_binary.fileBuffer);
49+
log_err("Table start magic not found in %s", input_binary.filePath);
50+
return -ENOENT;
51+
}
52+
53+
// Map header
54+
table_header =
55+
(ACPI_TABLE_HEADER *)(input_binary.fileBuffer + table_start_offset);
56+
57+
// Calulate and validate table size
58+
table_size = table_header->Length;
59+
if (table_size <= 0 ||
60+
table_size > input_binary.fileSize - table_start_offset) {
61+
printf("[WARN] Invalid table size %u\n", table_size);
62+
}
63+
64+
// Calculate and correct checksum
65+
table_header->Checksum =
66+
checksum(input_binary.fileBuffer + table_start_offset, table_size);
67+
68+
// Check if output file string does not exist
69+
if (argc == 2) {
70+
// Write file to current directory with default file name from input binary
71+
char table_name[5];
72+
memcpy(table_name, table_header->Signature, 4);
73+
table_name[4] = '\0';
74+
75+
size_t out_len = sizeof(table_name) + 4; // Signature.aml + '\0'
76+
output_file_path = malloc(out_len);
77+
if (!output_file_path) {
78+
free(input_binary.fileBuffer);
79+
log_err("Failed to allocate memory for output file path");
80+
return -ENOMEM;
81+
}
82+
// Construct output file path
83+
snprintf(output_file_path, out_len, "%s.%s", table_name, "aml");
84+
output_table.filePath = output_file_path;
85+
} else if (argc >= 3 && is_directory(argv[2])) {
86+
// Output to specified directory with default file name from input binary
87+
char table_name[5];
88+
memcpy(table_name, table_header->Signature, 4);
89+
table_name[4] = '\0';
90+
size_t out_len =
91+
strlen(argv[2]) + sizeof(table_name) + 5; // dir/Signature.aml + '\0'
92+
output_file_path = malloc(out_len);
93+
if (!output_file_path) {
94+
free(input_binary.fileBuffer);
95+
log_err("Failed to allocate memory for output file path");
96+
return -ENOMEM;
97+
}
98+
// Remove the last '/' if exists
99+
if (argv[2][strlen(argv[2]) - 1] == '/')
100+
argv[2][strlen(argv[2]) - 1] = '\0';
101+
// Construct output file path
102+
snprintf(output_file_path, out_len, "%s/%s.%s", argv[2], table_name, "aml");
103+
output_table.filePath = output_file_path;
104+
} else {
105+
output_table.filePath = argv[2];
106+
}
107+
108+
// Write table to output file
109+
output_table.fileSize = table_size;
110+
output_table.fileBuffer = malloc(output_table.fileSize);
111+
memcpy(output_table.fileBuffer, input_binary.fileBuffer + table_start_offset,
112+
output_table.fileSize);
113+
ret = write_file_content(&output_table);
114+
if (ret < 0) {
115+
log_err("Failed to write ACPI table to %s", output_table.filePath);
116+
free(input_binary.fileBuffer);
117+
free(output_table.fileBuffer);
118+
if (output_file_path)
119+
free(output_file_path);
120+
return ret;
121+
}
122+
123+
// Success
124+
log_info("Table %c%c%c%c extracted to :\t%s", table_header->Signature[0],
125+
table_header->Signature[1], table_header->Signature[2],
126+
table_header->Signature[3], output_table.filePath);
127+
128+
// Clean up
129+
free(input_binary.fileBuffer);
130+
free(output_table.fileBuffer);
131+
if (output_file_path)
132+
free(output_file_path);
133+
134+
return ret;
135+
}

0 commit comments

Comments
 (0)