@@ -135,62 +135,68 @@ 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 = case try_read (SegmentPaths ) of
155+ {ok , Data } ->
156+ file :write (Fout , Data ),
157+ io :format (" Wrote ~s (~p bytes) at offset ~s (~p )~n " , [
158+ maps :get (name , Segment ),
159+ byte_size (Data ),
160+ maps :get (offset , Segment ),
161+ SegmentOffset
162+ ]),
163+ SegmentOffset + byte_size (Data );
164+ {error , Reason } ->
165+ Fmt =
166+ " Failed to read file ~p Reason: ~p ."
167+ " Note that a full build is required before running this command." ,
168+ throw (io_lib :format (Fmt , [SegmentPaths , Reason ]))
169+ end ,
170+ if Segments == [] -> ok ;
171+ true ->
172+ [PeekNext | _ ] = Segments ,
173+ NextOffset = from_hex (maps :get (offset , PeekNext )),
174+ case SegmentEnd > NextOffset of
175+ true ->
176+ throw (
177+ io_lib :format (
178+ " Error: insufficient space for segment ~p . Overflows partition by: ~p bytes~n " ,
179+ [maps :get (name , Segment ), SegmentEnd - NextOffset ]
180+ )
181+ );
182+ false ->
183+ PadSize = NextOffset - SegmentEnd ,
184+ case PadSize of
185+ 0 ->
186+ ok ;
187+ PadSize ->
188+ Padding = [
189+ 16#FF
190+ || _ <- lists :seq (1 , PadSize )
191+ ],
192+ io :format (" Padding ~p bytes~n " , [PadSize ]),
193+ file :write (Fout , Padding ),
194+ ok
195+ end
196+ end
197+ end ,
198+ write_segments (RootDir , BootFile , Fout , Segments ).
199+
194200% % @private
195201try_read ([]) ->
196202 {error , not_found };
0 commit comments