2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/freeldr/freeldr/disk/ramdisk.c
5 * PURPOSE: Implements routines to support booting from a RAM Disk
6 * PROGRAMMERS: ReactOS Portable Systems Group
10 /* INCLUDES *******************************************************************/
16 /* GLOBALS ********************************************************************/
22 /* FUNCTIONS ******************************************************************/
24 static ARC_STATUS
RamDiskClose(ULONG FileId
)
32 static ARC_STATUS
RamDiskGetFileInformation(ULONG FileId
, FILEINFORMATION
* Information
)
35 // Give current seek offset and ram disk size to caller
37 RtlZeroMemory(Information
, sizeof(FILEINFORMATION
));
38 Information
->EndingAddress
.LowPart
= gRamDiskSize
;
39 Information
->CurrentAddress
.LowPart
= gRamDiskOffset
;
44 static ARC_STATUS
RamDiskOpen(CHAR
* Path
, OPENMODE OpenMode
, ULONG
* FileId
)
47 // Always return success, as contents are already in memory
52 static ARC_STATUS
RamDiskRead(ULONG FileId
, VOID
* Buffer
, ULONG N
, ULONG
* Count
)
59 StartAddress
= (PVOID
)((ULONG_PTR
)gRamDiskBase
+ gRamDiskOffset
);
62 // Don't allow reads past our image
64 if (gRamDiskOffset
+ N
> gRamDiskSize
)
73 RtlCopyMemory(Buffer
, StartAddress
, N
);
79 static ARC_STATUS
RamDiskSeek(ULONG FileId
, LARGE_INTEGER
* Position
, SEEKMODE SeekMode
)
82 // Only accept absolute mode now
84 if (SeekMode
!= SeekAbsolute
)
88 // Check if we're in the ramdisk
90 if (Position
->HighPart
!= 0)
92 if (Position
->LowPart
>= gRamDiskSize
)
96 // OK, remember seek position
98 gRamDiskOffset
= Position
->LowPart
;
103 static const DEVVTBL RamDiskVtbl
= {
105 RamDiskGetFileInformation
,
113 RamDiskInitialize(VOID
)
115 /* Setup the RAMDISK device */
116 FsRegisterDevice("ramdisk(0)", &RamDiskVtbl
);
121 RamDiskLoadVirtualFile(IN PCHAR FileName
)
124 ULONG TotalRead
, ChunkSize
, Count
;
125 PCHAR MsgBuffer
= "Loading RamDisk...";
126 ULONG PercentPerChunk
, Percent
;
127 FILEINFORMATION Information
;
128 LARGE_INTEGER Position
;
134 UiDrawProgressBarCenter(1, 100, MsgBuffer
);
137 // Try opening the ramdisk file
139 RamFile
= FsOpenFile(FileName
);
146 Status
= ArcGetFileInformation(RamFile
, &Information
);
147 if (Status
!= ESUCCESS
)
149 FsCloseFile(RamFile
);
154 // For now, limit RAM disks to 4GB
156 if (Information
.EndingAddress
.HighPart
!= 0)
158 UiMessageBox("RAM disk too big.");
159 FsCloseFile(RamFile
);
162 gRamDiskSize
= Information
.EndingAddress
.LowPart
;
165 // Allocate memory for it
167 ChunkSize
= 8 * 1024 * 1024;
168 if (gRamDiskSize
< ChunkSize
)
169 Percent
= PercentPerChunk
= 0;
171 Percent
= PercentPerChunk
= 100 / (gRamDiskSize
/ ChunkSize
);
172 gRamDiskBase
= MmAllocateMemoryWithType(gRamDiskSize
, LoaderXIPRom
);
175 UiMessageBox("Failed to allocate memory for RAM disk.");
176 FsCloseFile(RamFile
);
183 for (TotalRead
= 0; TotalRead
< gRamDiskSize
; TotalRead
+= ChunkSize
)
186 // Check if we're at the last chunk
188 if ((gRamDiskSize
- TotalRead
) < ChunkSize
)
191 // Only need the actual data required
193 ChunkSize
= gRamDiskSize
- TotalRead
;
199 UiDrawProgressBarCenter(Percent
, 100, MsgBuffer
);
200 Percent
+= PercentPerChunk
;
205 Position
.HighPart
= 0;
206 Position
.LowPart
= TotalRead
;
207 Status
= ArcSeek(RamFile
, &Position
, SeekAbsolute
);
208 if (Status
== ESUCCESS
)
210 Status
= ArcRead(RamFile
,
211 (PVOID
)((ULONG_PTR
)gRamDiskBase
+ TotalRead
),
219 if (Status
!= ESUCCESS
|| Count
!= ChunkSize
)
221 MmFreeMemory(gRamDiskBase
);
224 FsCloseFile(RamFile
);
225 UiMessageBox("Failed to read RAM disk.");
230 FsCloseFile(RamFile
);
232 // Register a new device for the ramdisk
233 FsRegisterDevice("ramdisk(0)", &RamDiskVtbl
);