@@ -12,12 +12,20 @@ use tokio_serial::SerialStream;
1212use crate :: bootloader_serial:: { issue_command, Command , Response } ;
1313use crate :: errors:: TockloaderError ;
1414
15+ /// This structure contains all relevant information about a tock application.
16+ ///
17+ /// All data is stored either within [TbfHeader]s, or [TbfFooter]s.
18+ ///
19+ /// See also <https://book.tockos.org/doc/tock_binary_format>
1520#[ derive( Debug ) ]
1621pub struct AppAttributes {
1722 pub tbf_header : TbfHeader ,
1823 pub tbf_footers : Vec < TbfFooter > ,
1924}
2025
26+ /// This structure represents a footer of a Tock application. Currently, footers
27+ /// only contain credentials, which are used to verify the integrity of the
28+ /// application.
2129#[ derive( Debug ) ]
2230pub struct TbfFooter {
2331 pub credentials : TbfFooterV2Credentials ,
@@ -40,7 +48,19 @@ impl AppAttributes {
4048 }
4149 }
4250
43- // TODO: Document this function
51+ /// Retrieve all application attributes from the device's memory using a
52+ /// probe-rs connection.
53+ ///
54+ /// Applications are layed out in memory sequentially, starting from the
55+ /// `appaddr` address. This function will attempt to read all applications
56+ /// until it fails to parse.
57+ ///
58+ /// # Parameters
59+ /// - `board_core`: Core access, obtained from a
60+ /// [ProbeRSConnection](crate::connection::ProbeRSConnection)
61+ /// - `addr`: The starting address of the first application in memory.
62+ /// Board-specific. See also
63+ /// [BoardSettings](crate::board_settings::BoardSettings).
4464 pub ( crate ) fn read_apps_data_probe (
4565 board_core : & mut Core ,
4666 addr : u64 ,
@@ -49,6 +69,8 @@ impl AppAttributes {
4969 let mut apps_counter = 0 ;
5070 let mut apps_details: Vec < AppAttributes > = vec ! [ ] ;
5171
72+ // All applications are stored sequentially in memory, so we read until
73+ // we fail to parse.
5274 loop {
5375 let mut appdata = vec ! [ 0u8 ; 8 ] ;
5476
@@ -60,6 +82,11 @@ impl AppAttributes {
6082 let header_size: u16 ;
6183 let total_size: u32 ;
6284
85+ // The first 8 bytes of the application data contain the TBF header
86+ // lengths and version.
87+ //
88+ // Note on expect: `read` always fills up the entire buffer, which
89+ // was previously declared as 8 bytes.
6390 match parse_tbf_header_lengths (
6491 & appdata
6592 . try_into ( )
@@ -81,14 +108,24 @@ impl AppAttributes {
81108 let header = parse_tbf_header ( & header_data, tbf_version)
82109 . map_err ( TockloaderError :: ParsingError ) ?;
83110
111+ // The end of the application binary marks the beginning of the
112+ // footer.
113+ //
114+ // TODO(george-cosma): This is not always true, `get_binary_end`
115+ // does not make sense if the application is just padding. This can
116+ // crash the process.
84117 let binary_end_offset = header. get_binary_end ( ) ;
85118
86119 let mut footers: Vec < TbfFooter > = vec ! [ ] ;
87120 let total_footers_size = total_size - binary_end_offset;
88121 let mut footer_offset = binary_end_offset;
89122 let mut footer_number = 0 ;
90123
124+ // Try to parse footers until we reach the end of the application.
91125 loop {
126+ // We don't know the size of the current footer, so we read the
127+ // remaining bytes in the application (`footer_offset -
128+ // binary_end_offset`) , even if we overread.
92129 let mut appfooter =
93130 vec ! [ 0u8 ; ( total_footers_size - ( footer_offset - binary_end_offset) ) as usize ] ;
94131
@@ -102,6 +139,7 @@ impl AppAttributes {
102139 footers. insert ( footer_number, TbfFooter :: new ( footer_info. 0 , footer_info. 1 ) ) ;
103140
104141 footer_number += 1 ;
142+ // we add 4 because that is the size of TL part of the TLV header (2 bytes type + 2 bytes length)
105143 footer_offset += footer_info. 1 + 4 ;
106144
107145 if footer_offset == total_size {
@@ -117,7 +155,19 @@ impl AppAttributes {
117155 }
118156 }
119157
120- // TODO: Document this function
158+ /// Retrieve all application attributes from the device's memory using a
159+ /// serial connection.
160+ ///
161+ /// Applications are layed out in memory sequentially, starting from the
162+ /// `appaddr` address. This function will attempt to read all applications
163+ /// until it fails to parse.
164+ ///
165+ /// # Parameters
166+ /// - `port`: Serial access, obtained from a
167+ /// [SerialConnection](crate::connection::SerialConnection)
168+ /// - `addr`: The starting address of the first application in memory.
169+ /// Board-specific. See also
170+ /// [BoardSettings](crate::board_settings::BoardSettings).
121171 pub ( crate ) async fn read_apps_data_serial (
122172 port : & mut SerialStream ,
123173 addr : u64 ,
@@ -126,20 +176,30 @@ impl AppAttributes {
126176 let mut apps_counter = 0 ;
127177 let mut apps_details: Vec < AppAttributes > = vec ! [ ] ;
128178
179+ // All applications are stored sequentially in memory, so we read until
180+ // we fail to parse.
129181 loop {
182+ // The tockloader protocol only supports 32-bit architectures,
183+ // though in the future support will be extended to 64-bit.
130184 let mut pkt = ( appaddr as u32 ) . to_le_bytes ( ) . to_vec ( ) ;
131185 let length = ( 8_u16 ) . to_le_bytes ( ) . to_vec ( ) ;
132186 for i in length {
133187 pkt. push ( i) ;
134188 }
135189
190+ // Read the first 8 bytes, which is the length of a TLV header.
136191 let ( _, appdata) =
137192 issue_command ( port, Command :: ReadRange , pkt, true , 8 , Response :: ReadRange ) . await ?;
138193
139194 let tbf_version: u16 ;
140195 let header_size: u16 ;
141196 let total_size: u32 ;
142197
198+ // The first 8 bytes of the application data contain the TBF header
199+ // lengths and version.
200+ //
201+ // Note on expect: `read` always fills up the entire buffer, which
202+ // was previously declared as 8 bytes.
143203 match parse_tbf_header_lengths (
144204 & appdata[ 0 ..8 ]
145205 . try_into ( )
@@ -159,6 +219,7 @@ impl AppAttributes {
159219 pkt. push ( i) ;
160220 }
161221
222+ // Read the rest of the header
162223 let ( _, header_data) = issue_command (
163224 port,
164225 Command :: ReadRange ,
@@ -178,7 +239,11 @@ impl AppAttributes {
178239 let mut footer_offset = binary_end_offset;
179240 let mut footer_number = 0 ;
180241
242+ // Try to parse footers until we reach the end of the application.
181243 loop {
244+ // We don't know the size of the current footer, so we read the
245+ // remaining bytes in the application (`footer_offset -
246+ // binary_end_offset`) , even if we overread.
182247 let mut pkt = ( appaddr as u32 + footer_offset) . to_le_bytes ( ) . to_vec ( ) ;
183248 let length = ( ( total_footers_size - ( footer_offset - binary_end_offset) ) as u16 )
184249 . to_le_bytes ( )
@@ -187,6 +252,7 @@ impl AppAttributes {
187252 pkt. push ( i) ;
188253 }
189254
255+ // Read the next header (and perhaps data beyond it)
190256 let ( _, appfooter) = issue_command (
191257 port,
192258 Command :: ReadRange ,
@@ -203,6 +269,7 @@ impl AppAttributes {
203269 footers. insert ( footer_number, TbfFooter :: new ( footer_info. 0 , footer_info. 1 ) ) ;
204270
205271 footer_number += 1 ;
272+ // we add 4 because that is the size of TL part of the TLV header (2 bytes type + 2 bytes length)
206273 footer_offset += footer_info. 1 + 4 ;
207274
208275 if footer_offset == total_size {
0 commit comments