11pub mod patch;
22pub mod pointer;
33pub mod serializer;
4+
45pub mod string_block;
56
67use crate :: common:: * ;
@@ -10,13 +11,17 @@ use crate::ser::patch::Patch;
1011const RSVMAP_LEN : usize = 16 ;
1112
1213/// Make dtb header with structure block and string block length.
13- fn make_header < ' se > ( writer : & ' se mut [ u8 ] , structure_length : u32 , string_block_length : u32 ) {
14+ fn make_header < ' se > (
15+ writer : & ' se mut [ u8 ] ,
16+ structure_length : u32 ,
17+ string_block_length : u32 ,
18+ ) -> usize {
1419 let ( header, _) = writer. split_at_mut ( HEADER_LEN as usize ) ;
1520 let header = unsafe { & mut * ( header. as_mut_ptr ( ) as * mut Header ) } ;
21+ let total_size =
22+ HEADER_PADDING_LEN + RSVMAP_LEN as u32 + structure_length + string_block_length;
1623 header. magic = u32:: from_be ( DEVICE_TREE_MAGIC ) ;
17- header. total_size = u32:: from_be (
18- HEADER_PADDING_LEN + RSVMAP_LEN as u32 + structure_length + string_block_length,
19- ) ;
24+ header. total_size = u32:: from_be ( total_size) ;
2025 assert_eq ! ( header. total_size % 8 , 0 ) ;
2126 header. off_dt_struct = u32:: from_be ( HEADER_PADDING_LEN + RSVMAP_LEN as u32 ) ;
2227 header. off_dt_strings = u32:: from_be ( HEADER_PADDING_LEN + RSVMAP_LEN as u32 + structure_length) ;
@@ -26,61 +31,64 @@ fn make_header<'se>(writer: &'se mut [u8], structure_length: u32, string_block_l
2631 header. boot_cpuid_phys = 0 ; // TODO
2732 header. size_dt_strings = u32:: from_be ( string_block_length as u32 ) ;
2833 header. size_dt_struct = u32:: from_be ( structure_length as u32 ) ;
34+
35+ total_size as usize
2936}
3037
3138/// Serialize the data to dtb, with a list fof Patch, write to the `writer`.
3239///
3340/// We do run-twice on convert, first time to generate string block, second time todo real
3441/// structure.
35- pub fn to_dtb < ' se , T > ( data : & T , list : & ' se [ Patch < ' se > ] , writer : & ' se mut [ u8 ] ) -> Result < ( ) , Error >
42+ pub fn to_dtb < ' se , T > (
43+ data : & T ,
44+ list : & ' se [ Patch < ' se > ] ,
45+ writer : & ' se mut [ u8 ] ,
46+ ) -> Result < usize , Error >
3647where
3748 T : serde:: ser:: Serialize ,
3849{
3950 writer. iter_mut ( ) . for_each ( |x| * x = 0 ) ;
4051
4152 let string_block_length = {
4253 let mut offset: usize = 0 ;
54+ let mut block = crate :: ser:: string_block:: StringBlock :: new ( Some ( writer) , & mut offset) ;
55+ let mut dst = crate :: ser:: pointer:: Pointer :: new ( None ) ;
56+ let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
57+ let mut ser =
58+ crate :: ser:: serializer:: SerializerInner :: new ( & mut dst, & mut block, & mut patch_list) ;
59+ let ser = crate :: ser:: serializer:: Serializer :: new ( & mut ser) ;
60+ data. serialize ( ser) ?;
4361 {
44- let mut dst = crate :: ser:: pointer:: Pointer :: new ( None ) ;
45- let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
46- let mut block = crate :: ser:: string_block:: StringBlock :: new ( writer, & mut offset) ;
47- let mut ser =
48- crate :: ser:: serializer:: SerializerInner :: new ( & mut dst, & mut block, & mut patch_list) ;
49- let ser = crate :: ser:: serializer:: Serializer :: new ( & mut ser) ;
50- data. serialize ( ser) ?;
51- offset
52- } ;
53- {
54- let mut block = crate :: ser:: string_block:: StringBlock :: new ( writer, & mut offset) ;
62+ let mut block = crate :: ser:: string_block:: StringBlock :: new ( Some ( writer) , & mut offset) ;
5563 block. align ( ) ;
5664 } ;
5765 offset
5866 } ;
5967
6068 list. iter ( ) . for_each ( |patch| patch. init ( ) ) ;
6169 let bottom_string_block_start = writer. len ( ) - string_block_length;
62- // Write to bottom, avoid overlap.
63- unsafe {
64- core:: ptr:: copy (
65- core:: ptr:: addr_of!( writer[ 0 ] ) ,
66- core:: ptr:: addr_of_mut!( writer[ bottom_string_block_start] ) ,
67- string_block_length,
68- ) ;
69- }
70+
71+ // Clear string block
7072 writer[ 0 ..string_block_length] . fill ( 0 ) ;
7173
7274 let structure_length = {
7375 let ( data_block, string_block) = writer. split_at_mut ( writer. len ( ) - string_block_length) ;
7476 let ( _, data_block) = data_block. split_at_mut ( HEADER_PADDING_LEN as usize + RSVMAP_LEN ) ;
7577
7678 let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
77- let mut temp_length = string_block_length;
78- let mut block = crate :: ser:: string_block:: StringBlock :: new ( string_block, & mut temp_length) ;
79+ let mut temp_length = 0 ;
80+ let mut block =
81+ crate :: ser:: string_block:: StringBlock :: new ( Some ( string_block) , & mut temp_length) ;
7982 let mut dst = crate :: ser:: pointer:: Pointer :: new ( Some ( data_block) ) ;
8083 let mut ser =
8184 crate :: ser:: serializer:: SerializerInner :: new ( & mut dst, & mut block, & mut patch_list) ;
8285 let ser = crate :: ser:: serializer:: Serializer :: new ( & mut ser) ;
8386 let struct_len = data. serialize ( ser) ?. 1 ;
87+ {
88+ let mut block =
89+ crate :: ser:: string_block:: StringBlock :: new ( Some ( writer) , & mut temp_length) ;
90+ block. align ( ) ;
91+ } ;
8492 assert_eq ! ( struct_len % 4 , 0 ) ; // As spec, structure block align with 4 bytes.
8593 assert_eq ! ( temp_length, string_block_length) ; // StringBlock should be same with first run.
8694 struct_len
@@ -97,9 +105,32 @@ where
97105 }
98106 writer[ bottom_string_block_start..] . fill ( 0 ) ;
99107
100- make_header ( writer, structure_length as u32 , string_block_length as u32 ) ;
108+ let result = make_header ( writer, structure_length as u32 , string_block_length as u32 ) ;
109+
110+ Ok ( result)
111+ }
112+
113+ #[ cfg( feature = "alloc" ) ]
114+ pub fn probe_dtb_length < ' se , T > ( data : & T , list : & ' se [ Patch < ' se > ] ) -> Result < usize , Error >
115+ where
116+ T : serde:: ser:: Serialize ,
117+ {
118+ let mut offset: usize = 0 ;
119+ let structure_length = {
120+ let mut dst = crate :: ser:: pointer:: Pointer :: new ( None ) ;
121+ let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
122+ let mut block = crate :: ser:: string_block:: StringBlock :: new ( None , & mut offset) ;
123+ let mut ser =
124+ crate :: ser:: serializer:: SerializerInner :: new ( & mut dst, & mut block, & mut patch_list) ;
125+ let ser = crate :: ser:: serializer:: Serializer :: new ( & mut ser) ;
126+ data. serialize ( ser) ?. 1
127+ } ;
128+ {
129+ let mut block = crate :: ser:: string_block:: StringBlock :: new ( None , & mut offset) ;
130+ block. align ( ) ;
131+ } ;
101132
102- Ok ( ( ) )
133+ Ok ( structure_length + offset + HEADER_PADDING_LEN as usize + RSVMAP_LEN )
103134}
104135
105136#[ derive( Debug ) ]
0 commit comments