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 ********************************************************************/
19 extern BOOLEAN gCacheEnabled
;
21 /* FUNCTIONS ******************************************************************/
25 RamDiskGetDataAtOffset(IN PVOID Offset
)
28 // Return data from our RAM Disk
30 assert(((ULONG_PTR
)gRamDiskBase
+ (ULONG_PTR
)Offset
) <
31 ((ULONG_PTR
)gRamDiskBase
+ (ULONG_PTR
)gRamDiskSize
));
32 return (PVOID
)((ULONG_PTR
)gRamDiskBase
+ (ULONG_PTR
)(Offset
));
36 RamDiskGetCacheableBlockCount(IN ULONG Reserved
)
39 // Allow 32KB transfers (64 sectors), emulating BIOS LBA
41 ASSERT(Reserved
== 0x49);
46 RamDiskGetDriveGeometry(IN ULONG Reserved
,
47 OUT PGEOMETRY Geometry
)
50 // Should never be called when the caller expects valid Geometry!
52 ASSERT(Reserved
== 0x49);
57 RamDiskReadLogicalSectors(IN ULONG Reserved
,
58 IN ULONGLONG SectorNumber
,
64 ASSERT(Reserved
== 0x49);
67 // Get actual pointers and lengths
69 StartAddress
= (PVOID
)((ULONG
)SectorNumber
* 512);
70 Length
= SectorCount
* 512;
73 // Don't allow reads past our image
75 if (((ULONG_PTR
)StartAddress
+ Length
) > gRamDiskSize
) return FALSE
;
80 RtlCopyMemory(Buffer
, RamDiskGetDataAtOffset(StartAddress
), Length
);
86 RamDiskCheckForVirtualFile(VOID
)
89 ULONG TotalRead
, ChunkSize
;
92 // Try opening the ramdisk file (this assumes the boot volume was opened)
94 RamFile
= FsOpenFile("reactos.img");
100 gRamDiskSize
= FsGetFileSize(RamFile
);
101 TuiPrintf("Found virtual ramdisk (%dKB)\n", gRamDiskSize
/ 1024);
102 if (!gRamDiskSize
) return;
105 // Allocate memory for it
107 ChunkSize
= 8 * 1024 * 1024;
108 gRamDiskBase
= MmAllocateMemory(gRamDiskSize
);
109 if (!gRamDiskBase
) return;
114 TuiPrintf("Loading ramdisk @ 0x%x...", gRamDiskBase
);
115 for (TotalRead
= 0; TotalRead
< gRamDiskSize
; TotalRead
+= ChunkSize
)
118 // Check if we're at the last chunk
120 if ((gRamDiskSize
- TotalRead
) < ChunkSize
)
123 // Only need the actual data required
125 ChunkSize
= gRamDiskSize
- TotalRead
;
132 if (!FsReadFile(RamFile
,
135 (PVOID
)((ULONG_PTR
)gRamDiskBase
+ TotalRead
)))
140 TuiPrintf("Failed to read ramdisk\n");
149 RamDiskSwitchFromBios(VOID
)
151 extern ULONG BootDrive
, BootPartition
;
154 // Check if we have a ramdisk, in which case we need to switch routines
159 // Don't use the BIOS for reads anymore
161 MachVtbl
.DiskReadLogicalSectors
= RamDiskReadLogicalSectors
;
162 MachVtbl
.DiskGetDriveGeometry
= RamDiskGetDriveGeometry
;
163 MachVtbl
.DiskGetCacheableBlockCount
= RamDiskGetCacheableBlockCount
;
166 // Also disable cached FAT reads
168 gCacheEnabled
= FALSE
;
171 // Switch to ramdisk boot partition