Trivial Solutions
                    The LoseThos 64-bit PC Operating System
File:/LT/Adam/Boot/InsBoot.APZ
This, and all LoseThos files, are public domain.  Do whatever you like.
God is watching; God is just; God is never out-done in generosity.  He talks!

LoseThos code compiles with the 64-bit LoseThos compiler/assembler I wrote.
Boot the LoseThos CD and you can compile it.  Not in Kansas anymore!

Click here for preliminary compiler information you need.

#help_index "Install"
//See Install Documentation or Upgrading Documentation.

//OSMain module: OS.BIZ
#define BOOT_BIC        "Boot.BIC"
//First dir on CD.  First file must be Boot.BIC (on CD-ROMs).
#define BOOT_DIR        "/0000Boot"
//Stage 2 of master boot loader: BootMHD2.BIZ
#define BOOTLOADER_BIC  "/0000Boot/BootLoader.BIC"
//Old master boot record
#define OLDMBR_BIC      "/0000Boot/OldMBR.BIC"
//patched version of BootCD.BIZ
#define CDBOOT_BIZ      "/0000Boot/CDBoot.BIZ"

if (IsDrvWritable) {
  "BootCD  ";Cmp("BootCD");
  "BootHD  ";Cmp("BootHD");
  "BootMHD ";Cmp("BootMHD");
  "BootMHD2";Cmp("BootMHD2");
  MkDir("/Temp"); //Good to have a Temp
}

Load("BootCD",LDF_NO_ABSS);
Load("BootHD",LDF_NO_ABSS);
Load("BootMHD",LDF_NO_ABSS);
Load("BootMHD2",LDF_NO_ABSS);

#help_index "Install;File/Install Related;File/CD DVD"
public BoolI64 CDBootFileCreate()
{
  U8 *br;
  U64 d,size=FileSize(BOOT_DIR "/" BOOT_BIC);
  U16 *_w;

  br=CAlloc(CD_BOOT_LOADER_SIZE);
  _w=BCD_BLK_CNT;
  *_w=(size+CD_BLK_SIZE-1)/CD_BLK_SIZE;

  //After preboot + CDBoot.BIZ comes Boot.BIC
  //CDBOOT

  //No emulation
  //This trick assumes OSMain is first file in first Dir.
  d=1+(CD_FILE_OFFSET+CD_BOOT_LOADER_SIZE/BLK_SIZE)/(CD_BLK_SIZE>>BLK_SIZE_BITS);
  _w=BCD_BLK_LO;
  *_w=d.u16[0];
  _w=BCD_BLK_HI;
  *_w=d.u16[1];

  MemCpy(br,BCD_START,BCD_END-BCD_START);
  FileWrite(CDBOOT_BIZ,br,CD_BOOT_LOADER_SIZE);
  Free(br);
  return TRUE;
}

#help_index "Call"
asm {
USE64
_HI_CALL::
        ENTER   0
        MOV     RAX,U64 16[RBP]
        OR      RAX,RAX
        JZ      @@05
        CALL    RAX
@@05:   LEAVE
        RET1    8
}
LTextern _HI_CALL U64 HiCall(U0 *s);

#help_index "Boot"
public U0 Boot(U8 *filename)
//Soft Reboot (no hardware rst)
//Specify the OSMain binary file you
//wish to boot.
{
  U64 size;
  OSMainStruct  *hi_image,*lo_image=sys_boot_base-sizeof(BinFileHeaderStruct),
                reg *shutdown,*hi_image2;

  if (!(hi_image2=FileRead(filename,&size))) return;
  switch (snd_dev) {
    case SD_PC_SPEAKER:
      break;
    case SD_HD_AUDIO:
      CallExtStr("HDAudioEnd",TRUE);
      break;
  }

  shutdown=MAlloc(SYS_RESTART_OSMAIN_END-SYS_RESTART_OSMAIN,Fs->code_heap);
  hi_image=MAlloc(size,Fs->code_heap);
  MemCpy(hi_image,hi_image2,size);
  Free(hi_image2);

  hi_image->boot_base=lo_image><(U8 *)+sizeof(BinFileHeaderStruct);
  hi_image->boot_patch_table_base=lo_image><(U8 *)+hi_image->h.loader_patch_table_offset;
  MemCpy(&hi_image->sys_mem_E801,&lo_image->sys_mem_E801,2*2);
  MemCpy(&hi_image->sys_mem_E820,&lo_image->sys_mem_E820,NUM_MEM_E820_ENTRIES*MEM_E820_ENTRY_SIZE);
  hi_image->sys_gr_mode=lo_image->sys_gr_mode;
  hi_image->sys_pci_busses=lo_image->sys_pci_busses;
  hi_image->boot_code=BOOT_CODE_RAM;

  Cli;
  if (mp_cnt>1)
    MPHalt;

  MemCpy(shutdown,SYS_RESTART_OSMAIN,SYS_RESTART_OSMAIN_END-SYS_RESTART_OSMAIN);
  MemCpy(&hi_image->sys_gdttab,&lo_image->sys_gdttab,sizeof(GdtTabStruct)*MAXGDT);
  MemCpy(lo_image,hi_image,size);
  HiCall(shutdown);
}

#help_index "Install"
U0 InstallLTDir(U8 src,U8 dst)
{
  U8 buf_s[64],buf_d[64];
  if (src==dst) return;
  SPrintF(buf_s,"%c:/LT",src);
  SPrintF(buf_d,"%c:/LT",dst);
  DelTree(buf_d);
  CopyTree(buf_s,buf_d);
}

U8 ChkWritable(U8 drv_let=0)
{
  BoolI8 cont=TRUE;
  U8 writable_drv=drv_let;
  LTPrt *p;
  LTBlkDev *bdev;
  if (!IsDrvWritable(drv_let)) {
    '' drv_let;
    ": Drive is read-only.\n";
    do {
      "Enter RAM drive (usually 'B') for temporary files:";
      writable_drv=ToUpper(GetChar);
      NewLine;
      p=Drv2Prt(writable_drv);
      bdev=p->bdev;
      if (bdev->type!=LTBDT_RAM ||
          !IsDrvWritable(writable_drv))
        "Not A RAM Drive\n";
      else
        cont=FALSE;
    } while (cont);
    Fmt(writable_drv,FALSE,FALSE);
    InstallLTDir(drv_let,writable_drv);
  }
  return writable_drv;
}


#help_index "Install"
public U0 MakeAll()
//Call from InstallBoot()  because loader must be patched with block address.

//These 3 modules (and bootloaders at top) are the only statically
//compiled code in LoseThos.  Everything else is JIT.
//You are doing it wrong if you make statically compiled code.

{
  Cd("/LT/Compiler");
  if (Cmp("Compiler","Compiler",NULL,':'))
    throw;
  Cd("/LT/OSMain");
  if (Cmp("OS","OS",NULL,':'))
    throw;
}

public BoolI64 InstallBoot(U8 src_drv,U8 dst_drv=0)
{
//Normally, you just supply a src_drv.  It will compile
//the code on that drive and update the boot sect.

//If you are making a bootable CD-ROM you supply a dst_drv.
//See Bootable CD-ROMs

//See Install Documentation

//Study my account examples my technique Cfg Strs Update Funs

  BoolI8 result=FALSE;
  LTBlkDev *bdev;
  LTPrt *p;
  FAT32BootStruct br;
  LTDirEntry de;
  U64 *qq,i;
  U8 *_b;
  U16 *_w;

  try {
    if (!src_drv) src_drv=Fs->cur_prt->drv_let;
    if (!dst_drv) dst_drv=src_drv;

    //This passes a cfg arg for
    //compilation of OSMain which is accessed
    //within a #exe {} statement.
    //See InsBootDstDrv
    //(There is no way to set compiler options.)
    NamedFramePtrAdd("InsBootDstDrv",dst_drv);
    src_drv=ChkWritable(src_drv);
    if (!Drv(src_drv))
      throw;
    MakeAll;
    Cd("/");

    bdev=Drv2BlkDev(dst_drv);
    p   =Drv2Prt   (dst_drv);
    switch (bdev->type) {
      case LTBDT_ATAPI:
        Move("/LT/OSMain/OS.BIZ",BOOT_DIR "/" BOOT_BIC);
        CDBootFileCreate;
        result=TRUE;
        break;
      case LTBDT_RAM:
      case LTBDT_ATA:
        Move("/LT/OSMain/OS.BIZ",BOOT_BIC);
        if (!FileFind(BOOT_BIC,&de,FALSE,TRUE))
          "No Boot.BIC\n";
        else {
          "Modifying partition boot record.\n";
          RBlks(p,&br,p->offset,1);
          br.jump_and_nop[0]=0xEB;
          br.jump_and_nop[1]=0x58;
          br.jump_and_nop[2]=0x90;
          _w=BHD_BLK_CNT;
          *_w=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
          qq=BHD_DAP_BLK;
          *qq=p->data+de.cluster*p->spc;
          _b=BHD_CODE;
          for (i=0;i<BHD_END-BHD_CODE;i++)
            br.code[i]=_b[i];
          for (;i<420;i++)
            br.code[i]=0;
          WBlks(p,&br,p->offset,1);
          result=TRUE;
        }
        break;
    }
  } catch
    CatchAll;
  NamedFramePtrDel("InsBootDstDrv");
  return result;
}


public U0 OldMasterBootRead(U8 src_drv,U8 dst_drv)
{
  LTBlkDev *bdev;
  LTPrt *p,*p2;
  MasterBootStruct mbr;
 
  bdev=Drv2BlkDev(src_drv);
  try {
    while (bdev->non_lt_drv) { //I think this would be insane, actually.
      p2=Drv2Prt(bdev->non_lt_drv);
      bdev=Drv2BlkDev(Prt2Drv(p2));
    }
  } catch
    Fs->catch_except=TRUE;
  Drv(dst_drv);
  p=Fs->cur_prt;
  if (p->type!=PT_LT && p->type!=PT_FAT32)
    PutDefineErr("ST_NOT_LT");
  else {
    //Bypass partition bounds-checking
    BlkDevLock(bdev);
    ATAReadBlks(bdev,&mbr,0,1);
    BlkDevUnlock(bdev);

    Drv(dst_drv);
    MkDir(BOOT_DIR);
    FileWrite(OLDMBR_BIC,&mbr,BLK_SIZE);
  }
}

public U0 OldMasterBootWrite(U8 src_drv,U8 dst_drv)
{
  LTBlkDev *bdev;
  MasterBootStruct *mbr;
  LTPrt *p2;
  bdev=Drv2BlkDev(dst_drv);
  try {
    while (bdev->non_lt_drv) { //I think this would be insane, actually.
      p2=Drv2Prt(bdev->non_lt_drv);
      bdev=Drv2BlkDev(Prt2Drv(p2));
    }
  } catch
    Fs->catch_except=TRUE;
  Drv(src_drv);
  mbr=FileRead(OLDMBR_BIC);
  if (mbr) {
    //Bypass partition bounds-checking
    BlkDevLock(bdev);
    ATAWriteBlks(bdev,mbr,0,1);
    BlkDevUnlock(bdev);
  }
  Free(mbr);
}

public U0 MasterBootZero(U8 dst_drv)
{
//This is dangerous!!
//The LoseThos parter doesn't play well
//with other operating systems at this time and you need
//to do this on a drive partitioned by LoseThos
//if you wish to partition with another operating system.
  LTBlkDev *bdev;
  MasterBootStruct mbr;
  LTPrt *p2;
  bdev=Drv2BlkDev(dst_drv);
  try {
    while (bdev->non_lt_drv) { //I think this would be insane, actually.
      p2=Drv2Prt(bdev->non_lt_drv);
      bdev=Drv2BlkDev(Prt2Drv(p2));
    }
  } catch
    Fs->catch_except=TRUE;
  MemSet(&mbr,0,BLK_SIZE);

  //Bypass partition bounds-checking
  BlkDevLock(bdev);
  ATAWriteBlks(bdev,&mbr,0,1);
  BlkDevUnlock(bdev);
}

public BoolI64 InstallMasterBoot(U8 drv_let,U8 *drv_list=NULL)
{
  BoolI8 result=FALSE;
  LTBlkDev *bdev,*bd1;
  LTPrt *p,*p1,*p2;
  MasterBootStruct mbr;
  LTDirEntry de;
  U64 i,j,size,*qq;
  U8 *_b;
  U16 *_w;
  U8 *menu_ptr,*ptr,ch,buf[128],buf2[128];

  try {
    if (drv_list)
      StrCpy(buf2,drv_list);
    else {
      j=0;
      for (i='A';i<='Z';i++)
        buf2[j++]=i;
      buf2[j++]=0;
    }

    Drv(drv_let);
    p=Fs->cur_prt;
    if (p->type!=PT_LT && p->type!=PT_FAT32)
      PutDefineErr("ST_NOT_LT");
    else {
      bdev=Drv2BlkDev(drv_let);
      try {
        while (bdev->non_lt_drv) { //I think this would be insane, actually.
          p2=Drv2Prt(bdev->non_lt_drv);
          bdev=Drv2BlkDev(Prt2Drv(p2));
        }
      } catch
        Fs->catch_except=TRUE;
      if (!FileFind(OLDMBR_BIC,&de,FALSE,TRUE))
        OldMasterBootRead(drv_let,drv_let);

      qq=BMHD2_BLK_ARRAY;
      MemSet(qq,0,sizeof(U64)*8);
      menu_ptr=BMHD2_BOOT_MSG;
      SPrintF(menu_ptr,"\n\r\n\rLoseThos Boot Loader\n\r\n\r");
      j=0;
      if (FileFind(OLDMBR_BIC,&de,FALSE,TRUE)) {
        *qq++=p->data+de.cluster*p->spc;
        StrCat(menu_ptr,"0. Old Boot Record\n\r");
        j++;
      }

      ptr=buf2;
      while (ch=*ptr++) {
        try
          p1=Drv2Prt(ch);
        catch {
          Fs->catch_except=TRUE;
          p1=NULL;
        }
        if (p1) {
          bd1=p1->bdev;
          try {
            while (bd1->non_lt_drv) { //I think this would be insane, actually.
              p2=Drv2Prt(bd1->non_lt_drv);
              bd1=Drv2BlkDev(Prt2Drv(p2));
            }
          } catch
            Fs->catch_except=TRUE;
          if (bd1==bdev) {
            *qq=p1->offset;
            "Drive %c:%16X\n",Prt2Drv(p1),*qq;
            SPrintF(buf,"%d. Drive %c\n\r",j++,Prt2Drv(p1));
            StrCat(menu_ptr,buf);
            qq++;
          }
        }
      }
      StrCat(menu_ptr,"\n\rSelection:");

      size=BMHD2_END-BMHD2_START;
      FileWrite(BOOTLOADER_BIC,BMHD2_START,size);

      if (!FileFind(BOOTLOADER_BIC,&de,FALSE,TRUE))
        "No Boot Loader Image\n";
      else {
        _w=BMHD_BLK_CNT;
        *_w=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
        qq=BMHD_DAP_BLK;
        *qq=p->data+de.cluster*p->spc;
        _b=BMHD_CODE;
        //Bypass partition bounds-checking
        BlkDevLock(bdev);
        ATAReadBlks(bdev,&mbr,0,1);
        for (i=0;i<BMHD_END-BMHD_CODE;i++)
          mbr.boot_code[i]=_b[i];
        for (;i<440;i++)
          mbr.boot_code[i]=0;
        if (!mbr.media_id)
          mbr.media_id=RandU32;
        mbr.zero=0;
        mbr.signature=0xAA55;

        ATAWriteBlks(bdev,&mbr,0,1);
        BlkDevUnlock(bdev);
        result=TRUE;
      }
    }
  } catch
    CatchAll;
  return result;
}

#help_index "Boot"

/*
These routines are intended for use when
booted to the production CD.  They
allow compiling and booting the RAM Drive 'B'.

These are good when you are trying to get
a new system working and you don't want to
burn a CD-ROM for each attempt.

If you alter the kernel, the RAM drive might
shift to a new location and data will not be
recognized.
*/

public U0 CmpProdCDROM(U8 src_drv,U8 dst_drv=0)
{
  Auto(PROD_CDROM_CFG);
  InstallBoot(src_drv,dst_drv);
}

public U0 Install2RAMDrv(U8 src_drv='T',U8 dst_drv='B')
{
  U8 buf_s[64],buf_d[64];
  Fmt(dst_drv,TRUE,FALSE);
  SPrintF(buf_s,"%C:/",src_drv);
  SPrintF(buf_d,"%C:/",dst_drv);
  CopyTree(buf_s,buf_d);
  CmpProdCDROM(dst_drv);
}

public U0 Boot2RAMDrv(U8 drv_let='B')
{
  U8 buf[64];
  CmpProdCDROM(drv_let);
  SPrintF(buf,"%C:/Boot.BIC",drv_let);
  Boot(buf);
}

#help_index ""
Historical capture: 2012-03-03. Home | Power on LoseThos | Sources and changes