@@ -6,12 +6,16 @@ pub mod string_block;
66use crate :: common:: * ;
77use crate :: ser:: patch:: Patch ;
88
9+ const RSVMAP_LEN : usize = 16 ;
10+
911/// We do run-twice on convert, first time to generate string block, second time todo real
1012/// structure.
1113pub fn to_dtb < ' se , T > ( data : & T , list : & ' se [ Patch < ' se > ] , writer : & ' se mut [ u8 ] ) -> Result < ( ) , Error >
1214where
1315 T : serde:: ser:: Serialize ,
1416{
17+ writer. iter_mut ( ) . for_each ( |x| * x = 0 ) ;
18+
1519 let mut offset: usize = 0 ;
1620 {
1721 let mut dst = crate :: ser:: pointer:: Pointer :: new ( None ) ;
@@ -22,24 +26,37 @@ where
2226 data. serialize ( & mut ser) ?;
2327 } ;
2428 list. iter ( ) . for_each ( |patch| patch. init ( ) ) ;
25- {
26- // Write from bottom to top, to avoid overlap.
27- for i in ( 0 ..offset) . rev ( ) {
28- writer[ writer. len ( ) - offset + i] = writer[ i] ;
29- writer[ i] = 0 ;
30- }
31- // TODO: make sure no out of bound.
29+ // Write from bottom to top, to avoid overlap.
30+ for i in ( 0 ..offset) . rev ( ) {
31+ writer[ writer. len ( ) - offset + i] = writer[ i] ;
32+ writer[ i] = 0 ;
33+ }
34+ // TODO: make sure no out of bound.
3235
33- // -1 for end zero.
34- let ( data_block, string_block) = writer. split_at_mut ( writer. len ( ) - offset) ;
35- let ( _, data_block) = data_block. split_at_mut ( size_of :: < crate :: common:: Header > ( ) ) ;
36+ let writer_len = writer. len ( ) ;
37+ let ( data_block, string_block) = writer. split_at_mut ( writer. len ( ) - offset) ;
38+ let ( header, data_block) = data_block. split_at_mut ( HEADER_LEN as usize + RSVMAP_LEN ) ;
39+ {
3640 let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
3741 let mut block = crate :: ser:: string_block:: StringBlock :: new ( string_block, & mut offset) ;
3842 let mut dst = crate :: ser:: pointer:: Pointer :: new ( Some ( data_block) ) ;
3943 let mut ser =
4044 crate :: ser:: serializer:: Serializer :: new ( & mut dst, & mut block, & mut patch_list) ;
41- ser. dst . step_by_u32 ( FDT_END ) ;
4245 data. serialize ( & mut ser) ?;
46+ ser. dst . step_by_u32 ( FDT_END ) ;
47+ }
48+ {
49+ let header = unsafe { & mut * ( header. as_mut_ptr ( ) as * mut Header ) } ;
50+ header. magic = u32:: from_be ( DEVICE_TREE_MAGIC ) ;
51+ header. total_size = u32:: from_be ( writer_len as u32 ) ;
52+ header. off_dt_struct = u32:: from_be ( HEADER_LEN + RSVMAP_LEN as u32 ) ;
53+ header. off_dt_strings = u32:: from_be ( ( writer_len - offset) as u32 ) ;
54+ header. off_mem_rsvmap = u32:: from_be ( HEADER_LEN ) ;
55+ header. version = u32:: from_be ( SUPPORTED_VERSION ) ;
56+ header. last_comp_version = u32:: from_be ( SUPPORTED_VERSION ) ; // TODO: maybe 16
57+ header. boot_cpuid_phys = 0 ; // TODO: wtf is this prop
58+ header. size_dt_strings = u32:: from_be ( offset as u32 ) ;
59+ header. size_dt_struct = u32:: from_be ( data_block. len ( ) as u32 ) ; // TODO: correct?
4360 }
4461 Ok ( ( ) )
4562}
0 commit comments