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(*Information
));
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 /* Register 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
;
135 UiDrawProgressBarCenter(1, 100, MsgBuffer
);
138 // Try opening the ramdisk file
140 RamFileId
= FsOpenFile(FileName
);
147 Status
= ArcGetFileInformation(RamFileId
, &Information
);
148 if (Status
!= ESUCCESS
)
155 // For now, limit RAM disks to 4GB
157 if (Information
.EndingAddress
.HighPart
!= 0)
159 UiMessageBox("RAM disk too big.");
163 gRamDiskSize
= Information
.EndingAddress
.LowPart
;
166 // Allocate memory for it
168 ChunkSize
= 8 * 1024 * 1024;
169 if (gRamDiskSize
< ChunkSize
)
170 Percent
= PercentPerChunk
= 0;
172 Percent
= PercentPerChunk
= 100 / (gRamDiskSize
/ ChunkSize
);
173 gRamDiskBase
= MmAllocateMemoryWithType(gRamDiskSize
, LoaderXIPRom
);
176 UiMessageBox("Failed to allocate memory for RAM disk.");
184 for (TotalRead
= 0; TotalRead
< gRamDiskSize
; TotalRead
+= ChunkSize
)
187 // Check if we're at the last chunk
189 if ((gRamDiskSize
- TotalRead
) < ChunkSize
)
192 // Only need the actual data required
194 ChunkSize
= gRamDiskSize
- TotalRead
;
200 UiDrawProgressBarCenter(Percent
, 100, MsgBuffer
);
201 Percent
+= PercentPerChunk
;
206 Position
.HighPart
= 0;
207 Position
.LowPart
= TotalRead
;
208 Status
= ArcSeek(RamFileId
, &Position
, SeekAbsolute
);
209 if (Status
== ESUCCESS
)
211 Status
= ArcRead(RamFileId
,
212 (PVOID
)((ULONG_PTR
)gRamDiskBase
+ TotalRead
),
220 if (Status
!= ESUCCESS
|| Count
!= ChunkSize
)
222 MmFreeMemory(gRamDiskBase
);
226 UiMessageBox("Failed to read RAM disk.");
233 /* Setup the RAMDISK device */