2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/freeldr/arch/i386/ramdisk.c
5 * PURPOSE: Implements routines to support booting from a RAM Disk
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
20 /* FUNCTIONS ******************************************************************/
24 RamDiskGetDataAtOffset(IN PVOID Offset
)
27 // Return data from our RAM Disk
29 ASSERT(((ULONG_PTR
)gRamDiskBase
+ (ULONG_PTR
)Offset
) <
30 ((ULONG_PTR
)gRamDiskBase
+ (ULONG_PTR
)gRamDiskSize
));
31 return (PVOID
)((ULONG_PTR
)gRamDiskBase
+ (ULONG_PTR
)(Offset
));
35 RamDiskGetCacheableBlockCount(IN ULONG Reserved
)
38 // Allow 32KB transfers (64 sectors), emulating BIOS LBA
40 ASSERT(Reserved
== 0x49);
45 RamDiskGetDriveGeometry(IN ULONG Reserved
,
46 OUT PGEOMETRY Geometry
)
49 // Should never be called when the caller expects valid Geometry!
51 ASSERT(Reserved
== 0x49);
56 RamDiskReadLogicalSectors(IN ULONG Reserved
,
57 IN ULONGLONG SectorNumber
,
63 ASSERT(Reserved
== 0x49);
66 // Get actual pointers and lengths
68 StartAddress
= (PVOID
)((ULONG_PTR
)SectorNumber
* 512);
69 Length
= SectorCount
* 512;
72 // Don't allow reads past our image
74 if (((ULONG_PTR
)StartAddress
+ Length
) > gRamDiskSize
) return FALSE
;
79 RtlCopyMemory(Buffer
, RamDiskGetDataAtOffset(StartAddress
), Length
);
85 RamDiskLoadVirtualFile(IN PCHAR FileName
)
88 ULONG TotalRead
, ChunkSize
;
89 PCHAR MsgBuffer
= "Loading ramdisk...";
90 ULONG PercentPerChunk
, Percent
;
95 UiDrawProgressBarCenter(1, 100, MsgBuffer
);
98 // Try opening the ramdisk file (this assumes the boot volume was opened)
100 RamFile
= FsOpenFile(FileName
);
106 gRamDiskSize
= FsGetFileSize(RamFile
);
107 if (!gRamDiskSize
) return;
110 // Allocate memory for it
112 ChunkSize
= 8 * 1024 * 1024;
113 Percent
= PercentPerChunk
= 100 / (gRamDiskSize
/ ChunkSize
);
114 gRamDiskBase
= MmAllocateMemory(gRamDiskSize
);
115 if (!gRamDiskBase
) return;
120 for (TotalRead
= 0; TotalRead
< gRamDiskSize
; TotalRead
+= ChunkSize
)
123 // Check if we're at the last chunk
125 if ((gRamDiskSize
- TotalRead
) < ChunkSize
)
128 // Only need the actual data required
130 ChunkSize
= gRamDiskSize
- TotalRead
;
136 UiDrawProgressBarCenter(Percent
, 100, MsgBuffer
);
137 Percent
+= PercentPerChunk
;
143 if (!FsReadFile(RamFile
,
146 (PVOID
)((ULONG_PTR
)gRamDiskBase
+ TotalRead
)))
151 UiMessageBox("Failed to read ramdisk\n");
159 RamDiskSwitchFromBios(VOID
)
161 extern ULONG BootDrive
, BootPartition
;
164 // Check if we have a ramdisk, in which case we need to switch routines
169 // Don't use the BIOS for reads anymore
171 MachVtbl
.DiskReadLogicalSectors
= RamDiskReadLogicalSectors
;
172 MachVtbl
.DiskGetDriveGeometry
= RamDiskGetDriveGeometry
;
173 MachVtbl
.DiskGetCacheableBlockCount
= RamDiskGetCacheableBlockCount
;
176 // Switch to ramdisk boot partition