1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
 * PROJECT:         ReactOS Boot Loader
 * LICENSE:         BSD - See COPYING.ARM in the top level directory
 * FILE:            boot/armllb/os/loader.c
 * PURPOSE:         OS Loader Code for LLB
 * PROGRAMMERS:     ReactOS Portable Systems Group
 */

#include "precomp.h"

BIOS_MEMORY_MAP MemoryMap[32];
ARM_BOARD_CONFIGURATION_BLOCK ArmBlock;
POSLOADER_INIT LoaderInit;
    
VOID
NTAPI
LlbAllocateMemoryEntry(IN BIOS_MEMORY_TYPE Type,
                      IN ULONG BaseAddress,
                      IN ULONG Length)
{
    PBIOS_MEMORY_MAP Entry;
    
    /* Get the next memory entry */
    Entry = MemoryMap;
    while (Entry->Length) Entry++;
    
    /* Fill it out */
    Entry->Length = Length;
    Entry->BaseAddress = BaseAddress;
    Entry->Type = Type;
    
    /* Block count */
    ArmBlock.MemoryMapEntryCount++;
}

VOID
NTAPI
LlbSetCommandLine(IN PCHAR CommandLine)
{
    /* Copy the command line in the ARM block */
    strcpy(ArmBlock.CommandLine, CommandLine);
}

VOID
NTAPI
LlbBuildArmBlock(VOID)
{
    /* Write version number */
    ArmBlock.MajorVersion = ARM_BOARD_CONFIGURATION_MAJOR_VERSION;
    ArmBlock.MinorVersion = ARM_BOARD_CONFIGURATION_MINOR_VERSION;
    
    /* Get arch type */
    ArmBlock.BoardType = LlbHwGetBoardType();
    
    /* Get peripheral clock rate */
    ArmBlock.ClockRate = LlbHwGetPClk();
    
    /* Get timer and serial port base addresses */
    ArmBlock.TimerRegisterBase = LlbHwGetTmr0Base();
    ArmBlock.UartRegisterBase = LlbHwGetUartBase(LlbHwGetSerialUart());
    
    /* Debug */
    DbgPrint("Machine Identifier: %lx\nPCLK: %d\nTIMER 0: %p\nSERIAL UART: %p\n",
             ArmBlock.BoardType,
             ArmBlock.ClockRate,
             ArmBlock.TimerRegisterBase,
             ArmBlock.UartRegisterBase);
    
    /* Now load the memory map */
    ArmBlock.MemoryMap = MemoryMap;
    
    /* Write firmware callbacks */
    ArmBlock.ConsPutChar = LlbFwPutChar;
    ArmBlock.ConsKbHit = LlbFwKbHit;
    ArmBlock.ConsGetCh = LlbFwGetCh;
    ArmBlock.VideoClearScreen = LlbFwVideoClearScreen;
    ArmBlock.VideoSetDisplayMode = LlbFwVideoSetDisplayMode;
    ArmBlock.VideoGetDisplaySize = LlbFwVideoGetDisplaySize;
    ArmBlock.VideoPutChar = LlbFwVideoPutChar;
    ArmBlock.GetTime = LlbFwGetTime;
}

VOID
NTAPI
LlbBuildMemoryMap(VOID)
{
    /* Zero out the memory map */
    memset(MemoryMap, 0, sizeof(MemoryMap));

    /* Call the hardware-specific function for hardware-defined regions */
    LlbHwBuildMemoryMap(MemoryMap);
}

//
// Should go to hwdev.c
//
POSLOADER_INIT
NTAPI
LlbHwLoadOsLoaderFromRam(VOID)
{
    ULONG Base, RootFs, Size;
    PCHAR Offset;
    CHAR CommandLine[64];
    
    /* On versatile we load the RAMDISK with initrd */
    LlbEnvGetRamDiskInformation(&RootFs, &Size);
    DbgPrint("Root fs: %lx, size: %lx\n", RootFs, Size);
    
    /* The OS Loader is at 0x20000, always */
    Base = 0x20000;
    
    /* Read image offset */
    Offset = LlbEnvRead("rdoffset");
    
    /* Set parameters for the OS loader */
    snprintf(CommandLine,
             sizeof(CommandLine),
             "rdbase=0x%lx rdsize=0x%lx rdoffset=%s",
             RootFs, Size, Offset);
    LlbSetCommandLine(CommandLine);
    
    /* Return the OS loader base address */
    return (POSLOADER_INIT)Base;
}

VOID
NTAPI
LlbLoadOsLoader(VOID)
{
    PCHAR BootDevice;
    
    /* Read the current boot device */
    BootDevice = LlbEnvRead("boot-device");
    printf("Loading OS Loader from: %s...\n", BootDevice);
    if (!strcmp(BootDevice, "NAND"))
    {
        // todo
    }
    else if (!strcmp(BootDevice, "RAMDISK"))
    {
        /* Call the hardware-specific function */
        LoaderInit = LlbHwLoadOsLoaderFromRam();
    }
    else if (!strcmp(BootDevice, "MMC") ||
             !strcmp(BootDevice, "SD"))
    {
        //todo
    }
    else if (!strcmp(BootDevice, "HDD"))
    {
        //todo
    }
    
    LoaderInit = (PVOID)0x80000000;<--- LoaderInit is assigned
#ifdef _ZOOM2_ // need something better than this...
    LoaderInit = (PVOID)0x81070000;<--- LoaderInit is overwritten
#endif
    printf("OS Loader loaded at 0x%p...JUMP!\n\n\n\n\n", LoaderInit);
}

VOID
NTAPI
LlbBoot(VOID)
{
    /* Setup the ARM block */
    LlbBuildArmBlock();
    
    /* Build the memory map */
    LlbBuildMemoryMap();
    
    /* Load the OS loader */
    LlbLoadOsLoader();

    /* Jump to the OS Loader (FreeLDR in this case) */
    LoaderInit(&ArmBlock);
}

/* EOF */