xref: /haiku/src/system/boot/Jamfile (revision a5c0d1a80e18f50987966fda2005210092d7671b)
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.cpp
310			LocaleData.cpp
311			qsort.c
312			kernel_vsprintf.cpp
313			memchr.c
314			memcmp.c
315			memmove.c
316			strdup.cpp
317			strndup.cpp
318			strlen.cpp
319			strnlen.cpp
320			strcmp.c
321			strcasecmp.c
322			strncmp.c
323			strcat.c
324			strcpy.c
325			strerror.c
326			strlcat.c
327			strlcpy.c
328			strchr.c
329			strrchr.c
330			strtol.c
331			strtoul.c
332			$(extraSources)
333		;
334
335		AddResources haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader.rdef ;
336
337		local archGrist = [ FGrist src system boot arch $(TARGET_KERNEL_ARCH_DIR) $(platform:G=) ] ;
338		local archObject = boot_arch_$(TARGET_KERNEL_ARCH).o ;
339		local ldflags = $(HAIKU_BOOT_LDFLAGS) $(HAIKU_BOOT_$(platform:G=:U)_LDFLAGS) ;
340		ldflags ?= $(TARGET_BOOT_LDFLAGS) ;
341
342		# needed by tarfs, packagefs, and video_splash.cpp
343		local supportLibs = [ FGrist boot_zlib.a ] ;
344		if [ FIsBuildFeatureEnabled zstd ] {
345			supportLibs += boot_zstd.a ;
346		}
347
348		# efi loader needs to be shared.
349		if $(TARGET_BOOT_PLATFORM) = efi {
350			ldflags += -shared ;
351			ldflags += -Map=$(HAIKU_OUTPUT_DIR)/efi.map ;
352		}
353
354		if $(TARGET_BOOT_PLATFORM) = riscv {
355			ldflags += -z notext ;
356		}
357
358		BootLd boot_loader_$(platform:G=) :
359			boot_platform_$(platform:G=).o
360			$(archObject:G=$(archGrist))
361			[ MultiBootGristFiles
362				boot_loader.a
363				boot_net.a
364				boot_partitions.a
365
366				# file systems
367				boot_bfs.a
368				boot_amiga_ffs.a
369				boot_tarfs.a
370				boot_fatfs.a
371				boot_packagefs.a
372
373				boot_loader.a
374					# a second time, so undefined references in the file systems can be
375					# resolved
376				$(supportLibs)
377			]
378
379			# libroot functions needed by the stage2 boot loader
380			boot_libroot_$(platform:G=).o
381
382			: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/boot_loader_$(platform:G=).ld
383			: $(ldflags)
384		;
385
386		switch $(TARGET_BOOT_PLATFORM) {
387			case efi :
388				if $(HAIKU_BOOT_$(platform:G=:U)_PRIVATE_KEYFILE) {
389					BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM).unsigned
390						: boot_loader_$(TARGET_BOOT_PLATFORM) ;
391					SignEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
392						: haiku_loader.$(TARGET_BOOT_PLATFORM).unsigned
393						: [ FDirName $(HAIKU_TOP) data boot efi keys DB.crt ]
394						: $(HAIKU_BOOT_$(platform:G=:U)_PRIVATE_KEYFILE) ;
395					VerifyEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
396						: [ FDirName $(HAIKU_TOP) data boot efi keys DB.crt ] ;
397				} else {
398					BuildEFILoader haiku_loader.$(TARGET_BOOT_PLATFORM)
399						: boot_loader_$(TARGET_BOOT_PLATFORM) ;
400				}
401
402				if $(TARGET_ARCH) = arm || $(TARGET_ARCH) = riscv64 {
403					# These EFI platforms need u-boot to get them going
404					BuildUImageScript boot.scr
405						: [ FDirName $(HAIKU_TOP) data boot u-boot boot-$(TARGET_ARCH).scr.txt ] ;
406				}
407
408			case bios_ia32 :
409				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
410
411			case pxe_ia32 :
412				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
413
414			case openfirmware :
415				BuildOpenFirmwareLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
416
417			case u-boot :
418				local loader_entry = `printf \"obase=16;ibase=16;10 + %x\\n\" $(HAIKU_BOOT_LOADER_BASE)|bc` ;
419				BuildUImage haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM)
420					:
421					-A $(TARGET_ARCH) -O linux -T kernel -C none
422					-a $(HAIKU_BOOT_LOADER_BASE) -e $(loader_entry)
423					-n 'Haiku $(TARGET_KERNEL_ARCH) loader' ;
424				BuildUImage haiku-floppyboot.tgz.$(TARGET_BOOT_PLATFORM) : haiku-floppyboot.tgz :
425					-A $(TARGET_ARCH) -O linux -T ramdisk -C none
426					-n 'Haiku $(TARGET_KERNEL_ARCH) floppyboot' ;
427				BuildUImageScript boot.scr
428					: [ FDirName $(HAIKU_TOP) data boot u-boot boot-$(TARGET_ARCH).scr.txt ] ;
429
430			case amiga_m68k :
431				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
432				ChecksumAmigaLoader haiku_loader.$(TARGET_BOOT_PLATFORM) ;
433
434			case atari_m68k :
435				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
436				ChecksumAtariLoader haiku_loader.$(TARGET_BOOT_PLATFORM) ;
437
438				AtariBootPrgLd haiku.prg :
439					boot_loader_$(TARGET_BOOT_PLATFORM)
440					: $(HAIKU_TOP)/src/system/ldscripts/$(TARGET_ARCH)/boot_prg_$(TARGET_BOOT_PLATFORM).ld
441					: -Bstatic
442				;
443
444			case riscv :
445				BuildBiosLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
446
447			case next_m68k :
448				BuildAoutLoader haiku_loader.$(TARGET_BOOT_PLATFORM) : boot_loader_$(TARGET_BOOT_PLATFORM) ;
449
450			case * :
451				Exit "Currently unsupported haiku_loader:" $(TARGET_BOOT_PLATFORM) ;
452		}
453	}
454}
455
456SubInclude HAIKU_TOP src system boot arch $(TARGET_KERNEL_ARCH_DIR) ;
457SubInclude HAIKU_TOP src system boot libs ;
458SubInclude HAIKU_TOP src system boot loader ;
459SubInclude HAIKU_TOP src system boot platform ;
460