freeldr.c
代码位置: D:/ReactOS/ReactOS_src/boot/freeldr/freeldr/freeldr.c
终于终于看到C语言了,汇编看者就是不爽,先介绍下这个文件,这个文件内的代码很少,基本上是命令参数,文件系统、调试、UI、内存的初始化,最后进行系统的加载。
看代码:
#include <freeldr.h>
#include <debug.h>
VOID BootMain(LPSTR CmdLine)
{
/* 命令行分析,经调试命令行的为NULL,所以分析这个函数就没意思了这里略过*/
CmdLineParse(CmdLine);
/*这里我们得看下,见下文*/
MachInit(CmdLine);
/*这里是文件系统的初始化*/
FsInit();
/*调试初始化,是用串口通信*/
DebugInit();
DbgPrintMask( DPRINT_WARNING,"CmdLine:%s/n",CmdLine );
DPRINTM(DPRINT_WARNING,"BootMain() called./n");
/*初始化UI*/
if (!UiInitialize(FALSE))
{
UiMessageBoxCritical("Unable to initialize UI./n");
return;
}
/*初始化内存管理*/
if (!MmInitializeMemoryManager())
{
UiMessageBoxCritical("Unable to initialize memory manager");
return;
}
/*开始加载系统*/
RunLoader();
}
首先是MachInit().
archmach.c
代码位置: d:/ReactOS/ReactOS_src/boot/freeldr/freeldr/arch/i386/archmach.c
VOID
MachInit(const char *CmdLine)
{
ULONG PciId;
memset(&MachVtbl,sizeof(MACHVTBL));
/* Check for XBox by identifying device at PCI 0:0:0,if it's
* 0x10de/0x02a5 then we're running on an XBox */
WRITE_PORT_ULONG((ULONG*) 0xcf8,CONFIG_CMD(0,0));
PciId = READ_PORT_ULONG((ULONG*) 0xcfc);
if (0x02a510de == PciId)
{
XBoxMachInit(CmdLine);
}
else
{
PcMachInit (CmdLine);
}
HalpCalibrateStallExecution();
}
代码也不多,这里说下结构体MachVtbl,这个结构体看下定义
int (*ConsGetCh)(VOID);
VOID (*VideoClearScreen)(UCHAR Attr);
VIDEODISPLAYMODE (*VideoSetDisplayMode)(char *DisplayMode,BOOLEAN Init);
VOID (*VideoGetDisplaySize)(PULONG Width,PULONG Height,PULONG Depth);
ULONG (*VideoGetBufferSize)(VOID);
VOID (*VideoSetTextCursorPosition)(ULONG X,ULONG Y);
VOID (*VideoHideShowTextCursor)(BOOLEAN Show);
VOID (*VideoPutChar)(int Ch,UCHAR Attr,unsigned X,unsigned Y);
VOID (*VideoCopyOffScreenBufferToVRAM)(PVOID Buffer);
BOOLEAN (*VideoIsPaletteFixed)(VOID);
VOID (*VideoSetPaletteColor)(UCHAR Color,UCHAR Red,UCHAR Green,UCHAR Blue);
VOID (*VideoGetPaletteColor)(UCHAR Color,UCHAR* Red,UCHAR* Green,UCHAR* Blue);
VOID (*VideoSync)(VOID);
VOID (*Beep)(VOID);
VOID (*PrepareForReactOS)(IN BOOLEAN Setup);
MEMORY_DESCRIPTOR* (*GetMemoryDescriptor)(MEMORY_DESCRIPTOR* Current);
ULONG (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap,ULONG MaxMemoryMapSize);
BOOLEAN (*DiskGetBootVolume)(PULONG DriveNumber,PULONGLONG StartSector,PULONGLONG SectorCount,int *FsType);
BOOLEAN (*DiskGetSystemVolume)(char *SystemPath,char *RemainingPath,PULONG Device,PULONG DriveNumber,int *FsType);
BOOLEAN (*DiskGetBootPath)(char *BootPath,unsigned Size);
VOID (*DiskGetBootDevice)(PULONG BootDevice);
BOOLEAN (*DiskBootingFromFloppy)(VOID);
BOOLEAN (*DiskNormalizeSystemPath)(char *SystemPath,unsigned Size);
BOOLEAN (*DiskReadLogicalSectors)(ULONG DriveNumber,ULONGLONG SectorNumber,ULONG SectorCount,PVOID Buffer);
BOOLEAN (*DiskGetPartitionEntry)(ULONG DriveNumber,ULONG PartitionNumber,PPARTITION_TABLE_ENTRY PartitionTableEntry);
BOOLEAN (*DiskGetDriveGeometry)(ULONG DriveNumber,PGEOMETRY DriveGeometry);
ULONG (*DiskGetCacheableBlockCount)(ULONG DriveNumber);
TIMEINFO* (*GetTime)(VOID);
ULONG (*GetRelativeTime)(VOID);
PCONFIGURATION_COMPONENT_DATA (*HwDetect)(VOID);
} MACHVTBL,*PMACHVTBL;
看到了没都是些函数的定义,为什么要这么定义呢?是问了可以增加程序的可移植性,为不同的硬件编写不同函数最后把指针赋予这个结构体就OK了。
接下来就是检查是否运行在XBox虚拟机下,本人没用过,不多说,这里我们也学习到了怎样检测系统是否运行在XBox下。我是在Vmware下运行的所以在我机子上会调用PcMachInit()函数.
这个函数下面说,最后是调用HalpCalibrateStallExecution()函数,现在还不知道是干什么的?
一个一个接着来
(下面要开启函数介绍的模式啦)
machpc.c
代码位置: d:/ReactOS/ReactOS_src/boot/freeldr/freeldr/arch/i386/machpc.c
来看函数PcMachInit();
代码如下:
VOID
PcMachInit(const char *CmdLine)
{
EnableA20();
/* Setup vtbl */
MachVtbl.ConsPutChar = PcConsPutChar;
MachVtbl.ConsKbHit = PcConsKbHit;
MachVtbl.ConsGetCh = PcConsGetCh;
MachVtbl.VideoClearScreen = PcVideoClearScreen;
MachVtbl.VideoSetDisplayMode = PcVideoSetDisplayMode;
MachVtbl.VideoGetDisplaySize = PcVideoGetDisplaySize;
MachVtbl.VideoGetBufferSize = PcVideoGetBufferSize;
MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
MachVtbl.VideoSetTextCursorPosition = PcVideoSetTextCursorPosition;
MachVtbl.VideoHideShowTextCursor = PcVideoHideShowTextCursor;
MachVtbl.VideoPutChar = PcVideoPutChar;
MachVtbl.VideoCopyOffScreenBufferToVRAM = PcVideoCopyOffScreenBufferToVRAM;
MachVtbl.VideoIsPaletteFixed = PcVideoIsPaletteFixed;
MachVtbl.VideoSetPaletteColor = PcVideoSetPaletteColor;
MachVtbl.VideoGetPaletteColor = PcVideoGetPaletteColor;
MachVtbl.VideoSync = PcVideoSync;
MachVtbl.Beep = PcBeep;
MachVtbl.PrepareForReactOS = PcPrepareForReactOS;
MachVtbl.GetMemoryMap = PcMemGetMemoryMap;
MachVtbl.DiskGetBootVolume = DiskGetBootVolume;
MachVtbl.DiskGetSystemVolume = DiskGetSystemVolume;
MachVtbl.DiskGetBootPath = DiskGetBootPath;
MachVtbl.DiskGetBootDevice = DiskGetBootDevice;
MachVtbl.DiskBootingFromFloppy = DiskBootingFromFloppy;
MachVtbl.DiskNormalizeSystemPath = DiskNormalizeSystemPath;
MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors;
MachVtbl.DiskGetPartitionEntry = DiskGetPartitionEntry;
MachVtbl.DiskGetDriveGeometry = PcDiskGetDriveGeometry;
MachVtbl.DiskGetCacheableBlockCount = PcDiskGetCacheableBlockCount;
MachVtbl.GetTime = PcGetTime;
MachVtbl.HwDetect = PcHwDetect;
}
都是指针呀,现在开启函数介绍模式.一个一个的看,从第一个开始
MachVtbl 函数之 PcConsPutChar()
代码位置: d:/ReactOS/ReactOS_src/boot/freeldr/freeldr/arch/i386/pccons.c
函数参数 int Ch
函数返回值: NULL
Int 10h AH=0Eh
MachVtbl 函数之PcConsKbHit
代码位置: d:/ReactOS/ReactOS_src/boot/freeldr/freeldr/arch/i386/pccons.c
函数参数:NULL
函数返回值:BOOL
函数说明: CHECK FOR KEYSTROKE 类似于C语言函数getch()主要调用int 16h 实现
Int 16h AH=01h
MachVtbl 函数之PcConsGetCh
代码位置: d:/ReactOS/ReactOS_src/boot/freeldr/freeldr/arch/i386/pccons.c
函数参数:NULL
函数返回值:int 获得的按键值
函数说明:类似C语言函数的getchar();主要用int 16h实现
Int 16h AH=00h
MachVtbl 函数之PcVideoClearScreen
代码位置: d:/ReactOS/ReactOS_src/boot/freeldr/freeldr/arch/i386/pcvideo.c
函数参数: UCHAR Attr
函数返回值:NULL
代码如下:
VOID
PcVideoClearScreen(UCHAR Attr)
{
USHORT AttrChar;
USHORT *BufPtr;
/* VIDEOTEXT_MEM_ADDRESS 0xB8000*/
AttrChar = ((USHORT) Attr << 8) | ' ';
/*填充显存*/
for (BufPtr = (USHORT *) VIDEOTEXT_MEM_ADDRESS;
BufPtr < (USHORT *) (VIDEOTEXT_MEM_ADDRESS + VIDEOTEXT_MEM_SIZE);
BufPtr++)
{
*BufPtr = AttrChar;
}
}