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 LONG
RamDiskClose(ULONG FileId
)
32 static LONG
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 LONG
RamDiskOpen(CHAR
* Path
, OPENMODE OpenMode
, ULONG
* FileId
)
47 // Always return success, as contents are already in memory
52 static LONG
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 LONG
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 ret
= ArcOpen(FileName
, OpenReadOnly
, &RamFile
);
145 ret
= ArcGetFileInformation(RamFile
, &Information
);
153 // For now, limit RAM disks to 4GB
155 if (Information
.EndingAddress
.HighPart
!= 0)
157 UiMessageBox("RAM disk too big\n");
161 gRamDiskSize
= Information
.EndingAddress
.LowPart
;
164 // Allocate memory for it
166 ChunkSize
= 8 * 1024 * 1024;
167 if (gRamDiskSize
< ChunkSize
)
168 Percent
= PercentPerChunk
= 0;
170 Percent
= PercentPerChunk
= 100 / (gRamDiskSize
/ ChunkSize
);
171 gRamDiskBase
= MmAllocateMemoryWithType(gRamDiskSize
, LoaderXIPRom
);
174 UiMessageBox("Failed to allocate memory for RAM disk\n");
182 for (TotalRead
= 0; TotalRead
< gRamDiskSize
; TotalRead
+= ChunkSize
)
185 // Check if we're at the last chunk
187 if ((gRamDiskSize
- TotalRead
) < ChunkSize
)
190 // Only need the actual data required
192 ChunkSize
= gRamDiskSize
- TotalRead
;
198 UiDrawProgressBarCenter(Percent
, 100, MsgBuffer
);
199 Percent
+= PercentPerChunk
;
204 Position
.HighPart
= 0;
205 Position
.LowPart
= TotalRead
;
206 ret
= ArcSeek(RamFile
, &Position
, SeekAbsolute
);
209 ret
= ArcRead(RamFile
,
210 (PVOID
)((ULONG_PTR
)gRamDiskBase
+ TotalRead
),
218 if (ret
!= ESUCCESS
|| Count
!= ChunkSize
)
220 MmFreeMemory(gRamDiskBase
);
224 UiMessageBox("Failed to read ramdisk\n");
231 // Register a new device for the ramdisk
232 FsRegisterDevice("ramdisk(0)", &RamDiskVtbl
);