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