;
; The VTF signature
;
; VTF-0 means that the VTF (Volume Top File) code does not require
; any fixups.
;
vtfSignature:
DB 'V', 'T', 'F', 0
ALIGN 16
resetVector:
;
; Reset Vector
;
; This is where the processor will begin execution
;
nop
nop
jmp EarlyBspInitReal16
ALIGN 16
fourGigabytes:
;
; Modified: EBX, ECX, EDX, EBP
;
; @param[in,out] RAX/EAX Initial value of the EAX register
; (BIST: Built-in Self Test)
; @param[in,out] DI 'BP': boot-strap processor, or
; 'AP': application processor
; @param[out] RBP/EBP Address of Boot Firmware Volume (BFV)
; @param[out] DS Selector allowing flat access to all addresses
; @param[out] ES Selector allowing flat access to all addresses
; @param[out] FS Selector allowing flat access to all addresses
; @param[out] GS Selector allowing flat access to all addresses
; @param[out] SS Selector allowing flat access to all addresses
;
; @return None This routine jumps to SEC and does not return
;
Main16:
OneTimeCall EarlyInit16
其中 EarlyInit16在Init16.asm 中:
;
; Modified: EAX
;
; @param[in] EAX Initial value of the EAX register (BIST: Built-in Self Test)
; @param[out] ESP Initial value of the EAX register (BIST: Built-in Self Test)
;
EarlyInit16:
;
; ESP - Initial value of the EAX register (BIST: Built-in Self Test)
;
mov esp, eax
debugInitialize //这是空的宏
OneTimeCallRet EarlyInit16
返回 EarlyInit16 后继续:
;
; Transition the processor from 16-bit real mode to 32-bit flat mode
;
OneTimeCall TransitionFromReal16To32BitFlat
;
; Search for the Boot Firmware Volume (BFV)
;
OneTimeCall Flat32SearchForBfvBase
就是说,这亏啊显卡符合 IBM VGA 规范,而这份规范年代久远,资料比较难以找到【参考3】.大概是说显卡的一些基本显示参数(例如:分辨率)是通过IO和显卡沟通的。首先是定义了几个基本的文本显示模式,处于这种文本显示的模式下,直接对下面给出来的内存写入字符和参数(比如颜色,闪烁等等)即可显示出来,这也是很早之前我们使用的DOS 的显示方式。
apping of Display Memory into CPU Address Space The first element that defines this mapping is whether or not the VGA decodes accesses from the CPU. This is controlled by the RAM Enable field. If display memory decoding is disabled, then the VGA hardware ignores writes to its address space. The address range that the VGA hardware decodes is based upon the Memory Map Select field. The following table shows the address ranges in absolute 32-bit form decoded for each value of this field:
00 — A0000h-BFFFFh — 128K
01 — A0000h-AFFFFh — 64K
10 — B0000h-B7FFFh — 32K
11 — B8000h-BFFFFh — 32K
但是,我们的 UEFI 是工作在图形模式下。因此,BIOS需要先通过IO Port (例如:3CEh和3CFh,这些都是 VGA Spec 规定好的端口号)使得显卡切换到图形模式下。例如,下面就是Cirrus CLGD 5446显卡支持的显示模式:
1.前面提到的通过IO Port 对VGA 进行初始化的操作,在 \OvmfPkg\QemuVideoDxe\Gop.c文件中:
EFI_STATUS
EFIAPI
QemuVideoGraphicsOutputSetMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber
)
/*++
Routine Description:
Graphics Output protocol interface to set video mode
Arguments:
This - Protocol instance pointer.
ModeNumber - The mode number to be set.
Returns:
EFI_SUCCESS - Graphics mode was changed.
EFI_DEVICE_ERROR - The device had an error and could not complete the request.
EFI_UNSUPPORTED - ModeNumber is not supported by this device.
--*/
EFI_STATUS
EFIAPI
QemuVideoGraphicsOutputBlt (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta
)
其中调用了 FrameBufferBlt()
switch (BltOperation) {
case EfiBltVideoToBltBuffer:
case EfiBltBufferToVideo:
case EfiBltVideoFill:
case EfiBltVideoToVideo:
Status = FrameBufferBlt (
Private->FrameBufferBltConfigure,
BltBuffer,
BltOperation,
SourceX,
SourceY,
DestinationX,
DestinationY,
Width,
Height,
Delta
);
break;
/**
Performs a UEFI Graphics Output Protocol Blt operation.
@param[in] Configure Pointer to a configuration which was successfully
created by FrameBufferBltConfigure ().
@param[in,out] BltBuffer The data to transfer to screen.
@param[in] BltOperation The operation to perform.
@param[in] SourceX The X coordinate of the source for BltOperation.
@param[in] SourceY The Y coordinate of the source for BltOperation.
@param[in] DestinationX The X coordinate of the destination for
BltOperation.
@param[in] DestinationY The Y coordinate of the destination for
BltOperation.
@param[in] Width The width of a rectangle in the blt rectangle
in pixels.
@param[in] Height The height of a rectangle in the blt rectangle
in pixels.
@param[in] Delta Not used for EfiBltVideoFill and
EfiBltVideoToVideo operation. If a Delta of 0
is used, the entire BltBuffer will be operated
on. If a subrectangle of the BltBuffer is
used, then Delta represents the number of
bytes in a row of the BltBuffer.
@retval RETURN_INVALID_PARAMETER Invalid parameter were passed in.
@retval RETURN_SUCCESS The Blt operation was performed successfully.
**/
RETURN_STATUS
EFIAPI
FrameBufferBlt (
IN FRAME_BUFFER_CONFIGURE *Configure,
IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta
)
/**
Performs a UEFI Graphics Output Protocol Blt Video Fill.
@param[in] Configure Pointer to a configuration which was successfully
created by FrameBufferBltConfigure ().
@param[in] Color Color to fill the region with.
@param[in] DestinationX X location to start fill operation.
@param[in] DestinationY Y location to start fill operation.
@param[in] Width Width (in pixels) to fill.
@param[in] Height Height to fill.
@retval RETURN_INVALID_PARAMETER Invalid parameter was passed in.
@retval RETURN_SUCCESS The video was filled successfully.
**/
EFI_STATUS
FrameBufferBltLibVideoFill (
IN FRAME_BUFFER_CONFIGURE *Configure,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height
)
{}
#if CONFIG_IDF_TARGET_ESP32C3
#define FSPI 0
#define HSPI 1
#else
#define FSPI 1 //SPI bus attached to the flash (can use the same data lines but different SS)
#define HSPI 2 //SPI bus normally mapped to pins 12 - 15, but can be matrixed to any pins
#if CONFIG_IDF_TARGET_ESP32
#define VSPI 3 //SPI bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
#endif
#endif
#include <SPI.h>
static const int spiClk = 40000000;
SPIClass * hspi = NULL;
void setup() {
Serial.begin(115200);
//initialise two instances of the SPIClass attached to VSPI and HSPI respectively
hspi = new SPIClass(HSPI);
//initialise hspi with default pins
//SCLK = 14, MISO = 12, MOSI = 13, SS = 15
hspi->begin(10,12,11,13);
//set up slave select pins as outputs as the Arduino API
//doesn't handle automatically pulling SS low
pinMode(hspi->pinSS(), OUTPUT); //HSPI SS
}
// the loop function runs over and over again until power down or reset
void loop() {
spiCommand(hspi, 0b11001100);
Serial.print(MISO);Serial.print(" ");
Serial.print(MOSI);Serial.print(" ");
Serial.print(SCK);Serial.print(" ");
Serial.print(SS);Serial.print(" ");
Serial.print(HSPI);Serial.print(" ");
Serial.print(FSPI);Serial.print(" ");
Serial.print(hspi->pinSS());Serial.println(" ");
delay(2000);
}
void spiCommand(SPIClass *spi, byte data) {
//use it as you would the regular arduino SPI API
spi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(spi->pinSS(), LOW); //pull SS slow to prep other end for transfer
spi->transfer(data);
digitalWrite(spi->pinSS(), HIGH); //pull ss high to signify end of data transfer
spi->endTransaction();
}
#include <SPI.h>
static const int spiClk = 40000000;
void setup() {
Serial.begin(115200);
SPI.begin();
}
void loop() {
spiCommand(&SPI, 0b11001100);
Serial.print(MISO);Serial.print(" ");
Serial.print(MOSI);Serial.print(" ");
Serial.print(SCK);Serial.print(" ");
Serial.print(SS);Serial.print(" ");
Serial.print(HSPI);Serial.print(" ");
Serial.print(FSPI);Serial.println(" ");
delay(200);
}
void spiCommand(SPIClass *spi, byte data) {
//use it as you would the regular arduino SPI API
spi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(spi->pinSS(), LOW); //pull SS slow to prep other end for transfer
spi->transfer(data);
digitalWrite(spi->pinSS(), HIGH); //pull ss high to signify end of data transfer
spi->endTransaction();
}
@echo off
setlocal
rem The format of %TIME% is HH:MM:SS,CS for example 23:59:59,99
set STARTTIME=%TIME%
rem 这里开始
rem 你要计算的部分
rem 这里结束
set ENDTIME=%TIME%
rem output as time
echo STARTTIME: %STARTTIME%
echo ENDTIME: %ENDTIME%
rem convert STARTTIME and ENDTIME to centiseconds
set /A STARTTIME=(1%STARTTIME:~0,2%-100)*360000 + (1%STARTTIME:~3,2%-100)*6000 + (1%STARTTIME:~6,2%-100)*100 + (1%STARTTIME:~9,2%-100)
set /A ENDTIME=(1%ENDTIME:~0,2%-100)*360000 + (1%ENDTIME:~3,2%-100)*6000 + (1%ENDTIME:~6,2%-100)*100 + (1%ENDTIME:~9,2%-100)
rem calculating the duratyion is easy
set /A DURATION=%ENDTIME%-%STARTTIME%
rem we might have measured the time inbetween days
if %ENDTIME% LSS %STARTTIME% set set /A DURATION=%STARTTIME%-%ENDTIME%
rem now break the centiseconds down to hors, minutes, seconds and the remaining centiseconds
set /A DURATIONH=%DURATION% / 360000
set /A DURATIONM=(%DURATION% - %DURATIONH%*360000) / 6000
set /A DURATIONS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000) / 100
set /A DURATIONHS=(%DURATION% - %DURATIONH%*360000 - %DURATIONM%*6000 - %DURATIONS%*100)
rem some formatting
if %DURATIONH% LSS 10 set DURATIONH=0%DURATIONH%
if %DURATIONM% LSS 10 set DURATIONM=0%DURATIONM%
if %DURATIONS% LSS 10 set DURATIONS=0%DURATIONS%
if %DURATIONHS% LSS 10 set DURATIONHS=0%DURATIONHS%
rem outputing
echo STARTTIME: %STARTTIME% centiseconds
echo ENDTIME: %ENDTIME% centiseconds
echo DURATION: %DURATION% in centiseconds
echo %DURATIONH%:%DURATIONM%:%DURATIONS%,%DURATIONHS%
endlocal
goto :EOF