xref: /haiku/src/system/boot/Jamfile (revision 4a55cc230cf7566cadcbb23b1928eefff8aea9a2)
1SubDir HAIKU_TOP src system boot ;
2
3DEFINES += _BOOT_MODE ;
4
5UsePrivateHeaders [ FDirName libroot locale ] ;
6
7rule BuildOpenFirmwareLoader {
8	local haikuLoader = $(1) ;
9	local bootLoader = $(2) ;
10
11	Depends $(haikuLoader) : $(bootLoader) ;
12	MakeLocateDebug $(haikuLoader) ;
13
14	switch $(TARGET_ARCH) {
15		case ppc :
16			BuildCoffLoader $(haikuLoader) : $(bootLoader) ;
17		case sparc :
18			BuildAoutLoader $(haikuLoader) : $(bootLoader) ;
19		case * :
20			Exit "Currently unsupported arch:" $(TARGET_ARCH) ;
21	}
22}
23
24
25#
26# A.out haiku_loader creation
27#
28rule BuildAoutLoader {
29	local haikuLoader = $(1) ;
30	local bootLoader = $(2) ;
31
32	Depends $(haikuLoader) : $(bootLoader) ;
33	MakeLocateDebug $(haikuLoader) ;
34
35	ELF2AOUT on $(haikuLoader) = <build>elf2aout ;
36	Depends $(haikuLoader) : <build>elf2aout ;
37}
38
39actions BuildAoutLoader bind ELF2AOUT {
40	$(RM) -f $(1)
41	$(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) \
42	$(ELF2AOUT) -o $(1) $(2)
43}
44
45
46#
47# Coff haiku_loader creation
48#
49rule BuildCoffLoader {
50	local coffLoader = $(1) ;
51	local bootLoader = $(2) ;
52	switch $(TARGET_ARCH) {
53		case ppc :
54			COFF_FORMAT on $(coffLoader) = xcoff-powermac ;
55		case * :
56			Exit "Currently unsupported coff arch:" $(TARGET_ARCH) ;
57	}
58	HACK_COFF on $(coffLoader) = <build>hack-coff ;
59
60	Depends $(coffLoader) : <build>hack-coff ;
61}
62
63actions BuildCoffLoader bind HACK_COFF {
64	$(RM) -f $(1)
65	# get the address of the COFF entry
66	$(TARGET_OBJCOPY_$(TARGET_KERNEL_ARCH)) -O symbolsrec $(2) $(2).syms
67	EP=`grep _coff_start $(2).syms | tr -d '\r' | cut -d'$' -f2`
68	$(RM) -f $(2).syms
69	# copy to XCOFF format and patch the entry point
70	$(TARGET_OBJCOPY_$(TARGET_KERNEL_ARCH)) -O $(COFF_FORMAT) --set-start="0x${EP}" $(2) $(1)
71	#$(CP) $(2) $(1)
72	# fill-in some fields objcopy missed
73	$(HACK_COFF) $(1)
74}
75
76
77#
78# BIOS haiku_loader creation
79#
80rule BuildBiosLoader {
81	local haikuLoader = $(1) ;
82	local bootLoader = $(2) ;
83
84	Depends $(haikuLoader) : $(bootLoader) ;
85	MakeLocateDebug $(haikuLoader) ;
86
87	on $(1) ResAttr $(1) : $(RESFILES) : false ;
88	if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] {
89		SetType $(1) ;
90		MimeSet $(1) ;
91	}
92}
93
94actions BuildBiosLoader {
95	$(RM) -f $(1)
96	$(TARGET_OBJCOPY_$(TARGET_KERNEL_ARCH)) -O binary $(2) $(1)
97}
98
99
100#
101# EFI loader creation
102#
103rule BuildEFILoader {
104	local efiLoader = $(1) ;
105	local bootLoader = $(2) ;
106
107	Depends $(efiLoader) : $(bootLoader) ;
108
109	switch $(TARGET_ARCH) {
110		case x86 :
111			OUTPUT_TARGET on $(efiLoader) = pei-i386 ;
112		case x86_64 :
113			OUTPUT_TARGET on $(efiLoader) = pei-x86-64 ;
114		case arm :
115			OUTPUT_TARGET on $(efiLoader) = binary ;
116		case arm64 :
117			OUTPUT_TARGET on $(efiLoader) = binary ;
118		case riscv64 :
119			OUTPUT_TARGET on $(efiLoader) = binary ;
120		case * :
121			Exit "Currently unsupported arch:" $(TARGET_ARCH) ;
122	}
123
124	MakeLocateDebug $(efiLoader) ;
125}
126
127actions BuildEFILoader
128{
129	$(RM) -f $(1)
130	if [ "$(OUTPUT_TARGET)" = "binary" ]; then
131		# no bfd support, fake efi Pe header
132		$(TARGET_OBJCOPY_$(TARGET_KERNEL_ARCH)) -j .text -j .sdata -j .data \
133			-j .dynamic -j .dynsym -j .rel* -j .rela* -j .reloc -j .dynstr \
134			-j _haiku_revision \
135			--output-target=$(OUTPUT_TARGET) $(2) $(1)
136	else
137		# bfd supports pe + efi for arch
138		$(TARGET_OBJCOPY_$(TARGET_KERNEL_ARCH)) -j .text -j .sdata -j .data \
139			-j .dynamic -j .dynsym -j .rel* -j .rela* -j .reloc -j .dynstr \
140			-j _haiku_revision \
141			--output-target=$(OUTPUT_TARGET) \
142			--subsystem=efi-app $(2) $(1)
143	fi
144}
145
146#
147# Sign our EFI Bootloader if a key has been provided
148# SignEFILoader <output> : <input> : <public_cert_file> : <private_key_file> ;
149#
150rule SignEFILoader
151{
152	local signedEFILoader = $(1) ;
153	local unsignedEFILoader = $(2) ;
154	local publicCert = $(3) ;
155	local privateKey = $(4) ;
156
157	Depends $(signedEFILoader) : $(unsignedEFILoader) ;
158
159	DB_CERT_FILE on $(signedEFILoader) = $(publicCert) ;
160	DB_KEY_FILE on $(signedEFILoader) = $(privateKey) ;
161}
162
163actions SignEFILoader
164{
165	$(RM) -f $(1)
166	echo "Signing EFI bootloader..."
167	sbsign --key $(DB_KEY_FILE) --cert $(DB_CERT_FILE) --output $(1) $(2)
168}
169
170#
171# Verify our EFI bootloader has been properly signed
172# VerifyEFILoader <loader> : <cert>
173#
174actions VerifyEFILoader
175{
176	sbverify --cert $(2) $(1)
177}
178
179
180#
181# U-boot image creation
182#
183rule BuildUImage image : data : args
184{
185    Depends $(image) : $(data) ;
186    LocalClean clean : $(image) ;
187    MKIMAGE_ARGS on $(image) = $(args) ;
188    colon on $(image) = ":" ;
189    local files = $(data:G=) ;
190    BuildUImage1 $(image) : $(data) ;
191}
192
193actions BuildUImage1
194{
195    mkimage $(MKIMAGE_ARGS) -d $(>:J=$(colon)) $(<)
196}
197
198#
199# Given a txt, generate a binary u-boot script
200#
201rule BuildUImageScript script : source
202{
203	Depends $(script) : $(source) ;
204	LocalClean clean : $(script) ;
205	SCRIPTNAME on $(script) = $(script) ;
206	FAKEOS on $(script) = "linux" ;
207	ARCH on $(script) = $(TARGET_ARCH) ;
208
209	if $(TARGET_ARCH) = "riscv64" || $(TARGET_ARCH) = "riscv32" {
210		ARCH on $(script) = "riscv" ;
211	}
212
213	BuildUImageScript1 $(script) : $(source) ;
214}
215
216actions BuildUImageScript1
217{
218	$(RM) -f $(1)
219	mkimage -A $(ARCH) -O $(FAKEOS) -T script -C none -n $(SCRIPTNAME) \
220		-d $(2) $(1)
221}
222
223# the bootsector on haiku_loader.amiga_m68k must be checksummed
224rule ChecksumAmigaLoader
225{
226	local haikuLoader = $(1) ;
227	local checksummer = <build>fixup_amiga_boot_checksum ;
228
229	Depends $(haikuLoader) : $(checksummer) ;
230
231	TARGET_CHECKSUM on $(haikuLoader) = $(checksummer) ;
232}
233
234actions ChecksumAmigaLoader bind TARGET_CHECKSUM
235{
236	$(TARGET_CHECKSUM) $(1)
237}
238
239# the bootsector on haiku_loader.atari_m68k must be checksummed
240rule ChecksumAtariLoader
241{
242	local haikuLoader = $(1) ;
243	local checksummer = <build>fixup_tos_boot_checksum ;
244
245	Depends $(haikuLoader) : $(checksummer) ;
246
247	TARGET_CHECKSUM on $(haikuLoader) = $(checksummer) ;
248}
249
250actions ChecksumAtariLoader bind TARGET_CHECKSUM {
251	$(TARGET_CHECKSUM) $(1)
252}
253
254
255
256# atari_m68k: AUTO folder PRG target
257# based on KernelLd
258rule AtariBootPrgLd
259{
260	# AtariBootPrgLd <name> : <objs> : <linkerscript> : <args> ;
261
262	LINK on $(1) = $(TARGET_LD_$(TARGET_KERNEL_ARCH)) ;
263
264	LINKFLAGS on $(1) = $(4) ;
265	if $(3) { LINKFLAGS on $(1) += --script=$(3) ; }
266
267	# Remove any preset LINKLIBS
268	LINKLIBS on $(1) = ;
269
270	# TODO: Do we really want to invoke SetupKernel here? The objects should
271	# have been compiled with KernelObjects anyway, so we're doing that twice.
272	SetupKernel $(2) ;
273
274	# Show that we depend on the libraries we need
275	LocalClean clean : $(1) ;
276	LocalDepends all : $(1) ;
277	Depends $(1) : $(2) ;
278
279	MakeLocateDebug $(1) ;
280
281}
282
283actions AtariBootPrgLd
284{
285	$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ;
286}
287
288
289local extraSources = ;
290if $(TARGET_CC_IS_LEGACY_GCC_$(TARGET_KERNEL_ARCH)) = 1 {
291	extraSources += atomic.S ;
292}
293
294for platform in [ MultiBootSubDirSetup ] {
295	on $(platform) {
296		if $(TARGET_ARCH) = x86_64 && $(TARGET_BOOT_PLATFORM) = efi {
297			SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot os arch
298								x86_64 ] ;
299		} else {
300			SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot os arch
301									$(TARGET_KERNEL_ARCH_DIR) ] ;
302		}
303
304		SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix string ] ;
305		SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix stdlib ] ;
306		SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix locale ] ;
307		SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) kernel lib ] ;
308
309		BootMergeObject boot_libroot_$(platform:G=).o :
310			abs.c
311			ctype_loc.cpp
312			ctype_l.cpp
313			ctype.cpp
314			LocaleData.cpp
315			qsort.c
316			kernel_vsprintf.cpp
317			memchr.c
318			memcmp.c
319			memmove.c
320			strdup.cpp
321			strndup.cpp
322			strlen.cpp
323			strnlen.cpp
324			strcmp.c
325			strcasecmp.c
326			strncmp.c
327			strcat.c
328			strcpy.c
329			strerror.c
330			strlcat.c
331			strlcpy.c
332			strchr.c
333			strrchr.c
334			strtol.c
335			strtoul.c
336			$(extraSources)
337		;
338
339		AddResources haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader.rdef ;
340
341		local archGrist = [ FGrist src system boot arch $(TARGET_KERNEL_ARCH_DIR) $(platform:G=) ] ;
342		local archObject = boot_arch_$(TARGET_KERNEL_ARCH).o ;
343		local ldflags = $(HAIKU_BOOT_LDFLAGS) $(HAIKU_BOOT_$(platform:G=:U)_LDFLAGS) ;
344		ldflags ?= $(TARGET_BOOT_LDFLAGS) ;
345
346		# needed by tarfs, packagefs, and video_splash.cpp
347		local supportLibs = [ FGrist boot_zlib.a ] ;
348		if [ FIsBuildFeatureEnabled zstd ] {
349			supportLibs += boot_zstd.a ;
350		}
351
352		# efi loader needs to be shared.
353		if $(TARGET_BOOT_PLATFORM) = efi {
354			ldflags += -shared ;
355			ldflags += -Map=$(TARGET_DEBUG_$(DEBUG)_LOCATE_TARGET)/efi.map ;
356		}
357
358		if $(TARGET_BOOT_PLATFORM) = riscv {
359			ldflags += -z notext ;
360		}
361
362		BootLd boot_loader_$(platform:G=) :
363			boot_platform_$(platform:G=).o
364			$(archObject:G=$(archGrist))
365			[ MultiBootGristFiles
366				boot_loader.a
367				boot_net.a
368				boot_partitions.a
369
370				# file systems
371				boot_bfs.a
372				boot_amiga_ffs.a
373				boot_tarfs.a
374				boot_fatfs.a
375				boot_packagefs.a
376
377				boot_loader.a
378					# a second time, so undefined references in the file systems can be
379					# resolved
380				$(supportLibs)
381			]
382
383			# libroot functions needed by the stage2 boot loader
384			boot_libroot_$(platform:G=).o
385
386			: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/boot_loader_$(platform:G=).ld
387			: $(ldflags)
388		;
389
390		MakeLocate <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) : [ FDirName $(TARGET_DEBUG_$(DEBUG)_LOCATE_TARGET) revisioned ] ;
391		CopySetHaikuRevision <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
392
393		switch $(TARGET_BOOT_PLATFORM) {
394			case efi :
395				if $(HAIKU_BOOT_$(platform:G=:U)_PRIVATE_KEYFILE) {
396					BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM).unsigned
397						: <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
398					SignEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
399						: haiku_loader.$(TARGET_BOOT_PLATFORM).unsigned
400						: [ FDirName $(HAIKU_TOP) data boot efi keys DB.crt ]
401						: $(HAIKU_BOOT_$(platform:G=:U)_PRIVATE_KEYFILE) ;
402					VerifyEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
403						: [ FDirName $(HAIKU_TOP) data boot efi keys DB.crt ] ;
404				} else {
405					BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
406						: <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
407				}
408
409				if $(TARGET_ARCH) = arm || $(TARGET_ARCH) = riscv64 {
410					# These EFI platforms need u-boot to get them going
411					BuildUImageScript boot.scr
412						: [ FDirName $(HAIKU_TOP) data boot u-boot boot-$(TARGET_ARCH).scr.txt ] ;
413				}
414
415			case bios_ia32 :
416				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
417
418			case pxe_ia32 :
419				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
420
421			case openfirmware :
422				BuildOpenFirmwareLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
423
424			case u-boot :
425				local loader_entry = `printf \"obase=16;ibase=16;10 + %x\\n\" $(HAIKU_BOOT_LOADER_BASE)|bc` ;
426				BuildUImage haiku_loader.$(TARGET_BOOT_PLATFORM) : <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM)
427					:
428					-A $(TARGET_ARCH) -O linux -T kernel -C none
429					-a $(HAIKU_BOOT_LOADER_BASE) -e $(loader_entry)
430					-n 'Haiku $(TARGET_KERNEL_ARCH) loader' ;
431				BuildUImage haiku-floppyboot.tgz.$(TARGET_BOOT_PLATFORM) : haiku-floppyboot.tgz :
432					-A $(TARGET_ARCH) -O linux -T ramdisk -C none
433					-n 'Haiku $(TARGET_KERNEL_ARCH) floppyboot' ;
434				BuildUImageScript boot.scr
435					: [ FDirName $(HAIKU_TOP) data boot u-boot boot-$(TARGET_ARCH).scr.txt ] ;
436
437			case amiga_m68k :
438				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
439				ChecksumAmigaLoader haiku_loader.$(TARGET_BOOT_PLATFORM) ;
440
441			case atari_m68k :
442				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
443				ChecksumAtariLoader haiku_loader.$(TARGET_BOOT_PLATFORM) ;
444
445				AtariBootPrgLd haiku.prg :
446					<revisioned>boot_loader_$(TARGET_BOOT_PLATFORM)
447					: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/boot_prg_$(TARGET_BOOT_PLATFORM).ld
448					: -Bstatic
449				;
450
451			case riscv :
452				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
453
454			case next_m68k :
455				BuildAoutLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : <revisioned>boot_loader_$(TARGET_BOOT_PLATFORM) ;
456
457			case * :
458				Exit "Currently unsupported haiku_loader:" $(TARGET_BOOT_PLATFORM) ;
459		}
460	}
461}
462
463SubInclude HAIKU_TOP src system boot arch $(TARGET_KERNEL_ARCH_DIR) ;
464SubInclude HAIKU_TOP src system boot libs ;
465SubInclude HAIKU_TOP src system boot loader ;
466SubInclude HAIKU_TOP src system boot platform ;
467