xref: /haiku/src/system/boot/Jamfile (revision 688acf41a377f25d4048dc6092edb86ac9179677)
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			--output-target=$(OUTPUT_TARGET) $(2) $(1)
135	else
136		# bfd supports pe + efi for arch
137		$(TARGET_OBJCOPY_$(TARGET_KERNEL_ARCH)) -j .text -j .sdata -j .data \
138			-j .dynamic -j .dynsym -j .rel* -j .rela* -j .reloc -j .dynstr \
139			--output-target=$(OUTPUT_TARGET) \
140			--subsystem=efi-app $(2) $(1)
141	fi
142}
143
144#
145# Sign our EFI Bootloader if a key has been provided
146# SignEFILoader <output> : <input> : <public_cert_file> : <private_key_file> ;
147#
148rule SignEFILoader
149{
150	local signedEFILoader = $(1) ;
151	local unsignedEFILoader = $(2) ;
152	local publicCert = $(3) ;
153	local privateKey = $(4) ;
154
155	Depends $(signedEFILoader) : $(unsignedEFILoader) ;
156
157	DB_CERT_FILE on $(signedEFILoader) = $(publicCert) ;
158	DB_KEY_FILE on $(signedEFILoader) = $(privateKey) ;
159}
160
161actions SignEFILoader
162{
163	$(RM) -f $(1)
164	echo "Signing EFI bootloader..."
165	sbsign --key $(DB_KEY_FILE) --cert $(DB_CERT_FILE) --output $(1) $(2)
166}
167
168#
169# Verify our EFI bootloader has been properly signed
170# VerifyEFILoader <loader> : <cert>
171#
172actions VerifyEFILoader
173{
174	sbverify --cert $(2) $(1)
175}
176
177
178#
179# U-boot image creation
180#
181rule BuildUImage image : data : args
182{
183    Depends $(image) : $(data) ;
184    LocalClean clean : $(image) ;
185    MKIMAGE_ARGS on $(image) = $(args) ;
186    colon on $(image) = ":" ;
187    local files = $(data:G=) ;
188    BuildUImage1 $(image) : $(data) ;
189}
190
191actions BuildUImage1
192{
193    mkimage $(MKIMAGE_ARGS) -d $(>:J=$(colon)) $(<)
194}
195
196#
197# Given a txt, generate a binary u-boot script
198#
199rule BuildUImageScript script : source
200{
201	Depends $(script) : $(source) ;
202	LocalClean clean : $(script) ;
203	SCRIPTNAME on $(script) = $(script) ;
204	FAKEOS on $(script) = "linux" ;
205	ARCH on $(script) = $(TARGET_ARCH) ;
206
207	if $(TARGET_ARCH) = "riscv64" || $(TARGET_ARCH) = "riscv32" {
208		ARCH on $(script) = "riscv" ;
209	}
210
211	BuildUImageScript1 $(script) : $(source) ;
212}
213
214actions BuildUImageScript1
215{
216	$(RM) -f $(1)
217	mkimage -A $(ARCH) -O $(FAKEOS) -T script -C none -n $(SCRIPTNAME) \
218		-d $(2) $(1)
219}
220
221# the bootsector on haiku_loader.amiga_m68k must be checksummed
222rule ChecksumAmigaLoader
223{
224	local haikuLoader = $(1) ;
225	local checksummer = <build>fixup_amiga_boot_checksum ;
226
227	Depends $(haikuLoader) : $(checksummer) ;
228
229	TARGET_CHECKSUM on $(haikuLoader) = $(checksummer) ;
230}
231
232actions ChecksumAmigaLoader bind TARGET_CHECKSUM
233{
234	$(TARGET_CHECKSUM) $(1)
235}
236
237# the bootsector on haiku_loader.atari_m68k must be checksummed
238rule ChecksumAtariLoader
239{
240	local haikuLoader = $(1) ;
241	local checksummer = <build>fixup_tos_boot_checksum ;
242
243	Depends $(haikuLoader) : $(checksummer) ;
244
245	TARGET_CHECKSUM on $(haikuLoader) = $(checksummer) ;
246}
247
248actions ChecksumAtariLoader bind TARGET_CHECKSUM {
249	$(TARGET_CHECKSUM) $(1)
250}
251
252
253
254# atari_m68k: AUTO folder PRG target
255# based on KernelLd
256rule AtariBootPrgLd
257{
258	# AtariBootPrgLd <name> : <objs> : <linkerscript> : <args> ;
259
260	LINK on $(1) = $(TARGET_LD_$(TARGET_KERNEL_ARCH)) ;
261
262	LINKFLAGS on $(1) = $(4) ;
263	if $(3) { LINKFLAGS on $(1) += --script=$(3) ; }
264
265	# Remove any preset LINKLIBS
266	LINKLIBS on $(1) = ;
267
268	# TODO: Do we really want to invoke SetupKernel here? The objects should
269	# have been compiled with KernelObjects anyway, so we're doing that twice.
270	SetupKernel $(2) ;
271
272	# Show that we depend on the libraries we need
273	LocalClean clean : $(1) ;
274	LocalDepends all : $(1) ;
275	Depends $(1) : $(2) ;
276
277	MakeLocateDebug $(1) ;
278
279}
280
281actions AtariBootPrgLd
282{
283	$(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ;
284}
285
286
287local extraSources = ;
288if $(TARGET_CC_IS_LEGACY_GCC_$(TARGET_KERNEL_ARCH)) = 1 {
289	extraSources += atomic.S ;
290}
291
292for platform in [ MultiBootSubDirSetup ] {
293	on $(platform) {
294		if $(TARGET_ARCH) = x86_64 && $(TARGET_BOOT_PLATFORM) = efi {
295			SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot os arch
296								x86_64 ] ;
297		} else {
298			SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot os arch
299									$(TARGET_KERNEL_ARCH_DIR) ] ;
300		}
301
302		SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix string ] ;
303		SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix stdlib ] ;
304		SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) libroot posix locale ] ;
305		SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) kernel lib ] ;
306
307		BootMergeObject boot_libroot_$(platform:G=).o :
308			abs.c
309			ctype_loc.cpp
310			ctype_l.cpp
311			ctype.cpp
312			LocaleData.cpp
313			qsort.c
314			kernel_vsprintf.cpp
315			memchr.c
316			memcmp.c
317			memmove.c
318			strdup.cpp
319			strndup.cpp
320			strlen.cpp
321			strnlen.cpp
322			strcmp.c
323			strcasecmp.c
324			strncmp.c
325			strcat.c
326			strcpy.c
327			strerror.c
328			strlcat.c
329			strlcpy.c
330			strchr.c
331			strrchr.c
332			strtol.c
333			strtoul.c
334			$(extraSources)
335		;
336
337		AddResources haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader.rdef ;
338
339		local archGrist = [ FGrist src system boot arch $(TARGET_KERNEL_ARCH_DIR) $(platform:G=) ] ;
340		local archObject = boot_arch_$(TARGET_KERNEL_ARCH).o ;
341		local ldflags = $(HAIKU_BOOT_LDFLAGS) $(HAIKU_BOOT_$(platform:G=:U)_LDFLAGS) ;
342		ldflags ?= $(TARGET_BOOT_LDFLAGS) ;
343
344		# needed by tarfs, packagefs, and video_splash.cpp
345		local supportLibs = [ FGrist boot_zlib.a ] ;
346		if [ FIsBuildFeatureEnabled zstd ] {
347			supportLibs += boot_zstd.a ;
348		}
349
350		# efi loader needs to be shared.
351		if $(TARGET_BOOT_PLATFORM) = efi {
352			ldflags += -shared ;
353			ldflags += -Map=$(TARGET_DEBUG_$(DEBUG)_LOCATE_TARGET)/efi.map ;
354		}
355
356		if $(TARGET_BOOT_PLATFORM) = riscv {
357			ldflags += -z notext ;
358		}
359
360		BootLd boot_loader_$(platform:G=) :
361			boot_platform_$(platform:G=).o
362			$(archObject:G=$(archGrist))
363			[ MultiBootGristFiles
364				boot_loader.a
365				boot_net.a
366				boot_partitions.a
367
368				# file systems
369				boot_bfs.a
370				boot_amiga_ffs.a
371				boot_tarfs.a
372				boot_fatfs.a
373				boot_packagefs.a
374
375				boot_loader.a
376					# a second time, so undefined references in the file systems can be
377					# resolved
378				$(supportLibs)
379			]
380
381			# libroot functions needed by the stage2 boot loader
382			boot_libroot_$(platform:G=).o
383
384			: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/boot_loader_$(platform:G=).ld
385			: $(ldflags)
386		;
387
388		switch $(TARGET_BOOT_PLATFORM) {
389			case efi :
390				if $(HAIKU_BOOT_$(platform:G=:U)_PRIVATE_KEYFILE) {
391					BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM).unsigned
392						: boot_loader_$(TARGET_BOOT_PLATFORM) ;
393					SignEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
394						: haiku_loader.$(TARGET_BOOT_PLATFORM).unsigned
395						: [ FDirName $(HAIKU_TOP) data boot efi keys DB.crt ]
396						: $(HAIKU_BOOT_$(platform:G=:U)_PRIVATE_KEYFILE) ;
397					VerifyEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
398						: [ FDirName $(HAIKU_TOP) data boot efi keys DB.crt ] ;
399				} else {
400					BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
401						: boot_loader_$(TARGET_BOOT_PLATFORM) ;
402				}
403
404				if $(TARGET_ARCH) = arm || $(TARGET_ARCH) = riscv64 {
405					# These EFI platforms need u-boot to get them going
406					BuildUImageScript boot.scr
407						: [ FDirName $(HAIKU_TOP) data boot u-boot boot-$(TARGET_ARCH).scr.txt ] ;
408				}
409
410			case bios_ia32 :
411				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
412
413			case pxe_ia32 :
414				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
415
416			case openfirmware :
417				BuildOpenFirmwareLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
418
419			case u-boot :
420				local loader_entry = `printf \"obase=16;ibase=16;10 + %x\\n\" $(HAIKU_BOOT_LOADER_BASE)|bc` ;
421				BuildUImage haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM)
422					:
423					-A $(TARGET_ARCH) -O linux -T kernel -C none
424					-a $(HAIKU_BOOT_LOADER_BASE) -e $(loader_entry)
425					-n 'Haiku $(TARGET_KERNEL_ARCH) loader' ;
426				BuildUImage haiku-floppyboot.tgz.$(TARGET_BOOT_PLATFORM) : haiku-floppyboot.tgz :
427					-A $(TARGET_ARCH) -O linux -T ramdisk -C none
428					-n 'Haiku $(TARGET_KERNEL_ARCH) floppyboot' ;
429				BuildUImageScript boot.scr
430					: [ FDirName $(HAIKU_TOP) data boot u-boot boot-$(TARGET_ARCH).scr.txt ] ;
431
432			case amiga_m68k :
433				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
434				ChecksumAmigaLoader haiku_loader.$(TARGET_BOOT_PLATFORM) ;
435
436			case atari_m68k :
437				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
438				ChecksumAtariLoader haiku_loader.$(TARGET_BOOT_PLATFORM) ;
439
440				AtariBootPrgLd haiku.prg :
441					boot_loader_$(TARGET_BOOT_PLATFORM)
442					: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/boot_prg_$(TARGET_BOOT_PLATFORM).ld
443					: -Bstatic
444				;
445
446			case riscv :
447				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
448
449			case next_m68k :
450				BuildAoutLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
451
452			case * :
453				Exit "Currently unsupported haiku_loader:" $(TARGET_BOOT_PLATFORM) ;
454		}
455	}
456}
457
458SubInclude HAIKU_TOP src system boot arch $(TARGET_KERNEL_ARCH_DIR) ;
459SubInclude HAIKU_TOP src system boot libs ;
460SubInclude HAIKU_TOP src system boot loader ;
461SubInclude HAIKU_TOP src system boot platform ;
462