@@ -9,6 +9,25 @@ use crate::ser::patch::Patch;
99// TODO: set reverse map
1010const RSVMAP_LEN : usize = 16 ;
1111
12+ /// 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+ let ( header, _) = writer. split_at_mut ( HEADER_LEN as usize ) ;
15+ let header = unsafe { & mut * ( header. as_mut_ptr ( ) as * mut Header ) } ;
16+ 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+ ) ;
20+ assert_eq ! ( header. total_size % 8 , 0 ) ;
21+ header. off_dt_struct = u32:: from_be ( HEADER_PADDING_LEN + RSVMAP_LEN as u32 ) ;
22+ header. off_dt_strings = u32:: from_be ( HEADER_PADDING_LEN + RSVMAP_LEN as u32 + structure_length) ;
23+ header. off_mem_rsvmap = u32:: from_be ( HEADER_PADDING_LEN ) ;
24+ header. version = u32:: from_be ( SUPPORTED_VERSION ) ;
25+ header. last_comp_version = u32:: from_be ( SUPPORTED_VERSION ) ; // TODO: maybe 16
26+ header. boot_cpuid_phys = 0 ; // TODO
27+ header. size_dt_strings = u32:: from_be ( string_block_length as u32 ) ;
28+ header. size_dt_struct = u32:: from_be ( structure_length as u32 ) ;
29+ }
30+
1231/// Serialize the data to dtb, with a list fof Patch, write to the `writer`.
1332///
1433/// We do run-twice on convert, first time to generate string block, second time todo real
@@ -37,16 +56,23 @@ where
3756 } ;
3857 offset
3958 } ;
59+
4060 list. iter ( ) . for_each ( |patch| patch. init ( ) ) ;
41- // Write from bottom to top, to avoid overlap.
42- for i in ( 0 ..string_block_length) . rev ( ) {
43- writer[ writer. len ( ) - string_block_length + i] = writer[ i] ;
44- writer[ i] = 0 ;
61+ 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+ ) ;
4569 }
70+ writer[ 0 ..string_block_length] . fill ( 0 ) ;
4671
47- let struct_len = {
72+ let structure_length = {
4873 let ( data_block, string_block) = writer. split_at_mut ( writer. len ( ) - string_block_length) ;
4974 let ( _, data_block) = data_block. split_at_mut ( HEADER_PADDING_LEN as usize + RSVMAP_LEN ) ;
75+
5076 let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
5177 let mut temp_length = string_block_length;
5278 let mut block = crate :: ser:: string_block:: StringBlock :: new ( string_block, & mut temp_length) ;
@@ -60,31 +86,19 @@ where
6086 struct_len
6187 } ;
6288
63- // Align to 8-bytes.
64- for i in 0 ..string_block_length {
65- writer[ HEADER_PADDING_LEN as usize + RSVMAP_LEN + struct_len + i] =
66- writer[ writer. len ( ) - string_block_length + i] ;
67- writer[ writer. len ( ) - string_block_length + i] = 0 ;
68- }
69-
70- // Make header
71- {
72- let ( header, _) = writer. split_at_mut ( HEADER_LEN as usize ) ;
73- let header = unsafe { & mut * ( header. as_mut_ptr ( ) as * mut Header ) } ;
74- header. magic = u32:: from_be ( DEVICE_TREE_MAGIC ) ;
75- header. total_size = u32:: from_be (
76- HEADER_PADDING_LEN + ( RSVMAP_LEN + struct_len + string_block_length) as u32 ,
89+ unsafe {
90+ core:: ptr:: copy (
91+ core:: ptr:: addr_of!( writer[ writer. len( ) - string_block_length] ) ,
92+ core:: ptr:: addr_of_mut!(
93+ writer[ HEADER_PADDING_LEN as usize + RSVMAP_LEN + structure_length]
94+ ) ,
95+ string_block_length,
7796 ) ;
78- assert_eq ! ( header. total_size % 8 , 0 ) ;
79- header. off_dt_struct = u32:: from_be ( HEADER_PADDING_LEN + RSVMAP_LEN as u32 ) ;
80- header. off_dt_strings = u32:: from_be ( HEADER_PADDING_LEN + ( RSVMAP_LEN + struct_len) as u32 ) ;
81- header. off_mem_rsvmap = u32:: from_be ( HEADER_PADDING_LEN ) ;
82- header. version = u32:: from_be ( SUPPORTED_VERSION ) ;
83- header. last_comp_version = u32:: from_be ( SUPPORTED_VERSION ) ; // TODO: maybe 16
84- header. boot_cpuid_phys = 0 ; // TODO
85- header. size_dt_strings = u32:: from_be ( string_block_length as u32 ) ;
86- header. size_dt_struct = u32:: from_be ( struct_len as u32 ) ;
8797 }
98+ writer[ bottom_string_block_start..] . fill ( 0 ) ;
99+
100+ make_header ( writer, structure_length as u32 , string_block_length as u32 ) ;
101+
88102 Ok ( ( ) )
89103}
90104
0 commit comments