Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

399 lines
10 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Copyright (c) 1992 Digital Equipment Corporation
  4. Module Name:
  5. palldr.c
  6. Abstract:
  7. This module implements the code to load the PAL image into memory.
  8. Author:
  9. Rod N. Gamache [DEC] 12-Sep-1992
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. --*/
  14. #include "bldr.h"
  15. #include "stdio.h"
  16. #include "string.h"
  17. #include "ntimage.h"
  18. #define ALIGN_PAL 0x10000 // Align PAL on 64KB boundary
  19. #define ALIGN_PAL_PAGE (ALIGN_PAL >> PAGE_SHIFT)
  20. extern ULONG BlConsoleOutDeviceId;
  21. extern ULONG BlConsoleInDeviceId;
  22. ARC_STATUS
  23. BlLoadPal(
  24. IN ULONG DeviceId,
  25. IN TYPE_OF_MEMORY MemoryType,
  26. IN PCHAR LoadPath,
  27. IN USHORT ImageType,
  28. OUT PVOID *ImageBase,
  29. IN PCHAR LoadDevice
  30. )
  31. /*++
  32. Routine Description:
  33. This routine attempts to load the PAL file from the specified
  34. load path.
  35. Arguments:
  36. DeviceId - Supplies the file table index of the device to load the
  37. specified image file from.
  38. MemoryType - Supplies the type of memory to to be assigned to the
  39. allocated memory descriptor.
  40. LoadPath - Supplies a pointer to string descriptor for the name of
  41. the path to the PAL file to load.
  42. ImageBase - Supplies a pointer to a variable that receives the
  43. address of the PAL image base.
  44. LoadDevice - Supplies a pointer to a string descriptor for the name
  45. of the load device.
  46. Return Value:
  47. ESUCCESS is returned if the specified image file is loaded
  48. successfully. Otherwise, an unsuccessful status is returned
  49. that describes the reason for failure.
  50. --*/
  51. {
  52. CHAR PalName[256];
  53. CHAR PalFileName[32];
  54. ARC_STATUS Status;
  55. CHAR OutputBuffer[256];
  56. ULONG Count;
  57. PIMAGE_NT_HEADERS NtHeaders;
  58. PIMAGE_SECTION_HEADER SectionHeader;
  59. PMEMORY_ALLOCATION_DESCRIPTOR PalMemoryDescriptor;
  60. PMEMORY_ALLOCATION_DESCRIPTOR NewMemoryDescriptor;
  61. ULONG StartVA;
  62. PVOID PalImageBase;
  63. PVOID NewImageBase;
  64. ULONG PalPage;
  65. ULONG PageCount;
  66. ULONG NewPageCount;
  67. ULONG ActualBase;
  68. ULONG FreePageCount;
  69. Status = BlGeneratePalName( PalFileName );
  70. if ( Status != ESUCCESS ) {
  71. return Status;
  72. }
  73. sprintf(PalName, "%s%s", LoadPath, PalFileName);
  74. BlOutputLoadMessage(LoadDevice, PalName);
  75. Status = BlLoadImage(DeviceId,
  76. MemoryType,
  77. PalName,
  78. ImageType,
  79. ImageBase);
  80. if ( Status != ESUCCESS ) {
  81. return Status;
  82. }
  83. NtHeaders = RtlImageNtHeader(*ImageBase);
  84. if (!NtHeaders) {
  85. return EBADF;
  86. }
  87. //
  88. // Compute the address of the section headers and calculate the
  89. // starting virtual address for the image.
  90. //
  91. SectionHeader =
  92. (PIMAGE_SECTION_HEADER)((ULONG)NtHeaders + sizeof(ULONG) +
  93. sizeof(IMAGE_FILE_HEADER) + NtHeaders->FileHeader.SizeOfOptionalHeader);
  94. StartVA = SectionHeader->VirtualAddress;
  95. PalImageBase = (PVOID)((ULONG)*ImageBase & ~KSEG0_BASE);
  96. PalPage = (ULONG)PalImageBase >> PAGE_SHIFT;
  97. //
  98. // Check if PAL is aligned correctly. If not, then allocate a new
  99. // memory descriptor and copy the PAL image to an aligned buffer.
  100. //
  101. //
  102. // Find the memory descriptor for the PAL image that was loaded,
  103. // and find the size (in pages) of that loaded image.
  104. //
  105. PalMemoryDescriptor = BlFindMemoryDescriptor(PalPage);
  106. PageCount = PalMemoryDescriptor->PageCount;
  107. if ( ((ULONG)PalImageBase & (ALIGN_PAL - 1)) != 0 ) {
  108. //
  109. // Calculate new size + alignment requirement, and allocate a new
  110. // memory descriptor. Use any physical address starting from zero.
  111. //
  112. NewPageCount = PageCount + ALIGN_PAL_PAGE - 1;
  113. //
  114. // Allocate a memory descriptor.
  115. //
  116. Status = BlAllocateDescriptor(MemoryType,
  117. 0,
  118. NewPageCount,
  119. &ActualBase);
  120. if (Status != ESUCCESS) {
  121. return Status;
  122. }
  123. NewMemoryDescriptor = BlFindMemoryDescriptor(ActualBase);
  124. //
  125. // Align PAL to 64KB boundary. First, return any free memory at front
  126. // of PAL image.
  127. //
  128. if ( (ActualBase & (ALIGN_PAL_PAGE - 1)) != 0 ) {
  129. NewMemoryDescriptor = BlFindMemoryDescriptor(ActualBase);
  130. FreePageCount = ALIGN_PAL_PAGE - (ActualBase & (ALIGN_PAL_PAGE-1));
  131. BlGenerateDescriptor(NewMemoryDescriptor,
  132. MemoryFree,
  133. ActualBase,
  134. FreePageCount);
  135. //
  136. // Adjust base and pagecount
  137. //
  138. ActualBase = (ActualBase + (ALIGN_PAL - 1 >> PAGE_SHIFT)) &
  139. ~(ALIGN_PAL_PAGE - 1);
  140. NewPageCount -= FreePageCount;
  141. }
  142. //
  143. // Compute the new image base.
  144. //
  145. NewImageBase = (PVOID)(KSEG0_BASE | (ActualBase << PAGE_SHIFT));
  146. //
  147. // Copy PAL from the loaded memory block to the new memory block.
  148. //
  149. PalImageBase = (PVOID)(KSEG0_BASE | (ULONG)PalImageBase);
  150. RtlMoveMemory(NewImageBase,
  151. (PVOID)((PUCHAR)PalImageBase + StartVA),
  152. (PageCount << PAGE_SHIFT) - StartVA);
  153. //
  154. // Free the original memory descriptor.
  155. //
  156. BlGenerateDescriptor(PalMemoryDescriptor,
  157. MemoryFree,
  158. PalMemoryDescriptor->BasePage,
  159. PalMemoryDescriptor->PageCount);
  160. *ImageBase = NewImageBase;
  161. //
  162. // Return any blocks free at the end of the new image section.
  163. //
  164. FreePageCount = NewPageCount - PageCount + (StartVA >> PAGE_SHIFT);
  165. if ( FreePageCount ) {
  166. BlGenerateDescriptor(NewMemoryDescriptor,
  167. MemoryFree,
  168. ActualBase + PageCount - (StartVA >> PAGE_SHIFT),
  169. FreePageCount);
  170. }
  171. } else if ( StartVA != 0 ) {
  172. //
  173. // Move the image down to the start of the memory descriptor
  174. //
  175. PalImageBase = (PVOID)(KSEG0_BASE | (ULONG)PalImageBase);
  176. RtlMoveMemory(PalImageBase,
  177. (PVOID)((PUCHAR)PalImageBase + StartVA),
  178. (PageCount << PAGE_SHIFT) - StartVA);
  179. //
  180. // Return any blocks free at the end of the image.
  181. //
  182. FreePageCount = StartVA >> PAGE_SHIFT;
  183. if ( FreePageCount ) {
  184. BlGenerateDescriptor(PalMemoryDescriptor,
  185. MemoryFree,
  186. PalPage + PageCount - (StartVA >> PAGE_SHIFT),
  187. FreePageCount);
  188. }
  189. }
  190. return ESUCCESS;
  191. }
  192. ARC_STATUS
  193. BlGeneratePalName(
  194. IN PCHAR PalFileName
  195. )
  196. /*++
  197. Routine Description:
  198. This routine generates the name of the correct PAL file for the current
  199. system.
  200. Arguments:
  201. PalFileName - Supplies a pointer to string for the name of the PAL file
  202. that is generated.
  203. Return Value:
  204. ESUCCESS is returned if the specified PAL file name is generated.
  205. Otherwise, an unsuccessful status is returned that describes the
  206. reason for failure.
  207. --*/
  208. {
  209. CHAR ProcessorName[32] = "";
  210. PCHAR ProcessorId;
  211. PCONFIGURATION_COMPONENT ComponentInfo;
  212. ARC_STATUS Status;
  213. ULONG Max = 7;
  214. //
  215. // Get the Processor Id Name from the ARC component Database.
  216. //
  217. ComponentInfo = ArcGetChild(NULL); // Get ARC component info
  218. while (ComponentInfo != NULL) {
  219. if ( ComponentInfo->Class == SystemClass &&
  220. ComponentInfo->Identifier != NULL ) {
  221. ComponentInfo = ArcGetChild(ComponentInfo); // Go Down in tree
  222. } else if ( ComponentInfo->Class == ProcessorClass &&
  223. ComponentInfo->Type == CentralProcessor &&
  224. ComponentInfo->Identifier != NULL) {
  225. strncat(ProcessorName, ComponentInfo->Identifier, 31);
  226. break;
  227. } else {
  228. ComponentInfo = ArcGetPeer(ComponentInfo); // Look through all entries
  229. }
  230. }
  231. //
  232. // On older firmware:
  233. //
  234. // The ProcessorName is of the form: mmm-rName, where:
  235. // mmm - is the manufacturer of the processor chip
  236. // r - is the revision of the processor chip
  237. // Name - is the name of the processor chip
  238. //
  239. // E.G. DEC-321064
  240. //
  241. // On newer firmware:
  242. //
  243. // The ProcessorName is of the form: mmm-Name-r, where:
  244. // mmm - is the manufacturer of the processor chip
  245. // r - is the revision of the processor chip
  246. // Name - is the name of the processor chip
  247. //
  248. // E.G. DEC-21064-3
  249. //
  250. ProcessorId = strchr(ProcessorName, '-');
  251. //
  252. // Load the PAL image into memory. The image will be of the
  253. // form <LoadPath>\Axxxxx.PAL. Try loading A<processorname>.PAL.
  254. // If that fails, then try AlphaAXP.pal.
  255. //
  256. //
  257. // Generate the full path name for the PAL image and load it into
  258. // memory.
  259. //
  260. Status = EBADF;
  261. if ( ProcessorId ) {
  262. CHAR ProcessorIdName[8] = "";
  263. PCHAR RevisionId;
  264. ULONG Max = 7;
  265. ProcessorId++; // Skip the hyphen
  266. //
  267. // Check for new ProcessorId format, look for the revision id
  268. // after the processor id.
  269. //
  270. RevisionId = strchr(ProcessorId, '-');
  271. if ( RevisionId ) {
  272. *RevisionId = '\0'; // Terminate the processor id
  273. RevisionId++; // Skip the hyphen
  274. strncat(ProcessorIdName, RevisionId, 2); // Copy Revision Id
  275. Max = Max - strlen( ProcessorIdName );
  276. }
  277. strncat(ProcessorIdName, ProcessorId, Max); // Copy Processor Id
  278. sprintf(PalFileName, "A%s.PAL", ProcessorIdName);
  279. Status = ESUCCESS;
  280. }
  281. return Status;
  282. }