DIRECTORY BootFile USING[ Location ], BootStartList USING [EntryPointer, Enumerate, IndexToEntryPointer, IndexToSpaceEntryPointer, Proc, SpaceEntryPointer], DebuggerSwap USING[ CallDebugger, NoteDiskDebugger ], Disk USING[ Channel, DriveAttributes, GetPageNumber, PageNumber ], DiskFace USING[ Type ], File USING[ Error, FP, GetRoot, Handle, NextVolume, Open, PageCount, PageNumber, Read, Volume ], FileInternal USING[ RegisterVMFile, VolumeObject ], GermSwap USING[ bootedFrom, switches ], MPCodes USING[ fileInitialized ], PhysicalVolume USING[ SubVolumeDetails ], Process USING [Detach], ProcessorFace USING[ SetMP ], VM USING [Interval, MakeReadOnly, PageNumberToAddress], VolumeFormat USING[ nullDiskFileID, RelID ]; FileInit: CEDAR MONITOR IMPORTS BootStartList, DebuggerSwap, Disk, File, FileInternal, GermSwap, Process, ProcessorFace, VM EXPORTS DiskFace--RelID--, File = BEGIN Volume: TYPE = REF VolumeObject; VolumeObject: PUBLIC TYPE = FileInternal.VolumeObject; FindVolumeFromLocation: PROC[loc: BootFile.Location] RETURNS[File.Volume] = BEGIN channel: Disk.Channel _ NIL; 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 BEGIN 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]; END; ENDLOOP; ENDLOOP; RETURN[NIL] END; FindSystemVolume: PROC RETURNS[File.Volume] = BEGIN IF GermSwap.switches[n] THEN RETURN[NIL]; RETURN[ FindVolumeFromLocation[GermSwap.bootedFrom.location] ] END; --File.--SystemVolume: PUBLIC PROC RETURNS[volume: Volume] = { RETURN[systemVolume] }; FindDebugger: PROC = TRUSTED BEGIN IF GermSwap.switches[n] OR systemVolume = NIL 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 BEGIN 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]]] ]; EXIT END; ENDLOOP; END; CheckVMFP: PROC[volume: Volume] RETURNS[BOOL] = BEGIN fp: File.FP = File.GetRoot[volume, VM ! File.Error => GOTO noGo ].fp; file: File.Handle = File.Open[volume, fp ! File.Error => GOTO noGo ]; FileInternal.RegisterVMFile[file]; RETURN[TRUE]; EXITS noGo => RETURN[FALSE] END; FindVM: PROC = TRUSTED BEGIN IF GermSwap.switches[n] OR systemVolume = NIL THEN RETURN; IF CheckVMFP[systemVolume] THEN RETURN; 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 RETURN; ENDLOOP; END; --DiskFace.--RelID: PUBLIC TYPE = VolumeFormat.RelID; CopyBootFile: PROC = TRUSTED BEGIN 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: ENTRY PROC = CHECKED { WHILE processesInUse = maxProcesses DO WAIT processAvailable ENDLOOP; processesInUse _ processesInUse + 1; }; NotifyProcessAvailable: ENTRY PROC = CHECKED { processesInUse _ processesInUse - 1; NOTIFY processAvailable; }; WaitUntilDone: ENTRY PROC = CHECKED { UNTIL processesInUse = 0 DO WAIT processAvailable ENDLOOP; }; SwapIn: BootStartList.Proc = UNCHECKED { OPEN BootStartList; entry: EntryPointer = IndexToEntryPointer[index]; WITH e: entry SELECT FROM space => IF ~e.bootLoaded THEN { WaitForAProcess[]; Process.Detach[FORK ForkedRead[ from: [e.backingPage], nPages: e.pages, to: VM.PageNumberToAddress[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; }; IF GermSwap.switches[n] THEN RETURN; bootFileVolume _ FindVolumeFromLocation[GermSwap.bootedFrom.location]; IF bootFileVolume = NIL THEN RETURN; bootFileFP _ GermSwap.bootedFrom.location.diskFileID.fID.relID; bootFileHandle _ File.Open[systemVolume, bootFileFP ! File.Error => GOTO noGo]; BootStartList.Enumerate[SwapIn]; BootStartList.Enumerate[MakeReadOnly]; WaitUntilDone[]; EXITS noGo => NULL END; systemVolume: Volume _ FindSystemVolume[]; FindDebugger[]; FindVM[]; CopyBootFile[]; TRUSTED {IF GermSwap.switches[three] THEN DebuggerSwap.CallDebugger["Key stop 3"L]}; TRUSTED {ProcessorFace.SetMP[MPCodes.fileInitialized]}; END. dCedar Nucleus (Files): initialisation FileInit.mesa Andrew Birrell July 8, 1983 3:01 pm Last Edited by: Levin, June 28, 1983 4:49 pm Operations on the system volume: finding it, finding debugger, finding VM backing file Copying in the non-initial-loaded part of the boot file "bootFileVolume" is logically independent of "SystemVolume[]" Main body ÊϘJšœ&™&Jšœ ™ Jšœ$™$JšÏk,™,š ˜ Jšœ œ ˜Jšœœc˜vJšœ œ#˜5Jšœœ8˜BJšœ œ ˜Jšœœ œK˜`Jšœ œ!˜3Jšœ œ˜'Jšœœ˜!Jšœœ˜)Jšœœ ˜Jšœœ ˜Jšœœ/˜7Jšœ œ˜,—J˜šœ œ˜JšœZ˜cJšœ Ïc œ˜!—J˜Jš˜˜J˜—JšœV™V˜Jšœœœ˜ J˜Jšœœœ˜6J˜šÏnœœœ˜KJš˜Jšœœ˜Jš œœœœœ˜Ršœœœœ8˜JJšœ˜šœ˜Jšœ œ˜JšœH˜HJšœœ˜8šœ˜ JšœW˜WJšœœ*˜JJšœœ˜Jšœ˜——Jšœ˜—Jšœ˜Jšœœ˜ Jšœ˜—J˜šŸœœœ˜-Jš˜Jšœœœœ˜)Jšœ8˜>Jšœ˜—J˜š ž Ÿ œœœœ˜Jšœ˜šœœ˜(Jšœ%˜%Jšœ5˜5Jšœœ˜šœ œ˜Jšœœœ˜8Jšœž+œ˜M—Jšœœ˜—šœ˜ J˜Jšœ œ˜JšœR˜Ršœ˜Jšœ>˜>Jšœ=˜=Jšœ˜—Jš˜Jšœ˜——Jšœ˜Jšœ˜—J˜šŸ œœœœ˜/Jš˜Jšœ œœœ ˜EJšœ9œ˜EJšœ"˜"Jšœœ˜ Jšœ œœ˜Jšœ˜—J˜šŸœœ˜Jš˜Jš œœœœœ˜:Jšœœœ˜'Jšœœœ˜Fšœœ œ˜SJšœ œœ˜8Jšœœœœ˜:—Jšœ˜Jšœ˜J˜J˜—J˜—Jšœ7™7˜Jšž œœœ˜5J˜šŸ œœ˜Jš˜J˜Jšœœ˜J˜Jšœœ˜Jšœ œ˜+J˜Jšœ˜Jšœ˜Jšœ˜J˜š Ÿ œœœ5œœ œ˜gJšœD˜DJ˜J˜—šŸœœœœ˜'Jšœœœœ˜EJ˜$J˜—šŸœœœœ˜.J˜$Jšœ˜J˜—šŸ œœœœ˜%Jšœœœœ˜:J˜—šÏbœ œ˜(Jšœ˜Jšœ1˜1šœ œ˜šœ˜šœœ˜J˜šœœ ˜Jšœ˜Jšœ˜Jšœœ˜$Jšœ˜—J˜——Jšœ œ˜Jšœœ˜—J˜—š  œ œ˜.Jšœ˜Jšœ1˜1šœ œ˜šœ ˜ J˜?šœœ˜.Jšœœ*˜<—J˜—Jšœ œ˜Jšœœ˜—J˜—J˜Jšœœœ˜$Jšœ=™=JšœF˜FJšœœœœ˜$Jšœ?˜?JšœDœ˜OJ˜ J˜&J˜Jšœ ˜Jšœ˜J˜J˜—J˜—Jšœ ™ ˜Jšœ*˜*J˜Jšœ˜J˜J˜ J˜J˜J˜Jšœœœ+˜TJ˜Jšœ0˜7J˜—Jšœ˜J˜J˜—…—’Å