1 /*
2 * PROJECT: ReactOS Boot Loader
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: boot/armllb/os/loader.c
5 * PURPOSE: OS Loader Code for LLB
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 #include "precomp.h"
10
11 BIOS_MEMORY_MAP MemoryMap[32];
12 ARM_BOARD_CONFIGURATION_BLOCK ArmBlock;
13 POSLOADER_INIT LoaderInit;
14
15 VOID
16 NTAPI
LlbAllocateMemoryEntry(IN BIOS_MEMORY_TYPE Type,IN ULONG BaseAddress,IN ULONG Length)17 LlbAllocateMemoryEntry(IN BIOS_MEMORY_TYPE Type,
18 IN ULONG BaseAddress,
19 IN ULONG Length)
20 {
21 PBIOS_MEMORY_MAP Entry;
22
23 /* Get the next memory entry */
24 Entry = MemoryMap;
25 while (Entry->Length) Entry++;
26
27 /* Fill it out */
28 Entry->Length = Length;
29 Entry->BaseAddress = BaseAddress;
30 Entry->Type = Type;
31
32 /* Block count */
33 ArmBlock.MemoryMapEntryCount++;
34 }
35
36 VOID
37 NTAPI
LlbSetCommandLine(IN PCHAR CommandLine)38 LlbSetCommandLine(IN PCHAR CommandLine)
39 {
40 /* Copy the command line in the ARM block */
41 strcpy(ArmBlock.CommandLine, CommandLine);
42 }
43
44 VOID
45 NTAPI
LlbBuildArmBlock(VOID)46 LlbBuildArmBlock(VOID)
47 {
48 /* Write version number */
49 ArmBlock.MajorVersion = ARM_BOARD_CONFIGURATION_MAJOR_VERSION;
50 ArmBlock.MinorVersion = ARM_BOARD_CONFIGURATION_MINOR_VERSION;
51
52 /* Get arch type */
53 ArmBlock.BoardType = LlbHwGetBoardType();
54
55 /* Get peripheral clock rate */
56 ArmBlock.ClockRate = LlbHwGetPClk();
57
58 /* Get timer and serial port base addresses */
59 ArmBlock.TimerRegisterBase = LlbHwGetTmr0Base();
60 ArmBlock.UartRegisterBase = LlbHwGetUartBase(LlbHwGetSerialUart());
61
62 /* Debug */
63 DbgPrint("Machine Identifier: %lx\nPCLK: %d\nTIMER 0: %p\nSERIAL UART: %p\n",
64 ArmBlock.BoardType,
65 ArmBlock.ClockRate,
66 ArmBlock.TimerRegisterBase,
67 ArmBlock.UartRegisterBase);
68
69 /* Now load the memory map */
70 ArmBlock.MemoryMap = MemoryMap;
71
72 /* Write firmware callbacks */
73 ArmBlock.ConsPutChar = LlbFwPutChar;
74 ArmBlock.ConsKbHit = LlbFwKbHit;
75 ArmBlock.ConsGetCh = LlbFwGetCh;
76 ArmBlock.VideoClearScreen = LlbFwVideoClearScreen;
77 ArmBlock.VideoSetDisplayMode = LlbFwVideoSetDisplayMode;
78 ArmBlock.VideoGetDisplaySize = LlbFwVideoGetDisplaySize;
79 ArmBlock.VideoPutChar = LlbFwVideoPutChar;
80 ArmBlock.GetTime = LlbFwGetTime;
81 }
82
83 VOID
84 NTAPI
LlbBuildMemoryMap(VOID)85 LlbBuildMemoryMap(VOID)
86 {
87 /* Zero out the memory map */
88 memset(MemoryMap, 0, sizeof(MemoryMap));
89
90 /* Call the hardware-specific function for hardware-defined regions */
91 LlbHwBuildMemoryMap(MemoryMap);
92 }
93
94 //
95 // Should go to hwdev.c
96 //
97 POSLOADER_INIT
98 NTAPI
LlbHwLoadOsLoaderFromRam(VOID)99 LlbHwLoadOsLoaderFromRam(VOID)
100 {
101 ULONG Base, RootFs, Size;
102 PCHAR Offset;
103 CHAR CommandLine[64];
104
105 /* On versatile we load the RAMDISK with initrd */
106 LlbEnvGetRamDiskInformation(&RootFs, &Size);
107 DbgPrint("Root fs: %lx, size: %lx\n", RootFs, Size);
108
109 /* The OS Loader is at 0x20000, always */
110 Base = 0x20000;
111
112 /* Read image offset */
113 Offset = LlbEnvRead("rdoffset");
114
115 /* Set parameters for the OS loader */
116 snprintf(CommandLine,
117 sizeof(CommandLine),
118 "rdbase=0x%lx rdsize=0x%lx rdoffset=%s",
119 RootFs, Size, Offset);
120 LlbSetCommandLine(CommandLine);
121
122 /* Return the OS loader base address */
123 return (POSLOADER_INIT)Base;
124 }
125
126 VOID
127 NTAPI
LlbLoadOsLoader(VOID)128 LlbLoadOsLoader(VOID)
129 {
130 PCHAR BootDevice;
131
132 /* Read the current boot device */
133 BootDevice = LlbEnvRead("boot-device");
134 printf("Loading OS Loader from: %s...\n", BootDevice);
135 if (!strcmp(BootDevice, "NAND"))
136 {
137 // todo
138 }
139 else if (!strcmp(BootDevice, "RAMDISK"))
140 {
141 /* Call the hardware-specific function */
142 LoaderInit = LlbHwLoadOsLoaderFromRam();
143 }
144 else if (!strcmp(BootDevice, "MMC") ||
145 !strcmp(BootDevice, "SD"))
146 {
147 //todo
148 }
149 else if (!strcmp(BootDevice, "HDD"))
150 {
151 //todo
152 }
153
154 LoaderInit = (PVOID)0x80000000;
155 #ifdef _ZOOM2_ // need something better than this...
156 LoaderInit = (PVOID)0x81070000;
157 #endif
158 printf("OS Loader loaded at 0x%p...JUMP!\n\n\n\n\n", LoaderInit);
159 }
160
161 VOID
162 NTAPI
LlbBoot(VOID)163 LlbBoot(VOID)
164 {
165 /* Setup the ARM block */
166 LlbBuildArmBlock();
167
168 /* Build the memory map */
169 LlbBuildMemoryMap();
170
171 /* Load the OS loader */
172 LlbLoadOsLoader();
173
174 /* Jump to the OS Loader (FreeLDR in this case) */
175 LoaderInit(&ArmBlock);
176 }
177
178 /* EOF */
179