Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
c91c0703
Commit
c91c0703
authored
Jan 14, 2021
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Re-enable DTB table rebuilding
parent
aec06a6f
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
240 additions
and
259 deletions
+240
-259
dtb.cpp
native/jni/magiskboot/dtb.cpp
+240
-259
No files found.
native/jni/magiskboot/dtb.cpp
View file @
c91c0703
...
@@ -124,38 +124,52 @@ static void dtb_print(const char *file, bool fstab) {
...
@@ -124,38 +124,52 @@ static void dtb_print(const char *file, bool fstab) {
munmap
(
dtb
,
size
);
munmap
(
dtb
,
size
);
}
}
static
bool
dtb_patch_rebuild
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
file
);
static
bool
dtb_patch
(
const
char
*
file
)
{
static
bool
dtb_patch
(
const
char
*
file
)
{
bool
keepverity
=
check_env
(
"KEEPVERITY"
);
bool
keep_verity
=
check_env
(
"KEEPVERITY"
);
bool
patched
=
false
;
bool
have_system
=
false
;
vector
<
pair
<
char
*
,
int
>>
flags_list
;
size_t
size
;
size_t
size
;
uint8_t
*
dtb
;
uint8_t
*
dtb
;
fprintf
(
stderr
,
"Loading dtbs from [%s]
\n
"
,
file
);
fprintf
(
stderr
,
"Loading dtbs from [%s]
\n
"
,
file
);
mmap_rw
(
file
,
dtb
,
size
);
mmap_rw
(
file
,
dtb
,
size
);
// Loop through all the dtbs
run_finally
f
([
=
]{
munmap
(
dtb
,
size
);
});
// First traverse through DTB to determine whether we need a rebuild
int
dtb_num
=
0
;
int
dtb_num
=
0
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
auto
fdt
=
dtb
+
i
;
auto
fdt
=
dtb
+
i
;
fprintf
(
stderr
,
"Loading dtb.%04d
\n
"
,
dtb_num
);
if
(
int
fstab
=
find_fstab
(
fdt
);
fstab
>=
0
)
{
if
(
int
fstab
=
find_fstab
(
fdt
);
fstab
>=
0
)
{
int
node
;
int
node
;
fdt_for_each_subnode
(
node
,
fdt
,
fstab
)
{
fdt_for_each_subnode
(
node
,
fdt
,
fstab
)
{
const
char
*
name
=
fdt_get_name
(
fdt
,
node
,
nullptr
);
const
char
*
name
=
fdt_get_name
(
fdt
,
node
,
nullptr
);
fprintf
(
stderr
,
"Found fstab entry [%s]
\n
"
,
name
);
if
(
!
keep_verity
)
{
if
(
!
keepverity
)
{
int
len
;
int
len
;
auto
value
=
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
);
char
*
value
=
(
char
*
)
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
);
patched
|=
patch_verity
(
const_cast
<
void
*>
(
value
),
len
)
!=
len
;
flags_list
.
emplace_back
(
value
,
len
)
;
}
}
if
(
name
==
"system"
sv
)
have_system
=
true
;
}
}
}
}
++
dtb_num
;
i
+=
fdt_totalsize
(
fdt
)
-
1
;
i
+=
fdt_totalsize
(
fdt
)
-
1
;
++
dtb_num
;
}
}
}
}
fprintf
(
stderr
,
"
\n
"
);
munmap
(
dtb
,
size
);
if
(
!
have_system
)
{
return
patched
;
// Patch in place with rw mmap
bool
patched
=
false
;
for
(
auto
&
[
value
,
len
]
:
flags_list
)
patched
|=
patch_verity
(
value
,
len
)
!=
len
;
return
patched
;
}
else
{
// Need to rebuild dtb due to additional props
return
dtb_patch_rebuild
(
dtb
,
size
,
file
);
}
}
}
int
dtb_commands
(
int
argc
,
char
*
argv
[])
{
int
dtb_commands
(
int
argc
,
char
*
argv
[])
{
...
@@ -176,279 +190,246 @@ int dtb_commands(int argc, char *argv[]) {
...
@@ -176,279 +190,246 @@ int dtb_commands(int argc, char *argv[]) {
}
}
namespace
{
namespace
{
// Unused, but keep these precious code as they took TONs of effort to write
struct
fdt_blob
{
void
*
fdt
;
uint32_t
offset
;
uint32_t
len
;
};
template
<
class
Iter
>
class
fdt_map_iter
{
public
:
typedef
decltype
(
std
::
declval
<
typename
Iter
::
value_type
::
second_type
>
().
fdt
)
value_type
;
typedef
value_type
*
pointer
;
typedef
value_type
&
reference
;
explicit
fdt_map_iter
(
Iter
j
)
:
i
(
j
)
{}
fdt_map_iter
&
operator
++
()
{
++
i
;
return
*
this
;
}
fdt_map_iter
operator
++
(
int
)
{
auto
tmp
=
*
this
;
++
(
*
this
);
return
tmp
;
}
fdt_map_iter
&
operator
--
()
{
--
i
;
return
*
this
;
}
fdt_map_iter
operator
--
(
int
)
{
auto
tmp
=
*
this
;
--
(
*
this
);
return
tmp
;
}
bool
operator
==
(
fdt_map_iter
j
)
const
{
return
i
==
j
.
i
;
}
bool
operator
!=
(
fdt_map_iter
j
)
const
{
return
!
(
*
this
==
j
);
}
reference
operator
*
()
{
return
i
->
second
.
fdt
;
}
pointer
operator
->
()
{
return
&
i
->
second
.
fdt
;
}
private
:
Iter
i
;
};
template
<
class
Iter
>
inline
fdt_map_iter
<
Iter
>
make_iter
(
Iter
j
)
{
return
fdt_map_iter
<
Iter
>
(
j
);
}
template
<
typename
Iter
>
static
bool
fdt_patch
(
Iter
first
,
Iter
last
)
{
bool
keepverity
=
check_env
(
"KEEPVERITY"
);
bool
redirect
=
check_env
(
"TWOSTAGEINIT"
);
bool
modified
=
false
;
int
idx
=
0
;
for
(
auto
it
=
first
;
it
!=
last
;
++
it
)
{
++
idx
;
auto
fdt
=
*
it
;
int
fstab
=
find_fstab
(
fdt
);
if
(
fstab
<
0
)
continue
;
fprintf
(
stderr
,
"Found fstab in dtb.%04d
\n
"
,
idx
-
1
);
int
block
;
fdt_for_each_subnode
(
block
,
fdt
,
fstab
)
{
const
char
*
name
=
fdt_get_name
(
fdt
,
block
,
nullptr
);
fprintf
(
stderr
,
"Found entry [%s] in fstab
\n
"
,
name
);
if
(
!
keepverity
)
{
int
size
;
auto
value
=
fdt_getprop
(
fdt
,
block
,
"fsmgr_flags"
,
&
size
);
char
*
copy
=
static_cast
<
char
*>
(
memcpy
(
malloc
(
size
),
value
,
size
));
if
(
patch_verity
(
copy
,
size
)
!=
size
)
{
modified
=
true
;
fdt_setprop_string
(
fdt
,
block
,
"fsmgr_flags"
,
copy
);
}
free
(
copy
);
}
if
(
redirect
&&
name
==
"system"
sv
)
{
modified
=
true
;
fprintf
(
stderr
,
"Changing mnt_point to /system_root
\n
"
);
fdt_setprop_string
(
fdt
,
block
,
"mnt_point"
,
"/system_root"
);
}
}
}
return
modified
;
}
#define MAX_FDT_GROWTH 256
template
<
class
Table
,
class
Header
>
struct
fdt_blob
{
static
int
dt_table_patch
(
const
Header
*
hdr
,
const
char
*
out
)
{
void
*
fdt
;
map
<
uint32_t
,
fdt_blob
>
dtb_map
;
uint32_t
offset
;
auto
buf
=
reinterpret_cast
<
const
uint8_t
*>
(
hdr
)
;
uint32_t
len
;
auto
tables
=
reinterpret_cast
<
const
Table
*>
(
hdr
+
1
)
;
}
;
constexpr
bool
is_dt_table
=
std
::
is_same_v
<
Header
,
dt_table_header
>
;
}
using
endian_conv
=
uint32_t
(
*
)(
uint32_t
);
static
bool
fdt_patch
(
void
*
fdt
)
{
endian_conv
be_to_le
;
int
fstab
=
find_fstab
(
fdt
);
endian_conv
le_to_be
;
if
(
fstab
<
0
)
if
constexpr
(
is_dt_table
)
{
return
false
;
be_to_le
=
fdt32_to_cpu
;
bool
modified
=
false
;
le_to_be
=
cpu_to_fdt32
;
int
node
;
}
else
{
fdt_for_each_subnode
(
node
,
fdt
,
fstab
)
{
be_to_le
=
le_to_be
=
[](
uint32_t
x
)
->
auto
{
return
x
;
};
const
char
*
name
=
fdt_get_name
(
fdt
,
node
,
nullptr
);
// Always patch verity if 2SI
int
len
;
auto
value
=
(
const
char
*
)
fdt_getprop
(
fdt
,
node
,
"fsmgr_flags"
,
&
len
);
string
copy
(
value
,
len
);
uint32_t
new_len
=
patch_verity
(
copy
.
data
(),
len
);
if
(
new_len
!=
len
)
{
modified
=
true
;
fdt_setprop
(
fdt
,
node
,
"fsmgr_flags"
,
copy
.
data
(),
new_len
);
}
}
if
(
name
==
"system"
sv
)
{
// Collect all dtbs
fprintf
(
stderr
,
"Setting [mnt_point] to [/system_root]
\n
"
);
auto
num_dtb
=
be_to_le
(
hdr
->
num_dtbs
);
fdt_setprop_string
(
fdt
,
node
,
"mnt_point"
,
"/system_root"
);
for
(
int
i
=
0
;
i
<
num_dtb
;
++
i
)
{
modified
=
true
;
auto
offset
=
be_to_le
(
tables
[
i
].
offset
);
if
(
dtb_map
.
count
(
offset
)
==
0
)
{
auto
blob
=
buf
+
offset
;
uint32_t
size
=
fdt_totalsize
(
blob
);
auto
fdt
=
xmalloc
(
size
+
MAX_FDT_GROWTH
);
memcpy
(
fdt
,
blob
,
size
);
fdt_open_into
(
fdt
,
fdt
,
size
+
MAX_FDT_GROWTH
);
dtb_map
[
offset
]
=
{
fdt
,
offset
};
}
}
}
if
(
dtb_map
.
empty
())
}
return
1
;
return
modified
;
}
// Patch fdt
if
(
!
fdt_patch
(
make_iter
(
dtb_map
.
begin
()),
make_iter
(
dtb_map
.
end
())))
return
1
;
unlink
(
out
);
int
fd
=
xopen
(
out
,
O_RDWR
|
O_CREAT
|
O_CLOEXEC
,
0644
);
uint32_t
total_size
=
0
;
// Copy headers and tables
#define MAX_FDT_GROWTH 256
total_size
+=
xwrite
(
fd
,
buf
,
dtb_map
.
begin
()
->
first
);
// mmap rw to patch table values retroactively
template
<
class
Table
,
class
Header
>
auto
mmap_sz
=
lseek
(
fd
,
0
,
SEEK_CUR
);
static
bool
dt_table_patch
(
const
Header
*
hdr
,
const
char
*
out
)
{
auto
addr
=
(
uint8_t
*
)
xmmap
(
nullptr
,
mmap_sz
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fd
,
0
);
map
<
uint32_t
,
fdt_blob
>
dtb_map
;
auto
buf
=
reinterpret_cast
<
const
uint8_t
*>
(
hdr
);
auto
tables
=
reinterpret_cast
<
const
Table
*>
(
buf
+
sizeof
(
Header
));
constexpr
bool
is_aosp
=
std
::
is_same_v
<
Header
,
dt_table_header
>
;
// AOSP DTB store ints in big endian
using
endian_conv
=
uint32_t
(
*
)(
uint32_t
);
endian_conv
be_to_le
;
endian_conv
le_to_be
;
if
constexpr
(
is_aosp
)
{
be_to_le
=
fdt32_to_cpu
;
le_to_be
=
cpu_to_fdt32
;
}
else
{
be_to_le
=
le_to_be
=
[](
uint32_t
x
)
{
return
x
;
};
}
// Guess alignment using gcd
// Collect all dtbs
uint32_t
align
=
1
;
auto
num_dtb
=
be_to_le
(
hdr
->
num_dtbs
);
if
constexpr
(
!
is_dt_table
)
{
for
(
int
i
=
0
;
i
<
num_dtb
;
++
i
)
{
auto
it
=
dtb_map
.
begin
();
auto
offset
=
be_to_le
(
tables
[
i
].
offset
);
align
=
(
it
++
)
->
first
;
if
(
dtb_map
.
count
(
offset
)
==
0
)
{
for
(;
it
!=
dtb_map
.
end
();
++
it
)
auto
blob
=
buf
+
offset
;
align
=
binary_gcd
(
align
,
it
->
first
);
uint32_t
size
=
fdt_totalsize
(
blob
);
auto
fdt
=
xmalloc
(
size
+
MAX_FDT_GROWTH
);
memcpy
(
fdt
,
blob
,
size
);
fdt_open_into
(
fdt
,
fdt
,
size
+
MAX_FDT_GROWTH
);
dtb_map
[
offset
]
=
{
fdt
,
offset
};
}
}
}
if
(
dtb_map
.
empty
())
return
false
;
// Patch fdt
bool
modified
=
false
;
for
(
auto
&
[
_
,
blob
]
:
dtb_map
)
modified
|=
fdt_patch
(
blob
.
fdt
);
if
(
!
modified
)
return
false
;
unlink
(
out
);
int
fd
=
xopen
(
out
,
O_RDWR
|
O_CREAT
|
O_CLOEXEC
,
0644
);
// This value is only used if AOSP DTB
uint32_t
total_size
=
0
;
// Copy headers and tables
total_size
+=
xwrite
(
fd
,
buf
,
dtb_map
.
begin
()
->
first
);
// mmap rw to patch table values retroactively
auto
mmap_sz
=
lseek
(
fd
,
0
,
SEEK_CUR
);
auto
addr
=
(
uint8_t
*
)
xmmap
(
nullptr
,
mmap_sz
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fd
,
0
);
// Guess alignment using gcd
uint32_t
align
=
1
;
if
constexpr
(
!
is_aosp
)
{
auto
it
=
dtb_map
.
begin
();
align
=
(
it
++
)
->
first
;
for
(;
it
!=
dtb_map
.
end
();
++
it
)
align
=
binary_gcd
(
align
,
it
->
first
);
}
// Write dtbs
// Write dtbs
for
(
auto
&
val
:
dtb_map
)
{
for
(
auto
&
val
:
dtb_map
)
{
val
.
second
.
offset
=
lseek
(
fd
,
0
,
SEEK_CUR
);
val
.
second
.
offset
=
lseek
(
fd
,
0
,
SEEK_CUR
);
auto
fdt
=
val
.
second
.
fdt
;
auto
fdt
=
val
.
second
.
fdt
;
fdt_pack
(
fdt
);
fdt_pack
(
fdt
);
auto
size
=
fdt_totalsize
(
fdt
);
auto
size
=
fdt_totalsize
(
fdt
);
total_size
+=
xwrite
(
fd
,
fdt
,
size
);
total_size
+=
xwrite
(
fd
,
fdt
,
size
);
if
constexpr
(
!
is_aosp
)
{
val
.
second
.
len
=
do_align
(
size
,
align
);
val
.
second
.
len
=
do_align
(
size
,
align
);
write_zero
(
fd
,
align_off
(
lseek
(
fd
,
0
,
SEEK_CUR
),
align
));
write_zero
(
fd
,
align_off
(
lseek
(
fd
,
0
,
SEEK_CUR
),
align
));
// total_size += align_off(lseek(fd, 0, SEEK_CUR), align); /* Not needed */
free
(
fdt
);
}
// Patch headers
if
constexpr
(
is_dt_table
)
{
auto
hdr_rw
=
reinterpret_cast
<
Header
*>
(
addr
);
hdr_rw
->
total_size
=
le_to_be
(
total_size
);
}
}
auto
tables_rw
=
reinterpret_cast
<
Table
*>
(
addr
+
sizeof
(
Header
));
free
(
fdt
);
for
(
int
i
=
0
;
i
<
num_dtb
;
++
i
)
{
}
auto
&
blob
=
dtb_map
[
be_to_le
(
tables_rw
[
i
].
offset
)];
tables_rw
[
i
].
offset
=
le_to_be
(
blob
.
offset
);
tables_rw
[
i
].
len
=
le_to_be
(
blob
.
len
);
}
munmap
(
addr
,
mmap_sz
);
close
(
fd
);
return
0
;
// Patch headers
if
constexpr
(
is_aosp
)
{
auto
hdr_rw
=
reinterpret_cast
<
Header
*>
(
addr
);
hdr_rw
->
total_size
=
le_to_be
(
total_size
);
}
auto
tables_rw
=
reinterpret_cast
<
Table
*>
(
addr
+
sizeof
(
Header
));
for
(
int
i
=
0
;
i
<
num_dtb
;
++
i
)
{
auto
&
blob
=
dtb_map
[
be_to_le
(
tables_rw
[
i
].
offset
)];
tables_rw
[
i
].
offset
=
le_to_be
(
blob
.
offset
);
tables_rw
[
i
].
len
=
le_to_be
(
blob
.
len
);
}
}
static
int
blob_patch
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
out
)
{
munmap
(
addr
,
mmap_sz
);
vector
<
uint8_t
*>
fdt_list
;
close
(
fd
);
vector
<
uint32_t
>
padding_list
;
for
(
int
i
=
0
;
i
<
dtb_sz
;
++
i
)
{
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
auto
len
=
fdt_totalsize
(
dtb
+
i
);
auto
fdt
=
static_cast
<
uint8_t
*>
(
xmalloc
(
len
+
MAX_FDT_GROWTH
));
memcpy
(
fdt
,
dtb
+
i
,
len
);
fdt_pack
(
fdt
);
uint32_t
padding
=
len
-
fdt_totalsize
(
fdt
);
padding_list
.
push_back
(
padding
);
fdt_open_into
(
fdt
,
fdt
,
len
+
MAX_FDT_GROWTH
);
fdt_list
.
push_back
(
fdt
);
i
+=
len
-
1
;
}
}
if
(
!
fdt_patch
(
fdt_list
.
begin
(),
fdt_list
.
end
()))
return
true
;
return
1
;
}
unlink
(
out
);
static
bool
blob_patch
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
out
)
{
int
fd
=
xopen
(
out
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
,
0644
);
vector
<
uint8_t
*>
fdt_list
;
vector
<
uint32_t
>
padding_list
;
for
(
int
i
=
0
;
i
<
fdt_list
.
size
();
++
i
)
{
for
(
int
i
=
0
;
i
<
dtb_sz
;
++
i
)
{
auto
fdt
=
fdt_list
[
i
];
if
(
memcmp
(
dtb
+
i
,
FDT_MAGIC_STR
,
4
)
==
0
)
{
auto
len
=
fdt_totalsize
(
dtb
+
i
);
auto
fdt
=
static_cast
<
uint8_t
*>
(
xmalloc
(
len
+
MAX_FDT_GROWTH
));
memcpy
(
fdt
,
dtb
+
i
,
len
);
fdt_pack
(
fdt
);
fdt_pack
(
fdt
);
// Only add padding back if it is anything meaningful
uint32_t
padding
=
len
-
fdt_totalsize
(
fdt
);
if
(
padding_list
[
i
]
>
4
)
{
padding_list
.
push_back
(
padding
);
auto
len
=
fdt_totalsize
(
fdt
);
fdt_open_into
(
fdt
,
fdt
,
len
+
MAX_FDT_GROWTH
);
fdt_set_totalsize
(
fdt
,
len
+
padding_list
[
i
]);
fdt_list
.
push_back
(
fdt
);
}
i
+=
len
-
1
;
xwrite
(
fd
,
fdt
,
fdt_totalsize
(
fdt
));
free
(
fdt
);
}
}
close
(
fd
);
}
return
0
;
bool
modified
=
false
;
for
(
auto
fdt
:
fdt_list
)
modified
|=
fdt_patch
(
fdt
);
if
(
!
modified
)
return
false
;
unlink
(
out
);
int
fd
=
xopen
(
out
,
O_WRONLY
|
O_CREAT
|
O_CLOEXEC
,
0644
);
for
(
int
i
=
0
;
i
<
fdt_list
.
size
();
++
i
)
{
auto
fdt
=
fdt_list
[
i
];
fdt_pack
(
fdt
);
// Only add padding back if it is anything meaningful
if
(
padding_list
[
i
]
>
4
)
{
auto
len
=
fdt_totalsize
(
fdt
);
fdt_set_totalsize
(
fdt
,
len
+
padding_list
[
i
]);
}
xwrite
(
fd
,
fdt
,
fdt_totalsize
(
fdt
));
free
(
fdt
);
}
}
close
(
fd
);
return
true
;
}
#define MATCH(s) (memcmp(dtb, s, sizeof(s) - 1) == 0)
#define MATCH(s) (memcmp(dtb, s, sizeof(s) - 1) == 0)
[[
maybe_unused
]]
static
int
dtb_patch
(
const
char
*
in
,
const
char
*
out
)
{
static
bool
dtb_patch_rebuild
(
uint8_t
*
dtb
,
size_t
dtb_sz
,
const
char
*
file
)
{
if
(
!
out
)
if
(
MATCH
(
QCDT_MAGIC
))
{
out
=
in
;
auto
hdr
=
reinterpret_cast
<
qcdt_hdr
*>
(
dtb
);
size_t
dtb_sz
;
switch
(
hdr
->
version
)
{
uint8_t
*
dtb
;
case
1
:
fprintf
(
stderr
,
"Loading dtbs from [%s]
\n
"
,
in
);
fprintf
(
stderr
,
"QCDT v1
\n
"
);
mmap_ro
(
in
,
dtb
,
dtb_sz
);
return
dt_table_patch
<
qctable_v1
>
(
hdr
,
file
);
run_finally
f
([
&
]{
munmap
(
dtb
,
dtb_sz
);
});
case
2
:
fprintf
(
stderr
,
"QCDT v2
\n
"
);
if
(
MATCH
(
QCDT_MAGIC
))
{
return
dt_table_patch
<
qctable_v2
>
(
hdr
,
file
);
auto
hdr
=
reinterpret_cast
<
qcdt_hdr
*>
(
dtb
);
case
3
:
switch
(
hdr
->
version
)
{
fprintf
(
stderr
,
"QCDT v3
\n
"
);
case
1
:
return
dt_table_patch
<
qctable_v3
>
(
hdr
,
file
);
fprintf
(
stderr
,
"QCDT v1
\n
"
);
default
:
return
dt_table_patch
<
qctable_v1
>
(
hdr
,
out
);
return
false
;
case
2
:
}
fprintf
(
stderr
,
"QCDT v2
\n
"
);
}
else
if
(
MATCH
(
DTBH_MAGIC
))
{
return
dt_table_patch
<
qctable_v2
>
(
hdr
,
out
);
auto
hdr
=
reinterpret_cast
<
dtbh_hdr
*>
(
dtb
);
case
3
:
switch
(
hdr
->
version
)
{
fprintf
(
stderr
,
"QCDT v3
\n
"
);
case
2
:
return
dt_table_patch
<
qctable_v3
>
(
hdr
,
out
);
fprintf
(
stderr
,
"DTBH v2
\n
"
);
default
:
return
dt_table_patch
<
bhtable_v2
>
(
hdr
,
file
);
return
1
;
default
:
}
return
false
;
}
else
if
(
MATCH
(
DTBH_MAGIC
))
{
}
auto
hdr
=
reinterpret_cast
<
dtbh_hdr
*>
(
dtb
);
}
else
if
(
MATCH
(
PXADT_MAGIC
))
{
switch
(
hdr
->
version
)
{
auto
hdr
=
reinterpret_cast
<
pxadt_hdr
*>
(
dtb
);
case
2
:
switch
(
hdr
->
version
)
{
fprintf
(
stderr
,
"DTBH v2
\n
"
);
case
1
:
return
dt_table_patch
<
bhtable_v2
>
(
hdr
,
out
);
fprintf
(
stderr
,
"PXA-DT v1
\n
"
);
default
:
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
file
);
return
1
;
default
:
}
return
false
;
}
else
if
(
MATCH
(
PXADT_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
pxadt_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"PXA-DT v1
\n
"
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
out
);
default
:
return
1
;
}
}
else
if
(
MATCH
(
PXA19xx_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
pxa19xx_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"PXA-19xx v1
\n
"
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
out
);
default
:
return
1
;
}
}
else
if
(
MATCH
(
SPRD_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
sprd_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"SPRD v1
\n
"
);
return
dt_table_patch
<
sprdtable_v1
>
(
hdr
,
out
);
default
:
return
1
;
}
}
else
if
(
MATCH
(
DT_TABLE_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
dt_table_header
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
0
:
fprintf
(
stderr
,
"DT_TABLE v0
\n
"
);
return
dt_table_patch
<
dt_table_entry
>
(
hdr
,
out
);
default
:
return
1
;
}
}
else
{
return
blob_patch
(
dtb
,
dtb_sz
,
out
);
}
}
}
else
if
(
MATCH
(
PXA19xx_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
pxa19xx_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"PXA-19xx v1
\n
"
);
return
dt_table_patch
<
pxatable_v1
>
(
hdr
,
file
);
default
:
return
false
;
}
}
else
if
(
MATCH
(
SPRD_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
sprd_hdr
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
1
:
fprintf
(
stderr
,
"SPRD v1
\n
"
);
return
dt_table_patch
<
sprdtable_v1
>
(
hdr
,
file
);
default
:
return
false
;
}
}
else
if
(
MATCH
(
DT_TABLE_MAGIC
))
{
auto
hdr
=
reinterpret_cast
<
dt_table_header
*>
(
dtb
);
switch
(
hdr
->
version
)
{
case
0
:
fprintf
(
stderr
,
"DT_TABLE v0
\n
"
);
return
dt_table_patch
<
dt_table_entry
>
(
hdr
,
file
);
default
:
return
false
;
}
}
else
{
return
blob_patch
(
dtb
,
dtb_sz
,
file
);
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment