@@ -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