diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index ea469b1b19..c5c2a79b98 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -197,10 +197,11 @@ SYSTEM_ADD_ONS_FILE_SYSTEMS = bfs bindfs btrfs cdda exfat ext2 fat iso9660 nfs googlefs ; -# build the haiku system package and add it +# build the haiku system packages and add them include [ FDirName $(HAIKU_BUILD_RULES_DIR) HaikuPackages ] ; AddPackageFilesToHaikuImage system : haiku.hpkg ; +AddPackageFilesToHaikuImage system : haiku_loader.hpkg ; AddSymlinkToHaikuImage . : /boot/common/apps ; @@ -315,9 +316,6 @@ SEARCH on fresh_install = [ FDirName $(HAIKU_TOP) data common settings ] ; AddFilesToHaikuImage common settings : fresh_install ; -# boot loader -AddFilesToHaikuImage system : haiku_loader ; - # decorators AddDirectoryToHaikuImage home config non-packaged add-ons decorators ; #AddFilesToHaikuImage home config add-ons decorators : ; diff --git a/build/jam/HaikuPackages b/build/jam/HaikuPackages index ec3dfc33a1..1afbb48843 100644 --- a/build/jam/HaikuPackages +++ b/build/jam/HaikuPackages @@ -4,6 +4,7 @@ local packages = Haiku HaikuCrossDevel HaikuDevel + HaikuLoader HaikuUserguide HaikuWelcome MakefileEngine diff --git a/build/jam/packages/Haiku b/build/jam/packages/Haiku index a9fd70cc7d..435363fad1 100644 --- a/build/jam/packages/Haiku +++ b/build/jam/packages/Haiku @@ -280,9 +280,6 @@ SEARCH on $(thinkPadFiles) = $(thinkpadDir) ; AddFilesToPackage data KeyboardLayouts ThinkPad : $(thinkPadFiles) ; -# boot loader -AddFilesToPackage : haiku_loader ; - # boot module links AddBootModuleSymlinksToPackage acpi@x86 ata@ata pci isa@x86 config_manager dpc diff --git a/build/jam/packages/HaikuLoader b/build/jam/packages/HaikuLoader new file mode 100644 index 0000000000..31298459a7 --- /dev/null +++ b/build/jam/packages/HaikuLoader @@ -0,0 +1,13 @@ +local haikuLoaderPackage = haiku_loader.hpkg ; +HaikuPackage $(haikuLoaderPackage) ; + + +# boot loader +AddFilesToPackage : haiku_loader ; + + +# Force no compression, so the stage one loader can directly execute the boot +# loader. +HAIKU_PACKAGE_COMPRESSION_LEVEL on $(haikuLoaderPackage) = 0 ; + +BuildHaikuPackage $(haikuLoaderPackage) : haiku_loader ; diff --git a/src/data/package_infos/haiku_loader b/src/data/package_infos/haiku_loader new file mode 100644 index 0000000000..b9bb561c9d --- /dev/null +++ b/src/data/package_infos/haiku_loader @@ -0,0 +1,18 @@ +name haiku_loader +version R1~alpha4_pm-1 +architecture x86_gcc2 +summary "The Haiku boot loader" +description "The Haiku boot loader." + +packager "The Haiku build system" +vendor "Haiku Project" + +copyrights "2001-2013 Haiku, Inc. et al" +licenses "MIT" + +provides { + haiku_loader=R1~alpha4_pm-1 +} + +requires { +} diff --git a/src/system/boot/platform/bios_ia32/stage1.S b/src/system/boot/platform/bios_ia32/stage1.S index af463698ed..bbfeca4f29 100644 --- a/src/system/boot/platform/bios_ia32/stage1.S +++ b/src/system/boot/platform/bios_ia32/stage1.S @@ -1,11 +1,11 @@ -; Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. +; Copyright 2005-2013, Ingo Weinhold, ingo_weinhold@gmx.de. ; Distributed under the terms of the MIT License. ; ; Stage 1 boot code for the good (?) old BIOS for use as boot block of HD ; partitions. The offset of the partition in 512 byte blocks must be written at ; position PARTITION_OFFSET_OFFSET (32 bit little endian; makebootable does ; that) or otherwise the code can't find the partition. -; The partition must be a BFS formatted. The file "system/haiku_loader" +; The partition must be BFS formatted. The file "system/haiku_loader" ; (the stage 2 boot loader) loaded into memory at 0x1000:0x0000 (linear address ; 0x10000) and entered at 0x:1000:0x0200 with parameters eax - partition offset ; in 512 byte blocks and dl - BIOS ID of the boot drive. @@ -193,6 +193,12 @@ struc BPlusTreeNode .all_key_length resw 1 endstruc +; The beginning of a HPKG header +struc HPKGHeader + .magic resd 1 + .header_size resw 1 + ; ... + ; That's what esp points to after a "pushad". struc PushadStack .edi resd 1 @@ -631,7 +637,7 @@ kReadErrorString db "read error", 0 kBadSuperBlockMagicString db "bad superblock", 0 kNotADirectoryString db "not a directory", 0 kBadInodeMagicString db "bad inode", 0 -kNoZbeosString db "haiku_loader not found", 0 +kNoZbeosString db "no loader", 0 %else kErrorString db "Failed to load OS. Press any key to reboot..." db 0 @@ -640,7 +646,8 @@ kErrorString db "Failed to load OS. Press any key to reboot..." ; the path to the boot loader kPathComponents: pathComponent "system" -pathComponent "haiku_loader" +pathComponent "packages" +pathComponent "haiku_loader.hpkg" db 0 @@ -706,20 +713,65 @@ readBootLoader: and ax, ax jnz .read_loop - ; We have successfully read the complete boot loader. Set up the + ; We have successfully read the complete boot loader package. The actual + ; code is located at the beginning of the package file heap which starts + ; directly after the header. Since the boot loader code expects to be + ; located at a fixed address, we have to move it there. + + ; First set up the source and target segment registers. We keep the current + ; value also in bx, since it is easier to do arithmetics with it. We keep + ; the increment value for the segment registers in dx. + mov bx, 0x1000 ; initial ds and es value + push bx + pop ds + push bx + pop es + mov dx, bx ; the increment value for the segment registers + + ; Determine how much we have to copy and from where to where. si will be + ; the source and di the destination pointer (both segment relative) and + ; ecx is our byte count. To save instructions we only approximate the count. + ; It may be almost a full segment greater than necessary. But that doesn't + ; really harm. + mov ecx, edi + shr ecx, 12 ; byte count + xor di, di ; target + mov ax, [di + HPKGHeader.header_size] ; header size (big endian) + xchg ah, al + mov si, ax ; source + +.move_loop: + movsb + test si, si + jnz .move_no_source_overflow + add bx, dx + push bx + pop ds +.move_no_source_overflow: + test di, di + jnz .move_no_destination_overflow + push bx + pop es + ; Using bx (the value of ds) is fine, since we assume that the + ; source is less than a segment ahead of the destination. +.move_no_destination_overflow: + dec ecx + jnz .move_loop + + ; We have successfully prepared the boot loader code. Set up the ; environment for it. ; eax - partition offset in sectors + push cs + pop ds + ; temporarily reset ds, so we can access our variables mov dword eax, [kPartitionOffset] ; dl - BIOS drive ID xor edx, edx mov dl, [bios_drive_id] - ; ds, es - push 0x07c0 - pop ds - push 0x1000 - pop es + ; Note: We don't have to set ds and es, since the stage 2 sets them + ; anyway before accessing any data. ; enter the boot loader jmp 0x1000:0x200 @@ -949,6 +1001,7 @@ bfsBlockToDiskBlock: ret +%if 0 ; _writeInt32 ; Writes the given number in 8 digit hexadecimal representation to screen. ; Used for debugging only. @@ -988,6 +1041,7 @@ _writeInt32: popad ret +%endif ; check whether we are small enough diff --git a/src/system/boot/platform/bios_ia32/stage1.bin b/src/system/boot/platform/bios_ia32/stage1.bin index 0a6d92a9b9..e348e81a55 100644 Binary files a/src/system/boot/platform/bios_ia32/stage1.bin and b/src/system/boot/platform/bios_ia32/stage1.bin differ