diff --git a/build/AUTO.ISO b/build/AUTO.ISO index c63e9cad..b5fc552d 100755 Binary files a/build/AUTO.ISO and b/build/AUTO.ISO differ diff --git a/src/System/Boot/BootDVD.ZC b/src/System/Boot/BootDVD.ZC new file mode 100755 index 00000000..8b0eb684 --- /dev/null +++ b/src/System/Boot/BootDVD.ZC @@ -0,0 +1,183 @@ +#define BOOT_HIGH_LOC_DVD ((BOOT_RAM_LIMIT - (BOOT_STACK_SIZE + DVD_BOOT_LOADER_SIZE)) >> 4) + +DefinePrint("DD_BOOT_HIGH_LOC_DVD", "%08X", BOOT_HIGH_LOC_DVD << 4); +DefinePrint("DD_BOOT_HIGH_LOC_DVD_END", "%08X", BOOT_RAM_LIMIT - 1); + +asm { +USE16 +BDVD_START:: +//DL is supposed to have the BIOS drive number + CLD + MOV AX, BOOT_HIGH_LOC_DVD + MOV ES, AX + + CLI + MOV SS, AX + MOV SP, BOOT_STACK_SIZE + DVD_BOOT_LOADER_SIZE + STI + + CALL BDVD_GET_RIP +BDVD_GET_RIP: + POP BX + SUB BX, BDVD_GET_RIP - BDVD_START + SHR BX, 4 +//This copies this bootloader's code to 0x$TX,"00096600",D="DD_BOOT_HIGH_LOC_DVD"$ + MOV AX, CS + ADD AX, BX + MOV DS, AX + MOV CX, DVD_BOOT_LOADER_SIZE + XOR SI, SI + XOR DI, DI + REP_MOVSB + + MOV AX, BOOT_HIGH_LOC_DVD + MOV DS, AX + +//The assembler doesn't support 16-bit very well. + DU8 0xEA; //JMP BOOT_HIGH_LOC_DVD:BDVD_MAIN + DU16 BDVD_MAIN - BDVD_START, BOOT_HIGH_LOC_DVD; + +BDVD_BIOS_DRIVE_NUM: DU8 0; +BDVD_PAGE: DU8 0; + +BDVD_DAP: DU8 16, 0, 1, 0; //One block at a time +BDVD_DAP_BUF: DU16 0, 0; +BDVD_DAP_BLK: DU64 0; + +BDVD_ZEALOS_MESSAGE: DU8 "Loading ZealOS", 0; + +BDVD_NOT64_MESSAGE: DU8 "ZealOS requires a 64-bit capable processor.\n\r", 0; + +//These get patched. +BDVD_BLK_LO:: DU16 0; +BDVD_BLK_HI:: DU16 0; +BDVD_BLK_COUNT:: DU16 0; +BDVD_SHIFT_BLKS:: DU16 0; +BDVD_PROGRESS_STEP:: DU32 0; +BDVD_PROGRESS_VAL:: DU32 0; + +BDVD_PUT_CHAR:: + MOV AH, 0xE + MOV BL, 7 //Might be foreground color on some BIOS's + MOV BH, U8 [BDVD_PAGE - BDVD_START] + INT 0x10 +BDVD_RET:: + RET +BDVD_PUTS:: +@@1: LODSB + TEST AL, AL + JZ BDVD_RET + CALL BDVD_PUT_CHAR + JMP @@1 + +BDVD_MAIN:: + MOV U8 [BDVD_BIOS_DRIVE_NUM - BDVD_START], DL //Passed in by BIOS + + MOV AH, 0xF + INT 0x10 + MOV U8 [BDVD_PAGE - BDVD_START], BH //Video page + + MOV EAX, 0x80000000 + CPUID + CMP EAX, 0x80000001 + JB @@05 + + MOV EAX, 0x80000001 + CPUID + BT EDX, 29 + JC @@15 +@@05: MOV SI, BDVD_NOT64_MESSAGE - BDVD_START + CALL BDVD_PUTS +@@10: JMP @@10 + +@@15: MOV SI, BDVD_ZEALOS_MESSAGE - BDVD_START + CALL BDVD_PUTS + + MOV AX, BOOT_RAM_BASE / 16 + MOV ES, AX + XOR ECX, ECX + MOV CX, U16 [BDVD_BLK_COUNT - BDVD_START] + + MOV EAX, (80 - 7 - 9) * 65536 //80 columns + XOR EDX, EDX + DIV ECX + MOV U32 [BDVD_PROGRESS_STEP - BDVD_START], EAX + MOV U32 [BDVD_PROGRESS_VAL - BDVD_START], 0 + + MOV AX, U16 [BDVD_BLK_LO - BDVD_START] + MOV DX, U16 [BDVD_BLK_HI - BDVD_START] + +@@20: PUSH CX //Block count + +//READ BLOCK + PUSH AX //Block lo + PUSH DX //Block hi + PUSH ES //Buf seg + MOV U16 [BDVD_DAP_BLK - BDVD_START], AX + MOV U16 [BDVD_DAP_BLK + 2 - BDVD_START], DX + MOV AX, ES + MOV U16 [BDVD_DAP_BUF + 2 - BDVD_START], AX //ES:0000 + MOV SI, BDVD_DAP - BDVD_START //DS:SI=DAP + MOV AH, 0x42 + MOV DL, U8 [BDVD_BIOS_DRIVE_NUM - BDVD_START] + INT 0x13 + + POP AX //ES + ADD AX, DVD_BLK_SIZE / 16 + MOV ES, AX + POP DX + POP AX + INC AX + JNZ @@25 + INC DX + +@@25: PUSH AX + MOV BX, U16 [BDVD_PROGRESS_VAL + 2 - BDVD_START] + MOV EAX, U32 [BDVD_PROGRESS_STEP - BDVD_START] + ADD U32 [BDVD_PROGRESS_VAL - BDVD_START], EAX + CMP U16 [BDVD_PROGRESS_VAL + 2 - BDVD_START], BX + JE @@30 + MOV AL, '.' + CALL BDVD_PUT_CHAR +@@30: POP AX + + POP CX + LOOP @@20 + +//Shift backward to align + PUSH DS + MOV BX, U16 [BDVD_SHIFT_BLKS - BDVD_START] + SHL BX, BLK_SIZE_BITS - 4 + MOV CX, U16 [BDVD_BLK_COUNT - BDVD_START] + MOV AX, BOOT_RAM_BASE / 16 + MOV ES, AX + ADD AX, BX + MOV DS, AX +@@35: PUSH CX + XOR SI, SI + XOR DI, DI + MOV CX, DVD_BLK_SIZE / 4 + REP_MOVSD + MOV AX, DS + ADD AX, DVD_BLK_SIZE / 16 + MOV DS, AX + MOV AX, ES + ADD AX, DVD_BLK_SIZE / 16 + MOV ES, AX + POP CX + LOOP @@35 + POP DS + +//See $LK,"AHCIBootDVDProbeAll",A="MN:AHCIBootDVDProbeAll"$(). + MOV EBX, U32 [BDVD_BLK_LO - BDVD_START] + MOV AX, U16 [BDVD_SHIFT_BLKS - BDVD_START] + SHL EAX, 16 + MOV AX, BOOT_SRC_DVD //$MA-X+PU,"See sys_boot_src",LM="Find(\"sys_boot_src\",\"/*\");View;\n"$ + +//The assembler doesn't support 16-bit very well. + DU8 0xEA; //JMP BOOT_RAM_BASE:0000 + DU16 0, BOOT_RAM_BASE / 16; +//Continues here $LK,"::/Kernel/KStart16.ZC",A="FL:::/Kernel/KStart16.ZC,1"$ +BDVD_END:: +#assert BDVD_END-BDVD_START < DVD_BOOT_LOADER_SIZE +} diff --git a/src/System/Boot/BootDVDIns.ZC b/src/System/Boot/BootDVDIns.ZC new file mode 100755 index 00000000..e0016420 --- /dev/null +++ b/src/System/Boot/BootDVDIns.ZC @@ -0,0 +1,35 @@ +//See $LK,"Install Documentation",A="FI:::/Doc/Install.DD"$. +//Study the account examples: $LK,"Config Strs",A="FL:::/Demo/AcctExample/TOS/TOSConfig.ZC,1"$, $LK,"Update Funs",A="FL:::/Demo/AcctExample/TOS/TOSDistro.ZC,1"$ + +#include "BootDVD" +#include "DiskISORedSea" + +#help_index "Install" + +#define KERNEL_BIN_C "Kernel.BIN.C" +#define BOOT_DIR "/Boot" +#define BOOT_DIR_DVD_KERNEL_BIN_C BOOT_DIR "/DVD" KERNEL_BIN_C + +U0 MakeAll() +{ + if (Comp("/Compiler/Compiler", "Compiler",, ':')) + throw; + if (Comp("/Kernel/Kernel", "Kernel",, ':')) + throw; +} + +public U0 BootDVDIns(U8 drv_let=0) +{//See $LK,"::/Misc/DoDistro.ZC"$. + try + { + if (!Drive(drv_let)) + throw; + MakeAll; + Move("/Kernel/Kernel.BIN", BOOT_DIR_DVD_KERNEL_BIN_C); + } + catch + { + PutExcept; + Beep; + } +} diff --git a/src/System/Boot/BootHD.ZC b/src/System/Boot/BootHD.ZC new file mode 100755 index 00000000..b5acb587 --- /dev/null +++ b/src/System/Boot/BootHD.ZC @@ -0,0 +1,91 @@ +#define MODULE_SIZE 1 * BLK_SIZE +#define BOOT_HIGH_LOC_HD ((BOOT_RAM_LIMIT - (BOOT_STACK_SIZE + MODULE_SIZE)) >> 4) + +DefinePrint("DD_BOOT_HIGH_LOC_HD", "%08X", BOOT_HIGH_LOC_HD << 4); + +asm { +USE16 +BHD_CODE:: + +#define BHD_START (BHD_CODE - offset(CFAT32Boot.code)) + + CLD + + MOV AX, BOOT_HIGH_LOC_HD + MOV ES, AX + + CLI + MOV SS, AX + MOV SP, BOOT_STACK_SIZE + MODULE_SIZE + STI + + CALL BHD_GET_RIP +BHD_GET_RIP: + POP BX + SUB BX, BHD_GET_RIP - BHD_START + SHR BX, 4 +//This copies this bootloader's code to 0x$TX,"00096C00",D="DD_BOOT_HIGH_LOC_HD"$ + MOV AX, CS + ADD AX, BX + MOV DS, AX + MOV CX, MODULE_SIZE + XOR SI, SI + XOR DI, DI + REP_MOVSB + + MOV AX, BOOT_HIGH_LOC_HD + MOV DS, AX + +//The assembler doesn't support 16-bit very well. + DU8 0xEA; //JMP BOOT_HIGH_LOC_HD:BHD_HISTART + DU16 BHD_HISTART - BHD_START, BOOT_HIGH_LOC_HD; + +BHD_BIOS_DRIVE_NUM: DU8 0; + +//Gets patched by $LK,"BootHDIns",A="MN:BootHDIns"$(). +BHD_BLK_COUNT:: DU16 0; + +BHD_DAP: DU8 16, 0, 1, 0; //One block at a time +BHD_DAP_BUF: DU16 0, 0; +//Gets patched by $LK,"BootHDIns",A="MN:BootHDIns"$(). +BHD_DAP_BLK:: //64-bit +BHD_DAP_BLK_LO: DU32 0; +BHD_DAP_BLK_HI: DU32 0; + +BHD_HISTART: + MOV U8 [BHD_BIOS_DRIVE_NUM - BHD_START], DL //Passed in by BIOS + MOV AX, BOOT_RAM_BASE / 16 + MOV ES, AX + XOR ECX, ECX + MOV CX, U16 [BHD_BLK_COUNT - BHD_START] + +@@05: PUSH CX //Block count + +//READ BLOCK + PUSH ES //Buf seg + MOV AX, ES + MOV U16 [BHD_DAP_BUF + 2 - BHD_START], AX //ES:0000 + MOV SI, BHD_DAP - BHD_START //DS:SI=DAP + MOV AH, 0x42 + MOV DL, U8 [BHD_BIOS_DRIVE_NUM - BHD_START] + INT 0x13 + + POP AX //ES + ADD AX, BLK_SIZE / 16 + MOV ES, AX + INC U32 [BHD_DAP_BLK_LO - BHD_START] + JNZ @@10 + INC U32 [BHD_DAP_BLK_HI - BHD_START] + +@@10: POP CX + LOOP @@05 + + XOR EBX, EBX + MOV EAX, BOOT_SRC_HARDDRIVE //$MA-X+PU,"See sys_boot_src",LM="Find(\"sys_boot_src\",\"/*\");View;\n"$ +//The assembler doesn't support 16-bit very well. + DU8 0xEA; //JMP BOOT_RAM_BASE:0000 + DU16 0, BOOT_RAM_BASE / 16; +//Continues here $LK,"::/Kernel/KStart16.ZC",A="FL:::/Kernel/KStart16.ZC,1"$ +BHD_END:: +#assert BHD_END - BHD_START < MODULE_SIZE - 2 +} diff --git a/src/System/Boot/BootHDIns.ZC b/src/System/Boot/BootHDIns.ZC new file mode 100755 index 00000000..67b19964 --- /dev/null +++ b/src/System/Boot/BootHDIns.ZC @@ -0,0 +1,84 @@ +//See $LK,"Install Documentation",A="FI:::/Doc/Install.DD"$. +//Study the account examples: $LK,"Config Strs",A="FL:::/Demo/AcctExample/TOS/TOSConfig.ZC,1"$, $LK,"Update Funs",A="FL:::/Demo/AcctExample/TOS/TOSDistro.ZC,1"$ + +#include "BootHD" + +#help_index "Install" + +#define KERNEL_BIN_C "Kernel.BIN.C" +#define BOOT_DIR "/Boot" +#define BOOT_DIR_KERNEL_BIN_C BOOT_DIR "/" KERNEL_BIN_C + +U0 CompComp() +{ + if (Comp("/Compiler/Compiler", "Compiler",, ':')) + throw; +} + +U0 MakeAll() +{ + CompComp; + if (Comp("/Kernel/Kernel", "Kernel",, ':')) + throw; +} + +public U0 BootHDIns(U8 drv_let=0) +{//$LK,"MakeAll",A="MN:MakeAll"$ and install new boot-loader. + CDrive *drive; + CFAT32Boot br; + CDirEntry de; + I64 i; + + try + { + if (!Drive(drv_let)) + throw; + + drive = Fs->cur_dv; + MakeAll; + + switch (Letter2BlkDevType(drive->drv_let)) + { + case BDT_RAM: + case BDT_ATA: + Move("/Kernel/Kernel.BIN", BOOT_DIR_KERNEL_BIN_C); + + if (!FileFind(BOOT_DIR_KERNEL_BIN_C, &de, FUF_JUST_FILES)) + "No Kernel.BIN.C\n"; + else + { + Free(de.full_name); + "Modifying partition boot record.\n"; + BlkRead(drive, &br, drive->drv_offset, 1); + + br.jump_and_nop[0] = OC_JMP_REL8; + br.jump_and_nop[1] = offset(CFAT32Boot.code) - 2; + +#assert offset(CFAT32Boot.code) >= offset(CRedSeaBoot.code) + + br.jump_and_nop[2] = OC_NOP; + *BHD_BLK_COUNT(U16 *) = (de.size + BLK_SIZE - 1) >> BLK_SIZE_BITS; + *BHD_DAP_BLK(I64 *) = Clus2Blk(drive, de.clus); + + for (i = 0; i < BHD_END - BHD_CODE; i++) + br.code[i] = BHD_CODE(U8 *)[i]; + +#assert sizeof(CFAT32Boot.code) >= BHD_END - BHD_CODE + + for (; i < sizeof(CFAT32Boot.code); i++) + br.code[i] = 0; + + BlkWrite(drive, &br, drive->drv_offset, 1); + } + break; + + default: + throw; + } + } + catch + { + PutExcept; + Beep; + } +} diff --git a/src/System/Boot/BootMHD.ZC b/src/System/Boot/BootMHD.ZC new file mode 100755 index 00000000..87795361 --- /dev/null +++ b/src/System/Boot/BootMHD.ZC @@ -0,0 +1,105 @@ +#define MODULE_SIZE 1 * BLK_SIZE +#define BOOT_HIGH_LOC_MHD ((BOOT_RAM_LIMIT - (BOOT_STACK_SIZE + MODULE_SIZE)) >> 4) + +DefinePrint("DD_BOOT_HIGH_LOC_MHD", "%08X", BOOT_HIGH_LOC_MHD << 4); + +asm { +USE16 +BMHD_START:: +BMHD_CODE:: + CLD + + MOV AX, BOOT_HIGH_LOC_MHD + + CLI + MOV SS, AX + MOV SP, BOOT_STACK_SIZE + MODULE_SIZE + STI + + PUSHF + PUSH DS + PUSH ES + PUSH FS + PUSH GS + PUSH ECX + PUSH EBX + PUSH EDX + PUSH EBP + + MOV ES, AX + + CALL BMHD_GET_RIP +BMHD_GET_RIP: + POP BX + SUB BX, BMHD_GET_RIP-BMHD_START + MOV CX, BX + SHR BX, 4 +//This copies this bootloader's code to 0x$TX,"00096C00",D="DD_BOOT_HIGH_LOC_MHD"$ + MOV AX, CS + PUSH AX + ADD AX, BX + MOV DS, AX + MOV U16 [BMHD_OLD_CS_RIP - BMHD_START], CX + POP U16 [BMHD_OLD_CS_RIP + 2 - BMHD_START] + + MOV CX, MODULE_SIZE + XOR SI, SI + XOR DI, DI + REP_MOVSB + + MOV AX, BOOT_HIGH_LOC_MHD + MOV DS, AX + +//The assembler doesn't support 16-bit very well. + DU8 0xEA; //JMP BOOT_HIGH_LOC_MHD:BMHD_HISTART + DU16 BMHD_HISTART - BMHD_START, BOOT_HIGH_LOC_MHD; + +BMHD_BIOS_DRIVE_NUM: DU8 0; +BMHD_OLD_CS_RIP: DU16 0, 0; +//Gets patched by $LK,"BootHDIns",A="MN:BootHDIns"$(). +BMHD_BLK_COUNT:: DU16 0; + +BMHD_DAP: DU8 16, 0, 1, 0; //One block at a time +BMHD_DAP_BUF: DU16 0, 0; +//Gets patched by $LK,"BootHDIns",A="MN:BootHDIns"$(). +BMHD_DAP_BLK:: //64-bit +BMHD_DAP_BLK_LO: DU32 0; +BMHD_DAP_BLK_HI: DU32 0; + +BMHD_HISTART: + MOV U8 [BMHD_BIOS_DRIVE_NUM - BMHD_START], DL //Passed in by BIOS + MOV AX, BOOT_RAM_BASE / 16 + MOV ES, AX + XOR ECX, ECX + MOV CX, U16 [BMHD_BLK_COUNT - BMHD_START] + +@@05: PUSH CX //Block count + +//READ BLOCK + PUSH ES //Buf seg + MOV AX, ES + MOV U16 [BMHD_DAP_BUF + 2 - BMHD_START], AX //ES:0000 + MOV SI, BMHD_DAP - BMHD_START //DS:SI=DAP + MOV AH, 0x42 + MOV DL, U8 [BMHD_BIOS_DRIVE_NUM - BMHD_START] + INT 0x13 + + POP AX //ES + ADD AX, BLK_SIZE / 16 + MOV ES, AX + INC U32 [BMHD_DAP_BLK_LO - BMHD_START] + JNZ @@10 + INC U32 [BMHD_DAP_BLK_HI - BMHD_START] + +@@10: POP CX + LOOP @@05 + + MOV DL, U8 [BMHD_BIOS_DRIVE_NUM - BMHD_START] + MOV EBX, U32 [BMHD_OLD_CS_RIP - BMHD_START] +//The assembler doesn't support 16-bit very well. + DU8 0xEA; //JMP BOOT_RAM_BASE:0000 + DU16 0, BOOT_RAM_BASE / 16; +//Continues here $LK,"BMHD2_START",A="FF:::/System/Boot/BootMHD2.ZC,BMHD2_START"$ +BMHD_END:: +#assert BMHD_END-BMHD_START <= 440 +} diff --git a/src/System/Boot/BootMHD2.ZC b/src/System/Boot/BootMHD2.ZC new file mode 100755 index 00000000..2be9dcf9 --- /dev/null +++ b/src/System/Boot/BootMHD2.ZC @@ -0,0 +1,121 @@ +#define MODULE_SIZE 2 * BLK_SIZE +#define BOOT_HIGH_LOC_MHD2 ((BOOT_RAM_LIMIT - (BOOT_STACK_SIZE + MODULE_SIZE)) >> 4) + +DefinePrint("DD_BOOT_HIGH_LOC_MHD2", "%08X", BOOT_HIGH_LOC_MHD2 << 4); + +asm { +USE16 +BMHD2_START:: + MOV U32 FS:[0], 'B' + 0x2000 + ('2' + 0x2000) << 16 + + MOV AX, BOOT_HIGH_LOC_MHD2 + MOV ES, AX +//This copies this bootloader's code to 0x$TX,"00096A00",D="DD_BOOT_HIGH_LOC_MHD2"$ + MOV AX, CS + MOV DS, AX + MOV U32 [BMHD2_OLD_CS_RIP - BMHD2_START], EBX + MOV U8 [BMHD2_BIOS_DRIVE_NUM - BMHD2_START], DL + + MOV CX, MODULE_SIZE + XOR SI, SI + XOR DI, DI + REP_MOVSB + + MOV AX, BOOT_HIGH_LOC_MHD2 + MOV DS, AX + +//The assembler doesn't support 16-bit very well. + DU8 0xEA; //JMP BOOT_HIGH_LOC_MHD2:BMHD2_HISTART + DU16 BMHD2_HISTART - BMHD2_START, BOOT_HIGH_LOC_MHD2; + +BMHD2_BOOT_MESSAGE:: + DU8 256 DUP(0); + +BMHD2_BIOS_DRIVE_NUM: DU8 0; +BMHD2_PAGE: DU8 0; +BMHD2_BLK_ARRAY:: DU64 8 DUP(0); + +BMHD2_DAP: DU8 16, 0, 1, 0; //One block at a time +BMHD2_DAP_BUF: DU16 0, 0; +BMHD2_DAP_BLK:: //64-bit +BMHD2_DAP_BLK_LO: DU32 0; +BMHD2_DAP_BLK_HI: DU32 0; + +BMHD2_PUT_CHAR:: + MOV AH, 0xE + MOV BL, 7 //Might be foreground color on some BIOS's + MOV BH, U8 [BMHD2_PAGE - BMHD2_START] + INT 0x10 +BMHD2_RET:: + RET +BMHD2_PUTS:: +@@1: LODSB + TEST AL, AL + JZ BMHD2_RET + CALL BMHD2_PUT_CHAR + JMP @@1 + +BMHD2_GETCHAR: + XOR AH, AH + INT 0x16 + PUSH AX + MOV AH, 0x0E + MOV BX, 0x07 + INT 0x10 + POP AX + RET + +BMHD2_HISTART: + MOV AH, 0xF + INT 0x10 + MOV U8 [BMHD2_PAGE - BMHD2_START], BH //Video page + + MOV U32 FS:[0], 0 +@@5: MOV SI, BMHD2_BOOT_MESSAGE - BMHD2_START + CALL BMHD2_PUTS + CALL BMHD2_GETCHAR + CMP AL, '0' + JB @@5 + CMP AL, '8' + JAE @@5 + AND EAX, 7 + + MOV EBX, U32 BMHD2_BLK_ARRAY - BMHD2_START[EAX * 8] + MOV EAX, U32 BMHD2_BLK_ARRAY + 4 - BMHD2_START[EAX * 8] + + TEST EBX, EBX + JNZ @@10 + TEST EAX, EAX + JZ @@5 + +@@10: MOV U32 [BMHD2_DAP_BLK_LO - BMHD2_START], EBX + MOV U32 [BMHD2_DAP_BLK_HI - BMHD2_START], EAX + + MOV AX, U16 [BMHD2_OLD_CS_RIP - BMHD2_START] + SHR AX, 4 + ADD AX, U16 [BMHD2_OLD_CS_RIP + 2 - BMHD2_START] + MOV U16 [BMHD2_DAP_BUF + 2 - BMHD2_START], AX //ES:0000 + MOV SI, BMHD2_DAP - BMHD2_START //DS:SI=DAP + MOV DL, U8 [BMHD2_BIOS_DRIVE_NUM - BMHD2_START] + MOV AH, 0x42 + INT 0x13 + + POP EBP + POP EDX + POP EBX + POP ECX + XOR EAX, EAX + POP GS + POP FS + POP ES + POP DS + POPF + +//The assembler doesn't support 16-bit very well. + DU8 0xEA; //JMP xxxx:yyyy +BMHD2_OLD_CS_RIP: + DU16 0, 0; +BMHD2_END:: +//Continues here $LK,"::/System/Boot/BootHD.ZC",A="FF:::/System/Boot/BootHD.ZC,START"$ +#assert BMHD2_END - BMHD2_START < MODULE_SIZE +} diff --git a/src/System/Boot/BootMHDIns.ZC b/src/System/Boot/BootMHDIns.ZC new file mode 100755 index 00000000..5720c7dd --- /dev/null +++ b/src/System/Boot/BootMHDIns.ZC @@ -0,0 +1,180 @@ +//See $LK,"Install Documentation",A="FI:::/Doc/Install.DD"$. +//Study the account examples: $LK,"Config Strs",A="FL:::/Demo/AcctExample/TOS/TOSConfig.ZC,1"$, $LK,"Update Funs",A="FL:::/Demo/AcctExample/TOS/TOSDistro.ZC,1"$ + +#include "BootMHD" +#include "BootMHD2" + +#help_index "Install" + +#define BOOT_DIR "/Boot" +//Stage 2 of master boot loader +#define BOOT_DIR_BOOTMHD2_BIN_C BOOT_DIR "/BootMHD2.BIN.C" +//Old master boot record +#define BOOT_DIR_OLDMBR_BIN_C BOOT_DIR "/OldMBR.BIN.C" + +public U0 BootMHDOldRead(U8 src_drive, U8 dst_drive) +{//Reads MBR from disk drive containing src partition. +//Writes a single block file to dst BOOT_DIR. + CBlkDev *bd = Letter2BlkDev(src_drive); + CDrive *drive; + CMasterBoot mbr; + + Drive(dst_drive); + drive = Fs->cur_dv; + + if (drive->fs_type != FSt_REDSEA && drive->fs_type != FSt_FAT32) + PrintErr("File System Not Supported\n"); + else + { +//Bypass partition bounds-checking + BlkDevLock(bd); + AHCIAtaBlksRead(bd, &mbr, 0, 1); + BlkDevUnlock(bd); + + Drive(dst_drive); + DirMake(BOOT_DIR); + FileWrite(BOOT_DIR_OLDMBR_BIN_C, &mbr, BLK_SIZE); + } +} + +public U0 BootMHDOldWrite(U8 src_drive, U8 dst_drive) +{//Reads OldMBR from src drive BOOT_DIR. +//writes it to the MBR of the drive with dst partition. + CBlkDev *bd = Letter2BlkDev(dst_drive); + CMasterBoot *mbr; + + Drive(src_drive); + + if (mbr = FileRead(BOOT_DIR_OLDMBR_BIN_C)) + { +//Bypass partition bounds-checking + BlkDevLock(bd); + AHCIAtaBlksWrite(bd, mbr, 0, 1); + BlkDevUnlock(bd); + } + Free(mbr); +} + +public U0 BootMHDZero(U8 dst_drive) +{//Set MBR of disk with dst partition to zero. + + //This is dangerous!! + //The ZealOS partitioner doesn't play well + //with other operating systems at this time and you need + //to do this on a drive partitioned by ZealOS + //if you wish to partition with another operating system. + CBlkDev *bd = Letter2BlkDev(dst_drive); + CMasterBoot mbr; + + MemSet(&mbr, 0, BLK_SIZE); +//Bypass partition bounds-checking + BlkDevLock(bd); + AHCIAtaBlksWrite(bd, &mbr, 0, 1); + BlkDevUnlock(bd); +} + +public Bool BootMHDIns(U8 drv_let, U8 *drv_list=NULL) +{//Create new MBR on the disk that has drv_let as a partition. +//Puts stage 2 in BOOT_DIR of drv_let. + CBlkDev *bd, *bd1; + CDrive *drive, *p1; + CMasterBoot mbr; + CDirEntry de; + I64 i, j, size, *_q; + U8 *menu_ptr, *ptr, ch, buf[STR_LEN]; + Bool res = FALSE; + + try + { + if (drv_list) + { + StrCopy(buf, drv_list); + StrUtil(buf, SUF_TO_UPPER); + } + else + { + j = 0; + for (i = 'A'; i <= 'Z'; i++) + buf[j++] = i; + buf[j++] = 0; + } + + Drive(drv_let); + drive = Fs->cur_dv; + + if (drive->fs_type != FSt_REDSEA && drive->fs_type != FSt_FAT32) + PrintErr("File System Not Supported\n"); + else + { + bd = drive->bd; + + if (!FileFind(BOOT_DIR_OLDMBR_BIN_C,, FUF_JUST_FILES)) + BootMHDOldRead(drv_let, drv_let); + + _q = BMHD2_BLK_ARRAY; + MemSet(_q, 0, sizeof(I64) * 8); + menu_ptr = BMHD2_BOOT_MESSAGE; + StrPrint(menu_ptr, "\n\r\n\rZealOS Boot Loader\n\r\n\r"); + j = 0; + + if (FileFind(BOOT_DIR_OLDMBR_BIN_C, &de, FUF_JUST_FILES)) + { + Free(de.full_name); + *_q++ = Clus2Blk(drive, de.clus); + CatPrint(menu_ptr, "0. Old Boot Record\n\r"); + j++; + } + + ptr = buf; + while (ch = *ptr++) + { + if ((p1 = Letter2Drive(ch, FALSE)) && (bd1 = p1->bd) && bd1 == bd) + { + *_q = p1->drv_offset; + "Drive %C:%16X\n", Drive2Letter(p1), *_q; + CatPrint(menu_ptr, "%d. Drive %C\n\r", j++, Drive2Letter(p1)); + _q++; + } + } + CatPrint(menu_ptr, "\n\rSelection:"); + + size = BMHD2_END - BMHD2_START; + FileWrite(BOOT_DIR_BOOTMHD2_BIN_C, BMHD2_START, size); + + if (!FileFind(BOOT_DIR_BOOTMHD2_BIN_C, &de, FUF_JUST_FILES)) + "No Boot Loader Image\n"; + else + { + Free(de.full_name); + + *BMHD_BLK_COUNT(U16 *) = (size + BLK_SIZE - 1) >> BLK_SIZE_BITS; + *BMHD_DAP_BLK(I64 *) = Clus2Blk(drive, de.clus); +//Bypass partition bounds-checking + BlkDevLock(bd); + AHCIAtaBlksRead(bd, &mbr, 0, 1); + + for (i = 0; i < BMHD_END - BMHD_CODE; i++) + mbr.code[i] = BMHD_CODE(U8 *)[i]; + +#assert sizeof(CMasterBoot.code) >= BMHD_END - BMHD_CODE + + for (; i < sizeof(CMasterBoot.code); i++) + mbr.code[i] = 0; + + if (!mbr.media_id) + mbr.media_id = RandU32; + + mbr.zero = 0; + mbr.signature = 0xAA55; + + AHCIAtaBlksWrite(bd, &mbr, 0, 1); + + BlkDevUnlock(bd); + res = TRUE; + } + } + } + catch + PutExcept; + return res; +} diff --git a/src/System/Boot/BootRAM.ZC b/src/System/Boot/BootRAM.ZC new file mode 100755 index 00000000..a6af49aa --- /dev/null +++ b/src/System/Boot/BootRAM.ZC @@ -0,0 +1,59 @@ +#help_index "Call" +asm { +_HI_CALL:: + PUSH RBP + MOV RBP, RSP + MOV RAX, U64 16[RBP] + TEST RAX, RAX + JZ @@05 + CALL RAX +@@05: POP RBP + RET1 8 +//************************************ +_HI_MEMCOPY:: + PUSH RBP + MOV RBP, RSP + PUSH RSI + PUSH RDI + CLD + MOV RDI, U64 SF_ARG1[RBP] + MOV RSI, U64 SF_ARG2[RBP] + MOV RCX, U64 SF_ARG3[RBP] + REP_MOVSB + MOV RAX, RDI + POP RDI + POP RSI + POP RBP + RET1 24 +} +_extern _HI_CALL I64 HiCall(U8 *machine_code); +_extern _HI_MEMCOPY U8 *HiMemCopy(U8 *dst, U8 *src, I64 count); + +#help_index "Boot" +public U0 BootRAM(U8 *filename="::" BOOT_DIR_KERNEL_BIN_C) +{//Softboot Kernel.BIN file. No hardware reset. + I64 size; + CKernel *hi_image, *lo_image = mem_boot_base - sizeof(CBinFile), reg *sys_ram_reboot; + do + if (!(hi_image = FileRead(filename, &size))) + return; + while (hi_image < 0x100000); //If alloc from low 640K, just get another copy. + + do + sys_ram_reboot = MAlloc(SYS_RAM_REBOOT_END - SYS_RAM_REBOOT, Fs->code_heap); + while (sys_ram_reboot < 0x100000); + + hi_image->boot_src = BOOT_SRC_RAM; + hi_image->boot_blk = 0; + hi_image->boot_patch_table_base = lo_image(U8 *) + hi_image->h.patch_table_offset; + hi_image->sys_run_level = lo_image->sys_run_level & (RLF_VESA | RLF_16BIT); + MemCopy(&hi_image->start, &lo_image->start, sizeof(CKernel) - offset(CKernel.start)); + + CLI + if (mp_count > 1) + MPHalt; + + HiMemCopy(sys_ram_reboot, SYS_RAM_REBOOT, SYS_RAM_REBOOT_END - SYS_RAM_REBOOT); + HiMemCopy(lo_image, hi_image, size); + HiCall(sys_ram_reboot); +} diff --git a/src/System/Boot/DiskISORedSea.ZC b/src/System/Boot/DiskISORedSea.ZC new file mode 100755 index 00000000..cc3a247e --- /dev/null +++ b/src/System/Boot/DiskISORedSea.ZC @@ -0,0 +1,217 @@ +#help_index "File/CD DVD" + +U0 FillU16Palindrome(CPalindromeU16 *dst, U16 w) +{ + dst->big = EndianU16(w); + dst->little = w; +} + +U0 FillU32Palindrome(CPalindromeU32 *dst, I64 d) +{ + dst->big = EndianU32(d); + dst->little = d; +} + +class CElTorito +{ + U16 w[16]; + U8 bootable; // 88=bootable 00=not bootable + U8 media_type; // 0=no emulation 4=hard disk + U16 load_seg; // 0000->07C0 + U8 sys_type; + U8 zero; + U16 sect_count; + U32 load_rba; // start address of virtual disk + U8 zero2[20]; +}; + +U0 RedSeaISO9660Stage1(U8 *iso_filename, U8 *stage2_filename) +{ + CDirEntry de; + CFile *out_file = NULL; + U8 *stage1_buf = CAlloc(DVD_BOOT_LOADER_SIZE); + + if (FileFind(stage2_filename, &de) && (out_file = FOpen(iso_filename, "wc+"))) + { + MemCopy(stage1_buf, BDVD_START, BDVD_END - BDVD_START); + *(BDVD_BLK_LO - BDVD_START + stage1_buf)(U32 *) = de.clus >> 2; + *(BDVD_BLK_COUNT - BDVD_START + stage1_buf)(U16 *) = (de.size + DVD_BLK_SIZE - 1) >> (BLK_SIZE_BITS + 2); + *(BDVD_SHIFT_BLKS - BDVD_START + stage1_buf)(U16 *) = de.clus & 3; + + if (de.clus & 3) + *(BDVD_BLK_COUNT - BDVD_START + stage1_buf)(U16 *) += 1; + + FBlkWrite(out_file, stage1_buf, 20 << 2 + 1 << 2, DVD_BOOT_LOADER_SIZE / BLK_SIZE); + FClose(out_file); + } + Free(stage1_buf); +} + +U0 RedSeaISO9660(U8 *iso_filename, U8 drv_let) +{ + CDrive *drive = Letter2Drive(drv_let); + CISOPriDesc *iso_pri = CAlloc(DVD_BLK_SIZE), + *iso_boot = CAlloc(DVD_BLK_SIZE), + *iso_sup = CAlloc(DVD_BLK_SIZE), + *iso_term = CAlloc(DVD_BLK_SIZE); + I64 iso_size = 0, i, j; + U32 *d; + CElTorito *et = CAlloc(DVD_BLK_SIZE); + U8 *zero_buf = CAlloc(DVD_BLK_SIZE), *st; + CFile *out_file = NULL; + + if (out_file = FOpen(iso_filename, "wc+")) + { + iso_size = FSize(out_file) / DVD_BLK_SIZE; + + for (i = 0; i < drive->bd->drv_offset; i += 4) + FBlkWrite(out_file, zero_buf, i, 4); + + iso_pri->type = ISOT_PRI_VOL_DESC; + StrCopy(iso_pri->id, "CD001"); + iso_pri->version = 1; + FillU16Palindrome(&iso_pri->vol_set_size, 1); + FillU16Palindrome(&iso_pri->vol_seq_num, 1); + FillU16Palindrome(&iso_pri->log_block_size, DVD_BLK_SIZE); + FillU32Palindrome(&iso_pri->vol_space_size, iso_size); + FillU32Palindrome(&iso_pri->root_dir_record, drive->root_clus); + iso_pri->file_structure_version = 1; + StrCopy(iso_pri->publisher_id, "ZealOS RedSea"); + + st = MStrPrint("ZealOS V%0.2f %D %T", sys_os_version, Now, Now); + StrCopy(iso_pri->preparer_id, st); + Free(st); + + MemCopy(iso_sup, iso_pri, DVD_BLK_SIZE); + iso_sup->type = ISOT_SUPPLEMENTARY_DESC; + + iso_boot->type = ISOT_BOOT_RECORD; + StrCopy(iso_boot->id, "CD001"); + iso_boot->version = 1; + StrCopy(iso_boot(U8 *) + 7, "EL TORITO SPECIFICATION"); + + FBlkWrite(out_file, iso_pri, 16 << 2, 4); + iso_term->type = ISOT_TERMINATOR; + StrCopy(iso_term->id, "CD001"); + iso_term->version = 1; + + d = iso_boot(U8 *) + 0x47; + *d = 20 << 2 >> 2; + FBlkWrite(out_file, iso_boot, 17 << 2, 4); + + FBlkWrite(out_file, iso_sup, 18 << 2, 4); + FBlkWrite(out_file, iso_term, 19 << 2, 4); + + et->w[0] = 1; + StrCopy(&et->w[2], "ZealOS"); + et->w[15] = 0xAA55; + + j = 0; + for (i = 0; i < 16; i++) //Checksum + j += et->w[i]; + + et->w[14] = -j; + et->bootable = 0x88; + et->media_type = 0;//0=no emu 2=1.44meg 4=hard drive + et->sect_count = 4; //5 seems like the limit, 4 is safer + et->load_rba = 20 << 2 >> 2 + 1; + FBlkWrite(out_file, et, 20 << 2, 4); + FClose(out_file); + } + Free(zero_buf); + Free(et); + Free(iso_pri); + Free(iso_boot); + Free(iso_sup); + Free(iso_term); +} + +I64 RedSeaISOPass1(CDirEntry *tmpde) +{ + I64 dir_entry_count = 3 + LinkedListCount(tmpde), res = 0; + + while (tmpde) + { + if (tmpde->attr & RS_ATTR_DIR) + { + if (tmpde->sub) + res += RedSeaISOPass1(tmpde->sub); + else + res += BLK_SIZE; //Empty dir + } + else + res += CeilU64(tmpde->size, BLK_SIZE); + + tmpde = tmpde->next; + } + res += CeilU64(dir_entry_count << 6, BLK_SIZE); //Size in bytes + +#assert CDIR_SIZE == 64 + + return res; +} + +public I64 RedSeaISO(U8 *_iso_filename=NULL, U8 *_src_dir, U8 *_stage2_filename=NULL) +{//See $LK,"::/Misc/DoDistro.ZC"$. Must be ISO.C + I64 i, res, root_count, root_dir_blks, bitmap_blks, bitmap_blks1; + CDirEntry *tmpde; + U8 buf[STR_LEN], *iso_filename, *src_dir, *stage2_filename; + CDrive *drive = DriveMakeFreeSlot(DriveNextFreeLet('Q')); //First $LK,"BDT_ISO_FILE_WRITE",A="MN:BDT_ISO_FILE_WRITE"$ + CBlkDev *bd = BlkDevNextFreeSlot(drive->drv_let, BDT_ISO_FILE_WRITE); + + if (!IsDir(_src_dir)) + PrintErr("'%s' is not a dir.\n", _src_dir); + else + { + if (!_iso_filename) + _iso_filename = blkdev.default_iso_c_filename; + + iso_filename = ExtChange(_iso_filename, "ISO.C"); + src_dir = DirNameAbs(_src_dir); + + if (_stage2_filename) + { + stage2_filename = FileNameAbs(_stage2_filename); + *stage2_filename = drive->drv_let; + + i = StrLen(src_dir); + if (i != 3) //If not root + i++; //Skip slash + + StrCopy(stage2_filename + 3, stage2_filename + i); + } + else + stage2_filename = NULL; + + tmpde = FilesFind(src_dir, FUF_RECURSE); + root_count = LinkedListCount(tmpde) + 3; + root_dir_blks = CeilU64(root_count << 6, BLK_SIZE) >> BLK_SIZE_BITS; + + if (res = RedSeaISOPass1(tmpde) >> BLK_SIZE_BITS) + { + bd->drv_offset = 19 << 2 + (DVD_BLK_SIZE * 2 + DVD_BOOT_LOADER_SIZE) / BLK_SIZE; + bitmap_blks = 1; + do + { + bitmap_blks1 = bitmap_blks; + bitmap_blks = (res + bitmap_blks + BLK_SIZE << 3 - 1) / BLK_SIZE << 3; + } + while (bitmap_blks != bitmap_blks1); + + bd->max_blk = CeilI64(bd->drv_offset + 1 + bitmap_blks + res, 4); + bd->max_blk--; //Inclusive. + bd->file_disk_name = SysStrNew(iso_filename); + bd->init_root_dir_blks = root_dir_blks; + BlkDevAdd(bd,, TRUE, TRUE); + StrPrint(buf, "%C:/", drive->drv_let); + CopyTree(src_dir, buf, TRUE); + RedSeaISO9660Stage1(iso_filename, stage2_filename); + DriveDel(drive); + BlkDevDel(bd); + } + Free(stage2_filename); + Free(src_dir); + Free(iso_filename); + } + return res; +} diff --git a/src/System/Boot/MakeBoot.ZC b/src/System/Boot/MakeBoot.ZC new file mode 100755 index 00000000..45635676 --- /dev/null +++ b/src/System/Boot/MakeBoot.ZC @@ -0,0 +1,8 @@ +Cd(__DIR__);; + +#include "BootDVDIns" +#include "BootHDIns" +#include "BootMHDIns" +#include "BootRAM" + +Cd("..");; diff --git a/src/System/Define.ZC b/src/System/Define.ZC index e5508206..c7214d7a 100755 --- a/src/System/Define.ZC +++ b/src/System/Define.ZC @@ -15,8 +15,8 @@ U0 LoadDocDefines() //$LK,"DD_BOOT_HIGH_LOC_DVD",A="FF:::/System/Boot/BootDVD.ZC,DD_BOOT_HIGH_LOC_DVD"$ $TR,"LineRep"$ -$ID,2$DefinePrint("DD_ZEALOS_LOC","95,270"); -$ID,-2$ +$ID,2$DefinePrint("DD_ZEALOS_LOC","95,327"); +$ID,-2$ DefinePrint("DD_MP_VECT", "%08X", MP_VECT_ADDR); DefinePrint("DD_MP_VECT_END", "%08X", MP_VECT_ADDR + COREAP_16BIT_INIT_END - COREAP_16BIT_INIT - 1);