- Implement beginnings of Ramdisk Port Driver. Planning compatibility with ISO, SDI...
[reactos.git] / reactos / boot / freeldr / freeldr / disk / ramdisk.c
1 /*
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
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 ASSERT(Reserved == 0x49);
42 return 64;
43 }
44
45 BOOLEAN
46 RamDiskGetDriveGeometry(IN ULONG Reserved,
47 OUT PGEOMETRY Geometry)
48 {
49 //
50 // Should never be called when the caller expects valid Geometry!
51 //
52 ASSERT(Reserved == 0x49);
53 return TRUE;
54 }
55
56 BOOLEAN
57 RamDiskReadLogicalSectors(IN ULONG Reserved,
58 IN ULONGLONG SectorNumber,
59 IN ULONG SectorCount,
60 IN PVOID Buffer)
61 {
62 PVOID StartAddress;
63 ULONG Length;
64 ASSERT(Reserved == 0x49);
65
66 //
67 // Get actual pointers and lengths
68 //
69 StartAddress = (PVOID)((ULONG)SectorNumber * 512);
70 Length = SectorCount * 512;
71
72 //
73 // Don't allow reads past our image
74 //
75 if (((ULONG_PTR)StartAddress + Length) > gRamDiskSize) return FALSE;
76
77 //
78 // Do the read
79 //
80 RtlCopyMemory(Buffer, RamDiskGetDataAtOffset(StartAddress), Length);
81 return TRUE;
82 }
83
84 VOID
85 NTAPI
86 RamDiskCheckForVirtualFile(VOID)
87 {
88 PFILE RamFile;
89 ULONG TotalRead, ChunkSize;
90
91 //
92 // Try opening the ramdisk file (this assumes the boot volume was opened)
93 //
94 RamFile = FsOpenFile("reactos.img");
95 if (RamFile)
96 {
97 //
98 // Get the file size
99 //
100 gRamDiskSize = FsGetFileSize(RamFile);
101 TuiPrintf("Found virtual ramdisk (%dKB)\n", gRamDiskSize / 1024);
102 if (!gRamDiskSize) return;
103
104 //
105 // Allocate memory for it
106 //
107 ChunkSize = 8 * 1024 * 1024;
108 gRamDiskBase = MmAllocateMemory(gRamDiskSize);
109 if (!gRamDiskBase) return;
110
111 //
112 // Read it in chunks
113 //
114 TuiPrintf("Loading ramdisk @ 0x%x...", gRamDiskBase);
115 for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize)
116 {
117 //
118 // Check if we're at the last chunk
119 //
120 if ((gRamDiskSize - TotalRead) < ChunkSize)
121 {
122 //
123 // Only need the actual data required
124 //
125 ChunkSize = gRamDiskSize - TotalRead;
126 }
127
128 //
129 // Copy the contents
130 //
131 TuiPrintf(".");
132 if (!FsReadFile(RamFile,
133 ChunkSize,
134 NULL,
135 (PVOID)((ULONG_PTR)gRamDiskBase + TotalRead)))
136 {
137 //
138 // Fail
139 //
140 TuiPrintf("Failed to read ramdisk\n");
141 }
142 }
143 TuiPrintf("\n");
144 }
145 }
146
147 VOID
148 NTAPI
149 RamDiskSwitchFromBios(VOID)
150 {
151 extern ULONG BootDrive, BootPartition;
152
153 //
154 // Check if we have a ramdisk, in which case we need to switch routines
155 //
156 if (gRamDiskBase)
157 {
158 //
159 // Don't use the BIOS for reads anymore
160 //
161 MachVtbl.DiskReadLogicalSectors = RamDiskReadLogicalSectors;
162 MachVtbl.DiskGetDriveGeometry = RamDiskGetDriveGeometry;
163 MachVtbl.DiskGetCacheableBlockCount = RamDiskGetCacheableBlockCount;
164
165 //
166 // Also disable cached FAT reads
167 //
168 gCacheEnabled = FALSE;
169
170 //
171 // Switch to ramdisk boot partition
172 //
173 BootDrive = 0x49;
174 BootPartition = 0;
175 }
176 }