DIRECTORY BootFile USING [ Location ], Booting USING [ CheckpointProc, RegisterProcs, RollbackProc ], BootStartList USING [EntryPointer, Enumerate, IndexToEntryPointer, IndexToSpaceEntryPointer, Proc, SpaceEntryPointer], DebuggerSwap USING [ CallDebugger, NoteDiskDebugger ], Disk USING [ Channel, DriveAttributes, GetPageNumber, NextChannel, PageNumber ], DiskFace USING [ Type ], File USING [ Error, FindVolumeFromName, FP, Handle, NextVolume, nullFP, Open, PageCount, PageNumber, Read, Volume ], FileBackdoor USING [ GetRoot], FileInternal USING [ Commit, GetLogicalLocation, GetPhysicalLocation, LockAndCloseFiles, LockVolume, ReadRootPage, RegisterVMFile, UnlockFiles, VolumeObject ], GermSwap USING [ bootedFrom, switches ], MPCodes USING [ fileInitialized ], PhysicalVolume USING [ GetPhysical, SubVolumeDetails ], Process USING [Detach], ProcessorFace USING [ SetMP ], VM USING [AddressForPageNumber, Interval, MakeReadOnly], VolumeFormat USING [ nullDiskFileID, RelID ]; FileInit: CEDAR MONITOR IMPORTS Booting, BootStartList, DebuggerSwap, Disk, File, FileBackdoor, FileInternal, GermSwap, PhysicalVolume, Process, ProcessorFace, VM EXPORTS DiskFace--RelID--, File = { Volume: TYPE = REF VolumeObject; VolumeObject: PUBLIC TYPE = FileInternal.VolumeObject; FindVolumeFromLocation: PROC [loc: BootFile.Location] RETURNS [File.Volume] = { FOR channel: Disk.Channel _ Disk.NextChannel[NIL], Disk.NextChannel[channel] UNTIL channel = NIL DO IF Disk.DriveAttributes[channel].type = loc.deviceType THEN EXIT REPEAT FINISHED => RETURN[NIL] ENDLOOP; FOR v: Volume _ File.NextVolume[NIL,FALSE], File.NextVolume[v,FALSE] UNTIL v = NIL DO FOR sv: LIST OF PhysicalVolume.SubVolumeDetails _ v.subVolumes, sv.rest UNTIL sv = NIL DO type: DiskFace.Type; ordinal: CARDINAL; [type: type, ordinal: ordinal] _ Disk.DriveAttributes[sv.first.channel]; IF type = loc.deviceType AND ordinal = loc.deviceOrdinal THEN { page: Disk.PageNumber = Disk.GetPageNumber[sv.first.channel, loc.diskFileID.firstLink]; IF page >= sv.first.address AND page < (sv.first.address + sv.first.size) THEN RETURN[v]; }; ENDLOOP; ENDLOOP; RETURN[NIL] }; systemVolume: Volume _ NIL; --File.--FindSystemVolume: PUBLIC ENTRY PROC RETURNS [found: BOOL] = { ENABLE UNWIND => NULL; IF systemVolume = NIL THEN { systemVolume _ FindVolumeFromLocation[GermSwap.bootedFrom.location]; IF systemVolume # NIL AND systemVolume.rootStatus = nonCedarVolume THEN systemVolume _ File.FindVolumeFromName["Cedar"]; }; FindDebugger[]; RETURN[systemVolume # NIL] }; --File.--SystemVolume: PUBLIC ENTRY PROC RETURNS [volume: Volume] = { RETURN[IF systemVolume = NIL OR systemVolume.destroyed THEN NIL ELSE systemVolume]; }; --File.--SetSystemVolume: PUBLIC ENTRY PROC [volume: Volume] = { systemVolume _ volume; FindDebugger[ ! UNWIND => NULL]; }; debuggerFound: BOOL _ FALSE; FindDebugger: INTERNAL PROC = TRUSTED { IF systemVolume = NIL OR debuggerFound THEN RETURN; FOR v: Volume _ File.NextVolume[NIL], File.NextVolume[v] UNTIL v = NIL DO IF (v.rootStatus = ok OR v.rootStatus = nonCedarVolume) AND v.root.bootingInfo[debuggee] # VolumeFormat.nullDiskFileID AND systemVolume # NIL AND ( SELECT systemVolume.root.type FROM pilot => v.root.type = pilotDebugger, pilotDebugger => v.root.type = pilotDebuggerDebugger, pilotDebuggerDebugger => FALSE, cedar => IF v.root.type = cedar THEN ( NOT systemVolume.root.coCedar AND v.root.coCedar) ELSE v.root.type = pilotDebugger -- change to FALSE after bootstrap to 5.0--, ENDCASE => FALSE) THEN { type: DiskFace.Type; ordinal: CARDINAL; [type: type, ordinal: ordinal] _ Disk.DriveAttributes[v.subVolumes.first.channel]; DebuggerSwap.NoteDiskDebugger[ debugger: [type, ordinal, disk[v.root.bootingInfo[debugger]]], debuggee: [type, ordinal, disk[v.root.bootingInfo[debuggee]]] ]; debuggerFound _ TRUE; EXIT }; ENDLOOP; }; RelocateDebugger: ENTRY PROC = { debuggerFound _ FALSE; FindDebugger[ ! UNWIND => NULL]; }; vmFound: BOOL _ FALSE; CheckVMFP: PROC [volume: Volume] RETURNS [BOOL] = { fp: File.FP = FileBackdoor.GetRoot[volume, VM ! File.Error => GOTO noGo ].fp; file: File.Handle = File.Open[volume, fp ! File.Error => GOTO noGo ]; FileInternal.RegisterVMFile[file]; RETURN[vmFound _ TRUE]; EXITS noGo => RETURN[FALSE] }; bootFileRead: BOOL _ FALSE; --File.--FindVM: PUBLIC ENTRY PROC RETURNS [found: BOOL _ FALSE] = TRUSTED { ENABLE UNWIND => NULL; IF vmFound THEN RETURN[TRUE]; IF systemVolume # NIL THEN { IF CheckVMFP[systemVolume] THEN found _ TRUE ELSE FOR v: Volume _ File.NextVolume[NIL], File.NextVolume[v] UNTIL v = NIL DO weAreCoCedar: BOOL = systemVolume.rootStatus = ok AND systemVolume.root.coCedar; itsCoCedar: BOOL = v.rootStatus = ok AND v.root.coCedar; IF itsCoCedar = weAreCoCedar AND CheckVMFP[v] THEN { found _ TRUE; EXIT }; ENDLOOP; }; IF NOT bootFileRead THEN { bootFileRead _ TRUE; CopyBootFile[]--releases monitor-- }; TRUSTED {IF GermSwap.switches[four] THEN DebuggerSwap.CallDebugger["Key stop 4"L]}; }; CheckpointThings: ENTRY PROC = { ENABLE UNWIND => NULL; checkPointExists: BOOL _ systemVolume # NIL; IF checkPointExists THEN checkPointExists _ (FileBackdoor.GetRoot[systemVolume, checkpoint ! File.Error => { checkPointExists _ FALSE; CONTINUE }].fp # File.nullFP); IF checkPointExists THEN { bootedLoc: BootFile.Location = GermSwap.bootedFrom.location; Equal: PROC [diskLoc: --disk-- BootFile.Location] RETURNS [BOOL] = TRUSTED { RETURN[diskLoc.deviceType = bootedLoc.deviceType AND diskLoc.deviceOrdinal = bootedLoc.deviceOrdinal AND diskLoc.diskFileID = bootedLoc.diskFileID]; }; IF Equal[FileInternal.GetLogicalLocation[systemVolume,bootFile]] OR Equal[FileInternal.GetPhysicalLocation[PhysicalVolume.GetPhysical[systemVolume],bootFile]] THEN GermSwap.switches[r] _ TRUE; } ELSE GermSwap.switches[r] _ FALSE; IF GermSwap.switches[f] THEN GermSwap.switches[r] _ FALSE; Booting.RegisterProcs[c: MyCheckpoint, r: MyRollback]; }; MyCheckpoint: Booting.CheckpointProc = { FOR volume: File.Volume _ File.NextVolume[NIL,FALSE], File.NextVolume[volume, FALSE] UNTIL volume = NIL DO FileInternal.Commit[volume ! File.Error => CONTINUE]; ENDLOOP; FileInternal.LockAndCloseFiles[]; FOR volume: File.Volume _ File.NextVolume[NIL,FALSE], File.NextVolume[volume, FALSE] UNTIL volume = NIL DO FileInternal.LockVolume[volume]; ENDLOOP; }; MyRollback: Booting.RollbackProc = { FileInternal.UnlockFiles[]; FOR volume: File.Volume _ File.NextVolume[NIL,FALSE], File.NextVolume[volume, FALSE] UNTIL volume = NIL DO FileInternal.ReadRootPage[volume]; ENDLOOP; RelocateDebugger[]; }; --DiskFace.--RelID: PUBLIC TYPE = VolumeFormat.RelID; CopyBootFile: INTERNAL PROC = TRUSTED { maxProcesses: NAT = 2; processesInUse: NAT _ 0; processAvailable: CONDITION _ [timeout: 0]; bootFileVolume: File.Volume; bootFileFP: RelID; bootFileHandle: File.Handle; ForkedRead: UNSAFE PROC [from: File.PageNumber, nPages: File.PageCount, to: LONG POINTER] = UNCHECKED { File.Read[file: bootFileHandle, from: from, nPages: nPages, to: to]; NotifyProcessAvailable[]; }; WaitForAProcess: INTERNAL PROC = CHECKED { WHILE processesInUse = maxProcesses DO WAIT processAvailable ENDLOOP; processesInUse _ processesInUse + 1; }; NotifyProcessAvailable: ENTRY PROC = CHECKED { ENABLE UNWIND => NULL; processesInUse _ processesInUse - 1; NOTIFY processAvailable; }; WaitUntilDone: INTERNAL PROC = CHECKED { UNTIL processesInUse = 0 DO WAIT processAvailable ENDLOOP; }; somethingToDo: BOOL _ FALSE; CheckForSwappedOut: BootStartList.Proc--RETURNS [stop: BOOL_FALSE]-- = UNCHECKED { OPEN BootStartList; entry: EntryPointer = IndexToEntryPointer[index]; WITH e: entry SELECT FROM space => IF ~e.bootLoaded AND e.type.class ~= empty THEN { somethingToDo _ TRUE; stop _ TRUE; }; swapUnit => NULL; ENDCASE => ERROR; }; SwapIn: INTERNAL BootStartList.Proc = UNCHECKED { OPEN BootStartList; entry: EntryPointer = IndexToEntryPointer[index]; WITH e: entry SELECT FROM space => IF ~e.bootLoaded AND e.type.class ~= empty THEN { WaitForAProcess[]; Process.Detach[FORK ForkedRead[ from: [e.backingPage], nPages: e.pages, to: VM.AddressForPageNumber[e.vmPage] ]]; }; swapUnit => NULL; ENDCASE => ERROR; }; MakeReadOnly: BootStartList.Proc = UNCHECKED { OPEN BootStartList; entry: EntryPointer = IndexToEntryPointer[index]; WITH e: entry SELECT FROM swapUnit => { parent: SpaceEntryPointer = IndexToSpaceEntryPointer[e.parent]; IF ~parent.bootLoaded AND e.info.readOnly THEN VM.MakeReadOnly[VM.Interval[parent.vmPage+e.base, e.pages]]; }; space => NULL; ENDCASE => ERROR; }; BootStartList.Enumerate[CheckForSwappedOut]; IF somethingToDo THEN { bootFileVolume _ FindVolumeFromLocation[GermSwap.bootedFrom.location]; IF bootFileVolume = NIL THEN RETURN; bootFileFP _ GermSwap.bootedFrom.location.diskFileID.fID.relID; bootFileHandle _ File.Open[bootFileVolume, bootFileFP ! File.Error => GOTO noGo]; BootStartList.Enumerate[SwapIn]; WaitUntilDone[]; -- before making them read-only! BootStartList.Enumerate[MakeReadOnly]; EXITS noGo => NULL }; }; TRUSTED { IF NOT GermSwap.switches[n] THEN [] _ FindSystemVolume[]; CheckpointThings[]; IF GermSwap.switches[three] THEN DebuggerSwap.CallDebugger["Key stop 3"L]; ProcessorFace.SetMP[MPCodes.fileInitialized]; }; }. ήFileInit.mesa - Files initialisation Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Andrew Birrell November 15, 1983 3:03 pm Levin, September 20, 1983 4:03 pm Russ Atkinson, February 20, 1985 3:06:14 pm PST Bob Hagmann January 31, 1985 11:05:40 am PST Russ Atkinson (RRA) May 15, 1985 8:30:32 pm PDT Operations on the system volume: finding it, finding debugger, finding VM backing file First, check there is a suitable device (otherwise, don't touch the volumes). Then, search for an appropriate logical volume Don't use a non-cedar system volume. Temp kludge: in that case, try Cedar Re-consider debugger location after a rollback We get here regardless of whether we found a VM file. On first time only, read boot file Compiler won't do equality check for me! First, try (but not very hard) to ensure our VAM information is written out Then lock all the files (before the volumes, to avoid deadlocking Then lock all the volumes Unlock the files first, to allow opening the volume VAM files Copying in the non-initial-loaded part of the boot file "bootFileVolume" is logically independent of "SystemVolume[]" Initialization Bob Hagmann January 31, 1985 11:04:48 am PST Cedar 6.0 conversion changes to: DIRECTORY Κ O˜codešœ$™$Kšœ Οmœ7™BKšœ)™)Kšœ!™!Kšœ/™/K™,K™/—K™šΟk ˜ Kšœ žœ˜Kšœžœ1˜>Kšœžœc˜vKšœ žœ$˜6KšœžœF˜PKšœ žœ ˜KšœžœžœJ˜tKšœ žœ ˜Kšœ žœ˜ŸKšœ žœ˜(Kšœžœ˜"Kšœžœ#˜7Kšœžœ ˜Kšœžœ ˜Kšžœžœ0˜8Kšœ žœ˜-—K˜šœ žœž˜Kšžœž˜ŠKšžœ Οc œžœ˜#K˜—KšœV™V˜Kšœžœžœ˜ K˜Kšœžœžœ˜6K˜šΟnœžœžœ˜OKšœM™Mšžœ*žœžœ ž˜cKšžœ5žœž˜@Kšžœžœžœžœ˜Kšžœ˜—Kšœ.™.š žœžœžœžœžœžœž˜Uš žœžœžœ8žœžœž˜YKšœ˜Kšœ žœ˜KšœH˜Hšžœžœžœ˜?KšœW˜WKšžœžœ*˜JKšžœžœ˜Kšœ˜—Kšžœ˜—Kšžœ˜—Kšžœžœ˜ Kšœ˜—K˜Kšœžœ˜K˜š Ÿ  œžœžœžœžœ žœ˜FKšžœžœžœ˜šžœžœ˜KšœD˜DKšœJ™Jšžœžœžœ)˜BKšžœ1˜5—Kšœ˜—K˜Kšžœžœ˜Kšœ˜—K˜š Ÿ   œžœžœžœžœ˜EKšžœžœžœžœžœžœžœ˜SKšœ˜—K˜š Ÿ  œžœžœžœ˜@Kšœ˜Kšœžœžœ˜ Kšœ˜—K˜Kšœžœžœ˜K˜š  œžœžœžœ˜'Kš žœžœžœžœžœ˜3šžœžœžœž˜Išžœžœ˜7Kšžœ;˜>Kšžœž˜šžœžœž˜(Kšœ%˜%Kšœ5˜5Kšœžœ˜šœ žœ˜Kšžœžœžœ˜8KšžœŸ+œ˜M—Kšžœžœ˜—šžœ˜K˜Kšœ žœ˜KšœR˜Ršœ˜Kšœ>˜>Kšœ=˜=Kšœ˜—Kšœžœ˜Kšž˜Kšœ˜———Kšžœ˜Kšœ˜—K˜š œžœžœ˜ Kšœ.™.Kšœžœ˜Kšœžœžœ˜ Kšœ˜—K˜Kšœ žœžœ˜K˜š  œžœžœžœ˜3Kšœ žœ žœžœ ˜MKšœ9žœ˜EKšœ"˜"Kšžœ žœ˜Kšžœ žœžœ˜Kšœ˜—K˜Kšœžœžœ˜K˜šŸ  œžœžœžœžœ žœžœžœ˜LKšžœžœžœ˜Kšžœ žœžœžœ˜šžœžœ˜šžœ˜Kšžœ ž˜šž˜šžœžœžœž˜IKšœžœ žœ˜PKšœ žœžœ˜8šžœžœžœ˜4Kšœžœ˜ Kšžœ˜—Kšžœ˜———Kšœ˜—KšœY™YKš žœžœžœžœŸœ˜UKšžœžœžœ+˜SKšœ˜—K˜š œžœžœ˜ Kšžœžœžœ˜Kšœžœžœ˜,šžœž˜šœA˜AKšœ%žœžœ˜J——šžœ˜šžœ˜Kšœ<˜