2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: GPL - See COPYING 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: alex@winsiderss.com
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
45 RamDiskGetDriveGeometry(IN ULONG Reserved
,
46 OUT PGEOMETRY Geometry
)
49 // Should never be called when the caller expects valid Geometry!
55 RamDiskReadLogicalSectors(IN ULONG Reserved
,
56 IN ULONGLONG SectorNumber
,
64 // Get actual pointers and lengths
66 StartAddress
= (PVOID
)((ULONG
)SectorNumber
* 512);
67 Length
= SectorCount
* 512;
70 // Don't allow reads past our image
72 if (((ULONG_PTR
)StartAddress
+ Length
) > gRamDiskSize
) return FALSE
;
77 RtlCopyMemory(Buffer
, RamDiskGetDataAtOffset(StartAddress
), Length
);
83 RamDiskCheckForVirtualFile(VOID
)
86 ULONG TotalRead
, ChunkSize
;
89 // Try opening the ramdisk file (this assumes the boot volume was opened)
91 RamFile
= FsOpenFile("reactos.img");
97 gRamDiskSize
= FsGetFileSize(RamFile
);
98 TuiPrintf("Found virtual ramdisk (%dKB)\n", gRamDiskSize
/ 1024);
99 if (!gRamDiskSize
) return;
102 // Allocate memory for it
104 ChunkSize
= 8 * 1024 * 1024;
105 gRamDiskBase
= MmAllocateMemory(gRamDiskSize
);
106 if (!gRamDiskBase
) return;
111 TuiPrintf("Loading ramdisk @ 0x%x...", gRamDiskBase
);
112 for (TotalRead
= 0; TotalRead
< gRamDiskSize
; TotalRead
+= ChunkSize
)
115 // Check if we're at the last chunk
117 if ((gRamDiskSize
- TotalRead
) < ChunkSize
)
120 // Only need the actual data required
122 ChunkSize
= gRamDiskSize
- TotalRead
;
129 if (!FsReadFile(RamFile
,
132 (PVOID
)((ULONG_PTR
)gRamDiskBase
+ TotalRead
)))
137 TuiPrintf("Failed to read ramdisk\n");
146 RamDiskSwitchFromBios(VOID
)
149 // Check if we have a ramdisk, in which case we need to switch routines
154 // Don't use the BIOS for reads anymore
156 MachVtbl
.DiskReadLogicalSectors
= RamDiskReadLogicalSectors
;
157 MachVtbl
.DiskGetDriveGeometry
= RamDiskGetDriveGeometry
;
158 MachVtbl
.DiskGetCacheableBlockCount
= RamDiskGetCacheableBlockCount
;
161 // Also disable cached FAT reads
163 gCacheEnabled
= FALSE
;
169 RamDiskInit(IN PCHAR CmdLine
)
172 // Get RAM disk parameters
174 gRamDiskBase
= (PVOID
)atoi(strstr(CmdLine
, "rdbase="));
175 gRamDiskSize
= atoi(strstr(CmdLine
, "rdsize="));