@@ -135,62 +135,76 @@ mkimage(RootDir, BootFile, OutputFile, Segments) ->
135135 io :format (" =============================================~n " ),
136136 case file :open (OutputFile , [write , binary ]) of
137137 {ok , Fout } ->
138- lists :foldl (
139- fun (Segment , PrevOffset ) ->
140- SegmentOffset = from_hex (maps :get (offset , Segment )),
141- case PrevOffset of
142- undefined ->
143- no_padding ;
144- _ ->
145- case SegmentOffset > PrevOffset of
146- true ->
147- Padding = [
148- 16#FF
149- || _ <- lists :seq (1 , SegmentOffset - PrevOffset )
150- ],
151- io :format (" Padding ~p bytes~n " , [SegmentOffset - PrevOffset ]),
152- file :write (Fout , Padding );
153- false ->
154- throw (
155- io_lib :format (
156- " Error: insufficient space for segment ~p . Over by: ~p bytes~n " ,
157- [
158- maps :get (name , Segment ), PrevOffset - SegmentOffset
159- ]
160- )
161- )
162- end
163- end ,
164- SegmentPaths = [
165- replace (
166- " BOOT_FILE" , BootFile , replace (" ROOT_DIR" , RootDir , SegmentPath )
167- )
168- || SegmentPath <- maps :get (path , Segment )
169- ],
170- case try_read (SegmentPaths ) of
171- {ok , Data } ->
172- file :write (Fout , Data ),
173- io :format (" Wrote ~s (~p bytes) at offset ~s (~p )~n " , [
174- maps :get (name , Segment ),
175- byte_size (Data ),
176- maps :get (offset , Segment ),
177- SegmentOffset
178- ]),
179- SegmentOffset + byte_size (Data );
180- {error , Reason } ->
181- Fmt =
182- " Failed to read file ~p Reason: ~p ."
183- " Note that a full build is required before running this command." ,
184- throw (io_lib :format (Fmt , [SegmentPaths , Reason ]))
185- end
186- end ,
187- undefined ,
188- Segments
189- );
138+ write_segments (RootDir , BootFile , Fout , Segments );
190139 {error , Reason } ->
191140 throw (io_lib :format (" Failed to open ~s for writing. Reason: ~p " , [OutputFile , Reason ]))
192141 end .
193142
143+ % % @private
144+ write_segments (_RootDir , _BootFile , Fout , []) ->
145+ file :close (Fout );
146+ write_segments (RootDir , BootFile , Fout , [Segment | Segments ]) ->
147+ SegmentOffset = from_hex (maps :get (offset , Segment )),
148+ SegmentPaths = [
149+ replace (
150+ " BOOT_FILE" , BootFile , replace (" ROOT_DIR" , RootDir , SegmentPath )
151+ )
152+ || SegmentPath <- maps :get (path , Segment )
153+ ],
154+ SegmentEnd =
155+ case try_read (SegmentPaths ) of
156+ {ok , Data } ->
157+ file :write (Fout , Data ),
158+ io :format (" Wrote ~s (~p bytes) at offset ~s (~p )~n " , [
159+ maps :get (name , Segment ),
160+ byte_size (Data ),
161+ maps :get (offset , Segment ),
162+ SegmentOffset
163+ ]),
164+ SegmentOffset + byte_size (Data );
165+ {error , Reason } ->
166+ Fmt =
167+ " Failed to read file ~p Reason: ~p ."
168+ " Note that a full build is required before running this command." ,
169+ throw (io_lib :format (Fmt , [SegmentPaths , Reason ]))
170+ end ,
171+ if
172+ Segments == [] ->
173+ % % Pad the rest of the sector since we don't have a next offset to pad too
174+ SectorPad = 4096 - (SegmentEnd rem 4096 ),
175+ case SectorPad of
176+ 0 -> ok ;
177+ _ -> ok = pad_to_size (Fout , SectorPad )
178+ end ;
179+ true ->
180+ [PeekNext | _ ] = Segments ,
181+ NextOffset = from_hex (maps :get (offset , PeekNext )),
182+ case SegmentEnd > NextOffset of
183+ true ->
184+ throw (
185+ io_lib :format (
186+ " Error: insufficient space for segment ~p . Overflows partition by: ~p bytes~n " ,
187+ [maps :get (name , Segment ), SegmentEnd - NextOffset ]
188+ )
189+ );
190+ false ->
191+ PadSize = NextOffset - SegmentEnd ,
192+ case PadSize of
193+ 0 ->
194+ ok ;
195+ PadSize ->
196+ ok = pad_to_size (Fout , PadSize )
197+ end
198+ end
199+ end ,
200+ write_segments (RootDir , BootFile , Fout , Segments ).
201+
202+ % % @private
203+ pad_to_size (Fout , Size ) ->
204+ Padding = [16#FF || _ <- lists :seq (1 , Size )],
205+ io :format (" Padding ~p bytes~n " , [Size ]),
206+ file :write (Fout , Padding ).
207+
194208% % @private
195209try_read ([]) ->
196210 {error , not_found };
0 commit comments