# Makefile for i386 boot program # define FLOPPY and SMALL using DEFINES macro as necessary DIR = boot2 include ../MakePaths.dir OPTIM = -Os -Oz CFLAGS = $(RC_CFLAGS) $(OPTIM) $(MORECPP) -arch i386 -g -Wmost -Werror \ -DSAIO_INTERNAL_USER \ -Wno-deprecated-declarations \ $(STANDALONE_CFLAGS) DEFINES= CONFIG = hd SYMDIR = $(SYMROOT) LIBSADIR = ../libsa LIBSAIODIR = ../libsaio UTILDIR = ../util INC = -I. -I.. -I$(SYMDIR) -I$(LIBSADIR) -I$(LIBSAIODIR) -I$(UTILDIR) ifneq "" "$(wildcard /bin/mkdirs)" MKDIRS = /bin/mkdirs else MKDIRS = /bin/mkdir -p endif AS = as LD = gcc # LIBS= -lc_static LIBS= -L$(SYMDIR) -lsaio -lsa LIBDEP= $(SYMDIR)/libsaio.a $(SYMDIR)/libsa.a OTHER_FILES = INSTALLDIR = $(DSTROOT)/usr/standalone/i386 VPATH = $(OBJROOT):$(SYMROOT) # The ordering is important; # sectorder.o and boot2.o must be the first two objects. OBJS = sectorder.o boot2.o loseg_utils.o boot.o graphics.o drivers.o prompt.o options.o lzss.o mboot.o preboot.o # button.o browser.o scrollbar.o == NOTYET UTILDIR = ../util SFILES = sectorder.s boot2.s CFILES = boot.c graphics.c drivers.c prompt.c options.c mboot.c preboot.c HFILES = boot.h appleClut8.h appleboot.h mboot.h multiboot.h OTHERFILES = Makefile ALLSRC = $(FOREIGNSRC) $(FOREIGNBIN) $(SFILES) $(CFILES) \ $(HFILES) $(OTHERFILES) DIRS_NEEDED = $(OBJROOT) $(SYMROOT) BOOT2ADDR = 20200 # 65024 == 64k - 512 bytes which is the most the old bootsectors can load #MAXBOOTSIZE = 65024 # Now that __LOSEG is used we can get quite a bit larger. In fact, probably larger than # this limit here so long as when running the stack doesn't encroach down into the BSS. MAXBOOTSIZE = 131072 all: $(DIRS_NEEDED) boot # -segment_order, -image_base, and -segaddr: # Ugh... # What we want is a binary that looks like this # 0x20200: __LOSEG # 0x20..0: __TEXT # 0x....0: __DATA # # That is, __LOSEG must be the first segment and it mut be at exactly 0x20200 # # Getting it at exactly 0x20200 is accomplished with -segaddr __LOSEG 0x20200 # Getting __TEXT to come after it is trickier. Unfortunately the # -segment_order flag is effectively superseded as soon as you manually lay # out a section with segaddr so the next available segment (__TEXT) gets laid # out at location 0 (the default image base for preload) # # Unfortunately the segalign option is completely ignored with the latest linker # meaning that if you want the linker to find the next aligned location for a # segment it will do so on a page (4k) boundary, not the specified boundary # # So you actually need the next segment (__TEXT) to come after the __LOSEG # which means -image_base must be after the end of __LOSEG and also page aligned # which means even though we use 0x20200 for image_base this is rounded up to # 0x21000 and that works although wastes almost 3k. # # Also -seg_page_size can only increase the page size to 4k multiples, not decrease it. # # About the only thing I can think to do here long-term is to use ld -r to produce # a single relocatable MH_OBJECT then get the size of each segment, round it up # to the next paragraph boundary (the alignment we actually want) and manually lay # out every segment according to that (i.e. output a segaddr for all segments) # It is unfortunate that segaddr seems to be the only thing that can override # the 4k alignment. # Another possiblity similarly uses ld -r but then instead of laying out each # segment actually produce a new .o with every segment combined into one with # different section names and then make a 512-byte zero page to account for the # first 512-byte hole and update machOconv to ignore this. # Yet another possibility is to rewrite __LOSEG into __TEXT in the actual code # and therefore only pay the page alignment size penalty for __DATA. # Although for reasons I don't understand it seems __DATA does not have to be # page aligned. boot: machOconv $(OBJS) $(LIBDEP) $(LD) -static -Wl,-preload \ -Wl,-image_base,$(BOOT2ADDR) \ -Wl,-segment_order,__LOSEG:__TEXT:__DATA \ -Wl,-segaddr,__LOSEG,$(BOOT2ADDR) \ -Wl,-e,boot2 \ -Wl,-dead_strip \ -Wl,-no_pie \ -nostdlib -arch i386 -Wl,-segalign,20 \ -o $(SYMROOT)/boot.sys $(filter %.o,$^) $(LIBS) -lcc_kext dsymutil -f $(SYMROOT)/boot.sys machOconv $(SYMROOT)/boot.sys $(SYMROOT)/boot || rm $(SYMROOT)/boot && test -f $(SYMROOT)/boot size $(SYMROOT)/boot.sys ls -l $(SYMROOT)/boot @( size=`ls -l $(SYMROOT)/boot | awk '{ print $$5}'` ; \ if expr "$$size" ">" "$(MAXBOOTSIZE)" > /dev/null ;\ then \ echo "Booter executable larger than $(MAXBOOTSIZE) bytes" ;\ rm $(SYMROOT)/boot ;\ exit 1;\ fi) prompt.o: vers.h vers.h: echo "#define I386BOOT_VERSION \"`vers_string -f 5.0`\"" | \ tr - . > $(SYMROOT)/vers.h install_i386:: all $(INSTALLDIR) cp $(SYMROOT)/boot $(OTHER_FILES) $(INSTALLDIR) cd $(INSTALLDIR); chmod u+w boot $(OTHER_FILES) clean:: rm -f $(SYMROOT)/boot.sys $(SYMROOT)/boot.sys.dwarf $(SYMROOT)/boot $(SYMROOT)/vers.h include ../MakeInc.dir # Build sectorder.o with the -n assembler flag so it can declare sections ordered before __TEXT,__text sectorder.o: CPPFLAGS += -Wa,-n $(OBJROOT)/sectorder.o: CPPFLAGS += -Wa,-n #dependencies -include $(OBJROOT)/Makedep