--- FIXED COMMIT LOG FOR r32128. NO CHANGES IN THIS REVISION ---
[reactos.git] / reactos / boot / freeldr / freeldr / disk / ramdisk.c
1 /*
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
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <freeldr.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS ********************************************************************/
16
17 PVOID gRamDiskBase;
18 ULONG gRamDiskSize;
19 extern BOOLEAN gCacheEnabled;
20
21 /* FUNCTIONS ******************************************************************/
22
23 FORCEINLINE
24 PVOID
25 RamDiskGetDataAtOffset(IN PVOID Offset)
26 {
27 //
28 // Return data from our RAM Disk
29 //
30 assert(((ULONG_PTR)gRamDiskBase + (ULONG_PTR)Offset) <
31 ((ULONG_PTR)gRamDiskBase + (ULONG_PTR)gRamDiskSize));
32 return (PVOID)((ULONG_PTR)gRamDiskBase + (ULONG_PTR)(Offset));
33 }
34
35 ULONG
36 RamDiskGetCacheableBlockCount(IN ULONG Reserved)
37 {
38 //
39 // Allow 32KB transfers (64 sectors), emulating BIOS LBA
40 //
41 return 64;
42 }
43
44 BOOLEAN
45 RamDiskGetDriveGeometry(IN ULONG Reserved,
46 OUT PGEOMETRY Geometry)
47 {
48 //
49 // Should never be called when the caller expects valid Geometry!
50 //
51 return TRUE;
52 }
53
54 BOOLEAN
55 RamDiskReadLogicalSectors(IN ULONG Reserved,
56 IN ULONGLONG SectorNumber,
57 IN ULONG SectorCount,
58 IN PVOID Buffer)
59 {
60 PVOID StartAddress;
61 ULONG Length;
62
63 //
64 // Get actual pointers and lengths
65 //
66 StartAddress = (PVOID)((ULONG)SectorNumber * 512);
67 Length = SectorCount * 512;
68
69 //
70 // Don't allow reads past our image
71 //
72 if (((ULONG_PTR)StartAddress + Length) > gRamDiskSize) return FALSE;
73
74 //
75 // Do the read
76 //
77 RtlCopyMemory(Buffer, RamDiskGetDataAtOffset(StartAddress), Length);
78 return TRUE;
79 }
80
81 VOID
82 NTAPI
83 RamDiskCheckForVirtualFile(VOID)
84 {
85 PFILE RamFile;
86 ULONG TotalRead, ChunkSize;
87
88 //
89 // Try opening the ramdisk file (this assumes the boot volume was opened)
90 //
91 RamFile = FsOpenFile("reactos.img");
92 if (RamFile)
93 {
94 //
95 // Get the file size
96 //
97 gRamDiskSize = FsGetFileSize(RamFile);
98 TuiPrintf("Found virtual ramdisk (%dKB)\n", gRamDiskSize / 1024);
99 if (!gRamDiskSize) return;
100
101 //
102 // Allocate memory for it
103 //
104 ChunkSize = 8 * 1024 * 1024;
105 gRamDiskBase = MmAllocateMemory(gRamDiskSize);
106 if (!gRamDiskBase) return;
107
108 //
109 // Read it in chunks
110 //
111 TuiPrintf("Loading ramdisk @ 0x%x...", gRamDiskBase);
112 for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize)
113 {
114 //
115 // Check if we're at the last chunk
116 //
117 if ((gRamDiskSize - TotalRead) < ChunkSize)
118 {
119 //
120 // Only need the actual data required
121 //
122 ChunkSize = gRamDiskSize - TotalRead;
123 }
124
125 //
126 // Copy the contents
127 //
128 TuiPrintf(".");
129 if (!FsReadFile(RamFile,
130 ChunkSize,
131 NULL,
132 (PVOID)((ULONG_PTR)gRamDiskBase + TotalRead)))
133 {
134 //
135 // Fail
136 //
137 TuiPrintf("Failed to read ramdisk\n");
138 }
139 }
140 TuiPrintf("\n");
141 }
142 }
143
144 VOID
145 NTAPI
146 RamDiskSwitchFromBios(VOID)
147 {
148 //
149 // Check if we have a ramdisk, in which case we need to switch routines
150 //
151 if (gRamDiskBase)
152 {
153 //
154 // Don't use the BIOS for reads anymore
155 //
156 MachVtbl.DiskReadLogicalSectors = RamDiskReadLogicalSectors;
157 MachVtbl.DiskGetDriveGeometry = RamDiskGetDriveGeometry;
158 MachVtbl.DiskGetCacheableBlockCount = RamDiskGetCacheableBlockCount;
159
160 //
161 // Also disable cached FAT reads
162 //
163 gCacheEnabled = FALSE;
164 }
165 }
166
167 VOID
168 NTAPI
169 RamDiskInit(IN PCHAR CmdLine)
170 {
171 //
172 // Get RAM disk parameters
173 //
174 gRamDiskBase = (PVOID)atoi(strstr(CmdLine, "rdbase="));
175 gRamDiskSize = atoi(strstr(CmdLine, "rdsize="));
176 }