@@ -19,49 +19,70 @@ where
19
19
{
20
20
writer. iter_mut ( ) . for_each ( |x| * x = 0 ) ;
21
21
22
- let mut offset: usize = 0 ;
23
- {
24
- let mut dst = crate :: ser:: pointer:: Pointer :: new ( None ) ;
25
- let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
26
- let mut block = crate :: ser:: string_block:: StringBlock :: new ( writer, & mut offset) ;
27
- let mut ser =
28
- crate :: ser:: serializer:: SerializerInner :: new ( & mut dst, & mut block, & mut patch_list) ;
29
- let ser = crate :: ser:: serializer:: Serializer :: new ( & mut ser) ;
30
- data. serialize ( ser) ?;
22
+ let string_block_length = {
23
+ let mut offset: usize = 0 ;
24
+ {
25
+ let mut dst = crate :: ser:: pointer:: Pointer :: new ( None ) ;
26
+ let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
27
+ let mut block = crate :: ser:: string_block:: StringBlock :: new ( writer, & mut offset) ;
28
+ let mut ser =
29
+ crate :: ser:: serializer:: SerializerInner :: new ( & mut dst, & mut block, & mut patch_list) ;
30
+ let ser = crate :: ser:: serializer:: Serializer :: new ( & mut ser) ;
31
+ data. serialize ( ser) ?;
32
+ offset
33
+ } ;
34
+ {
35
+ let mut block = crate :: ser:: string_block:: StringBlock :: new ( writer, & mut offset) ;
36
+ block. align ( ) ;
37
+ } ;
38
+ offset
31
39
} ;
32
40
list. iter ( ) . for_each ( |patch| patch. init ( ) ) ;
33
41
// Write from bottom to top, to avoid overlap.
34
- for i in ( 0 ..offset ) . rev ( ) {
35
- writer[ writer. len ( ) - offset + i] = writer[ i] ;
42
+ for i in ( 0 ..string_block_length ) . rev ( ) {
43
+ writer[ writer. len ( ) - string_block_length + i] = writer[ i] ;
36
44
writer[ i] = 0 ;
37
45
}
38
- // TODO: make sure no out of bound.
39
46
40
- let writer_len = writer. len ( ) ;
41
- let ( data_block, string_block) = writer. split_at_mut ( writer. len ( ) - offset) ;
42
- let ( header, data_block) = data_block. split_at_mut ( HEADER_LEN as usize + RSVMAP_LEN ) ;
43
47
let struct_len = {
48
+ let ( data_block, string_block) = writer. split_at_mut ( writer. len ( ) - string_block_length) ;
49
+ let ( _, data_block) = data_block. split_at_mut ( HEADER_PADDING_LEN as usize + RSVMAP_LEN ) ;
44
50
let mut patch_list = crate :: ser:: patch:: PatchList :: new ( list) ;
45
- let mut block = crate :: ser:: string_block:: StringBlock :: new ( string_block, & mut offset) ;
51
+ let mut temp_length = string_block_length;
52
+ let mut block = crate :: ser:: string_block:: StringBlock :: new ( string_block, & mut temp_length) ;
46
53
let mut dst = crate :: ser:: pointer:: Pointer :: new ( Some ( data_block) ) ;
47
54
let mut ser =
48
55
crate :: ser:: serializer:: SerializerInner :: new ( & mut dst, & mut block, & mut patch_list) ;
49
56
let ser = crate :: ser:: serializer:: Serializer :: new ( & mut ser) ;
50
- data. serialize ( ser) ?
57
+ let struct_len = data. serialize ( ser) ?. 1 ;
58
+ assert_eq ! ( struct_len % 4 , 0 ) ; // As spec, structure block align with 4 bytes.
59
+ assert_eq ! ( temp_length, string_block_length) ; // StringBlock should be same with first run.
60
+ struct_len
61
+ } ;
62
+
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 ;
51
68
}
52
- . 1 ;
69
+
53
70
// Make header
54
71
{
72
+ let ( header, _) = writer. split_at_mut ( HEADER_LEN as usize ) ;
55
73
let header = unsafe { & mut * ( header. as_mut_ptr ( ) as * mut Header ) } ;
56
74
header. magic = u32:: from_be ( DEVICE_TREE_MAGIC ) ;
57
- header. total_size = u32:: from_be ( writer_len as u32 ) ;
58
- header. off_dt_struct = u32:: from_be ( HEADER_LEN + RSVMAP_LEN as u32 ) ;
59
- header. off_dt_strings = u32:: from_be ( ( writer_len - offset) as u32 ) ;
60
- header. off_mem_rsvmap = u32:: from_be ( HEADER_LEN ) ;
75
+ header. total_size = u32:: from_be (
76
+ HEADER_PADDING_LEN + ( RSVMAP_LEN + struct_len + string_block_length) as u32 ,
77
+ ) ;
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 ) ;
61
82
header. version = u32:: from_be ( SUPPORTED_VERSION ) ;
62
83
header. last_comp_version = u32:: from_be ( SUPPORTED_VERSION ) ; // TODO: maybe 16
63
- header. boot_cpuid_phys = 0 ; // TODO: wtf is this prop
64
- header. size_dt_strings = u32:: from_be ( offset as u32 ) ;
84
+ header. boot_cpuid_phys = 0 ; // TODO
85
+ header. size_dt_strings = u32:: from_be ( string_block_length as u32 ) ;
65
86
header. size_dt_struct = u32:: from_be ( struct_len as u32 ) ;
66
87
}
67
88
Ok ( ( ) )
0 commit comments