- Create a slab that contains the last vestage of our life as the boot program.

- Include a font containing some characters we can use with boot video.
- Copy in a description of the boot framebuffer.
- Add a small ad-hoc number writing function.
- Display our progress building the initial page table.
- We don't necessarily have space in the boot-time page table so just kill
  off boot-time paging.
- Pass ntoskrnl the address of the boot slab.  It contains the boot font, a
  description of the boot video device and all active page table entries.
- Next, well be able to use this in early ntoskrnl space to display our 
  progress etc.  Since we're using phyiscal addresses to write to the boot
  framebuffer, the page table needn't include it.  This simplifies things
  compared to linux, but it's expensive.

svn path=/branches/powerpc/; revision=24390
This commit is contained in:
Art Yerkes
2006-10-04 08:10:01 +00:00
parent 532db1da72
commit 47e3cefe5b
7 changed files with 218 additions and 22 deletions
@@ -1,3 +1,8 @@
.extern PpcInit
_start:
b PpcInit
.globl _bss
.section ".bss"
_bss:
.long 0
@@ -103,6 +103,107 @@ void btext_drawhex(unsigned long v);
void *ioremap(__u32 phys, __u32 size);
void iounmap(void *logical);
font_char BootDigits[16] = {
" XXXXX "
"X X "
"X x X "
"X X X "
"X X "
" XXXXX "
" ",
" XX "
" XXX "
" XX "
" XX "
" XX "
" XX "
" ",
" XXXX "
" X X "
" XX "
" XX "
" XX "
" XXXXXX "
" ",
" XXXX "
" X X "
" XX "
" X "
" X X "
" XXXX "
" ",
" X X "
" X X "
" XXXXXX "
" X "
" X "
" X "
" ",
" XXXXXX "
" X "
" XXXXX "
" X "
" X "
" XXXXX "
" ",
" XXXXX "
" X "
" XXXXX "
" X X "
" X X "
" XXXX "
" ",
" XXXXXX "
" XX "
" XX "
" XXXXX "
" XX "
" XX "
" ",
" XXXX "
" X X "
" XXXX "
" X X "
" X X "
" XXXX "
" ",
" XXXX "
" X X "
" XXXXXX "
" X X "
" X X "
" X X "
" ",
" XXXXX "
" X X "
" XXXXX "
" X X "
" X X "
" XXXXX "
" ",
" XXXX "
" X X "
" X "
" X "
" X X "
" XXXX "
" ",
" XXXXXX "
" X "
" XXXX "
" X "
" X "
" XXXXXX "
" ",
" XXXXXX "
" X "
" XXXX "
" X "
" X "
" X "
" "
};
__u32 GetPVR();
#endif/*_FREELDR_ARCH_COMPAT_H*/
@@ -28,7 +28,7 @@ extern PCHAR GetFreeLoaderVersionString();
extern ULONG CacheSizeLimit;
of_proxy ofproxy;
void *PageDirectoryStart, *PageDirectoryEnd;
static int chosen_package, stdin_handle, part_handle = -1;
static int chosen_package, stdin_handle, part_handle = -1, kernel_mem = 0;
BOOLEAN AcpiPresent = FALSE;
char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 };
jmp_buf jmp;
@@ -340,10 +340,20 @@ ULONG PpcGetMemoryMap( PBIOS_MEMORY_MAP BiosMemoryMap,
(int)BiosMemoryMap[slots].BaseAddress,
(int)BiosMemoryMap[slots].Length);
if( BiosMemoryMap[slots].Length &&
/* Hack for pearpc */
if( kernel_mem ) {
BiosMemoryMap[slots].Length = kernel_mem * 1024;
ofw_claim((int)BiosMemoryMap[slots].BaseAddress,
(int)BiosMemoryMap[slots].Length,
0x1000) ) {
0x1000);
total += BiosMemoryMap[slots].Length;
slots++;
break;
/* Normal way */
} else if( BiosMemoryMap[slots].Length &&
ofw_claim((int)BiosMemoryMap[slots].BaseAddress,
(int)BiosMemoryMap[slots].Length,
0x1000) ) {
total += BiosMemoryMap[slots].Length;
slots++;
}
@@ -555,11 +565,11 @@ void PpcInit( of_proxy the_ofproxy ) {
len = ofw_getprop(chosen_package, "bootargs",
CmdLine, sizeof(CmdLine));
printf("bootargs: len %d\n", len);
if( len < 0 ) len = 0;
CmdLine[len] = 0;
printf("bootargs: len %d [%s]\n", len, CmdLine);
BootMain( CmdLine );
}
@@ -572,15 +582,19 @@ void MachInit(const char *CmdLine) {
printf( "Determining boot device: [%s]\n", CmdLine );
printf( "Boot Args: %s\n", CmdLine );
sep = NULL;
for( i = 0; i < strlen(CmdLine); i++ ) {
if( strncmp(CmdLine + i, "boot=", 5) == 0) {
strcpy(BootPart, CmdLine + i + 5);
sep = strchr(BootPart, ' ');
sep = strchr(BootPart, ',');
if( sep )
*sep = 0;
break;
while(CmdLine[i] && CmdLine[i]!=',') i++;
}
if( strncmp(CmdLine + i, "mem=", 4) == 0) {
kernel_mem = atoi(CmdLine+i+4);
printf("Allocate %dk kernel memory\n", kernel_mem);
while(CmdLine[i] && CmdLine[i]!=',') i++;
}
}
@@ -20,12 +20,15 @@
#include <freeldr.h>
#include <of_call.h>
#include "ppcboot.h"
#include "mmu.h"
#include "compat.h"
#define NDEBUG
#include <debug.h>
static PVOID KernelMemory = 0;
extern boot_infos_t BootInfo;
/* Bits to shift to convert a Virtual Address into an Offset in the Page Table */
#define PFN_SHIFT 12
@@ -107,26 +110,97 @@ ULONG_PTR KernelEntry;
typedef void (*KernelEntryFn)( void * );
VOID
DrawDigit(boot_infos_t *BootInfo, ULONG Digit, int x, int y)
{
int i,j,k;
for( i = 0; i < 7; i++ ) {
for( j = 0; j < 8; j++ ) {
for( k = 0; k < BootInfo->dispDeviceDepth/8; k++ ) {
SetPhysByte(((ULONG_PTR)BootInfo->dispDeviceBase)+
k +
(((j+x) * (BootInfo->dispDeviceDepth/8)) +
((i+y) * (BootInfo->dispDeviceRowBytes))),
BootInfo->dispFont[Digit][i*8+j] == ' ' ? 0 : 255);
}
}
}
}
VOID
DrawNumber(boot_infos_t *BootInfo, ULONG Number, int x, int y)
{
int i;
for( i = 0; i < 8; i++, Number<<=4 ) {
DrawDigit(BootInfo,(Number>>28)&0xf,x+(i*8),y);
}
}
VOID
NTAPI
FrLdrStartup(ULONG Magic)
{
KernelEntryFn KernelEntryAddress =
(KernelEntryFn)(KernelEntry + KernelBase);
ULONG_PTR PhysAddr, i;
for( i = 0; i < KernelMemorySize; i+=1<<PFN_SHIFT )
register ULONG_PTR i asm("r4"), j asm("r5");
UINT NeededPTE = ((UINT)KernelMemory) >> PFN_SHIFT;
UINT NeededMemory =
(2 * sizeof(ULONG_PTR) * (NeededPTE + NeededPTE / 512)) +
sizeof(BootInfo) + sizeof(BootDigits);
UINT NeededPages = ROUND_UP(NeededMemory,(1<<PFN_SHIFT));
register PULONG_PTR TranslationMap asm("r6") =
MmAllocateMemory(NeededMemory);
boot_infos_t *LocalBootInfo = (boot_infos_t *)TranslationMap;
TranslationMap = (PULONG_PTR)
(((PCHAR)&LocalBootInfo[1]) + sizeof(BootDigits));
memcpy(&LocalBootInfo[1], BootDigits, sizeof(BootDigits));
*LocalBootInfo = BootInfo;
LocalBootInfo->dispFont = (font_char *)&LocalBootInfo[1];
TranslationMap[0] = (ULONG_PTR)FrLdrStartup;
for( i = 1; i < NeededPages; i++ )
{
PhysAddr = PpcVirt2phys((ULONG)KernelMemory + i,0);
if( !InsertPageEntry(KernelBase + i,PhysAddr) )
{
printf("Foo: couldn't find a page slot for %x\n", i);
while(1);
}
TranslationMap[i*2] = NeededMemory+(i<<PFN_SHIFT);
}
KernelEntryAddress( (void*)Magic );
for( j = 0; j < KernelMemorySize>>PFN_SHIFT; j++ )
{
TranslationMap[(i+j)*2] = ((UINT)(KernelMemory+(i<<PFN_SHIFT)));
}
for( i = 0; i < j; i++ )
{
TranslationMap[(i*2)+1] = PpcVirt2phys(TranslationMap[i*2],0);
}
printf("Built map of %d pages\n", j);
/*
* Stuff page table entries for the page containing this code,
* The pages containing the page table entries, and finally the kernel
* pages.
*
* When done, we'll be able to flop over to kernel land!
*/
for( i = 0; i < j; i++ )
{
DrawNumber(LocalBootInfo,i,10,90);
DrawNumber(LocalBootInfo,TranslationMap[i*2],10,100);
DrawNumber(LocalBootInfo,TranslationMap[i*2+1],10,110);
InsertPageEntry
(TranslationMap[i*2],
TranslationMap[(i*2)+1],
(i>>10));
}
/* Tell them we're booting */
DrawNumber(LocalBootInfo,0x1cabba9e,10,120);
DrawNumber(LocalBootInfo,(ULONG)KernelEntryAddress,100,120);
KernelEntryAddress( (void*)LocalBootInfo );
while(1);
}
@@ -293,7 +293,7 @@ int PpcVirt2phys( int virt, int inst ) {
}
/* Add a new page table entry for the indicated mapping */
BOOLEAN InsertPageEntry( int virt, int phys ) {
BOOLEAN InsertPageEntry( int virt, int phys, int slot ) {
int i, ptehi, ptelo;
int sdr1 = GetSDR1();
int sr = GetSR( (virt >> 28) & 0xf );
@@ -307,7 +307,7 @@ BOOLEAN InsertPageEntry( int virt, int phys ) {
for( i = 0; i < 8; i++ ) {
ptehi = GetPhys( ptegaddr + (i * 8) );
if( ptehi & 0x80000000 ) continue;
if( (slot != i) && (ptehi & 0x80000000) ) continue;
ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f);
ptelo = phys & ~0xfff;
@@ -14,6 +14,6 @@ int BatHit( int bath, int batl, int virt );
int BatTranslate( int bath, int batl, int virt );
/* translate address */
int PpcVirt2phys( int virt, int inst );
BOOLEAN InsertPageEntry( int virt, int phys );
BOOLEAN InsertPageEntry( int virt, int phys, int slot );
#endif/*FREELDR_MMU_H*/
+2
View File
@@ -1,11 +1,13 @@
#ifndef REACTOS_PPCBOOT_H
#define REACTOS_PPCBOOT_H
typedef char font_char[57];
typedef struct _boot_infos_t {
int dispDeviceRect[4];
int dispDeviceRowBytes;
int dispDeviceDepth;
void *dispDeviceBase;
font_char *dispFont;
} boot_infos_t;
#endif/*REACTOS_PPCBOOT_H*/