Major overhaul of this branch.
This branch has been dedicated to purely the UEFI bootloader. As such, all other code has been removed. This code can be compiled with Visual Studio, gcc or llvm.
This commit is contained in:
parent
352db828e7
commit
d588e232c4
|
@ -1,10 +0,0 @@
|
|||
---
|
||||
DerivePointerAlignment: 'true'
|
||||
SpaceBeforeParens: ControlStatements
|
||||
UseTab: ForIndentation
|
||||
IndentWidth: 2
|
||||
TabWidth: 2
|
||||
ColumnLimit: 120
|
||||
BreakBeforeBraces: Attach
|
||||
|
||||
...
|
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.sh eol=lf
|
||||
Makefile eol=lf
|
71
.gitignore
vendored
71
.gitignore
vendored
|
@ -1,59 +1,14 @@
|
|||
|
||||
# Created by https://www.gitignore.io/api/c
|
||||
# Edit at https://www.gitignore.io/?templates=c
|
||||
|
||||
### C ###
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# End of https://www.gitignore.io/api/c
|
||||
*.efi
|
||||
*.vhd
|
||||
*.sdf
|
||||
*.suo
|
||||
*.opensdf
|
||||
*.opendb
|
||||
*.fd
|
||||
*.db*
|
||||
arm
|
||||
aa64
|
||||
x86_64
|
||||
x86_32
|
||||
image
|
||||
|
|
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
[submodule "gnu-efi"]
|
||||
path = gnu-efi
|
||||
url = git://git.code.sf.net/p/gnu-efi/code
|
||||
ignore = dirty
|
3
.vs/ProjectSettings.json
Normal file
3
.vs/ProjectSettings.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"CurrentProjectSetting": "No Configurations"
|
||||
}
|
9
.vs/VSWorkspaceState.json
Normal file
9
.vs/VSWorkspaceState.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ExpandedNodes": [
|
||||
"",
|
||||
"\\arch",
|
||||
"\\arch\\uefi"
|
||||
],
|
||||
"SelectedNode": "\\.gitignore",
|
||||
"PreviewInSolutionExplorer": false
|
||||
}
|
BIN
.vs/red/v15/ipch/AutoPCH/1f7ce03d182abcf7/SYS_CLOCK.ipch
Normal file
BIN
.vs/red/v15/ipch/AutoPCH/1f7ce03d182abcf7/SYS_CLOCK.ipch
Normal file
Binary file not shown.
BIN
.vs/red/v15/ipch/AutoPCH/349d759258598ef9/ENTRY.ipch
Normal file
BIN
.vs/red/v15/ipch/AutoPCH/349d759258598ef9/ENTRY.ipch
Normal file
Binary file not shown.
BIN
.vs/red/v15/ipch/AutoPCH/434b3cd0330f060/TTY.ipch
Normal file
BIN
.vs/red/v15/ipch/AutoPCH/434b3cd0330f060/TTY.ipch
Normal file
Binary file not shown.
BIN
.vs/red/v15/ipch/AutoPCH/89012f5cd6e4fc25/ENTRY.ipch
Normal file
BIN
.vs/red/v15/ipch/AutoPCH/89012f5cd6e4fc25/ENTRY.ipch
Normal file
Binary file not shown.
BIN
.vs/slnx.sqlite
Normal file
BIN
.vs/slnx.sqlite
Normal file
Binary file not shown.
11
README.md
11
README.md
|
@ -1,9 +1,6 @@
|
|||
# Sync
|
||||
##Sync UEFI Bootloader
|
||||
|
||||
Sync, an experimental synchronising OS.
|
||||
This branch represents the UEFI bootloader used by Sync.
|
||||
It tries to set a nice video mode, then gets the date and time, then finds, packs and loads the kernel, giving the information gathered to it.
|
||||
|
||||
Currently features:
|
||||
* Text mode printing with CSI support
|
||||
* literally nothing else
|
||||
|
||||
Keep posted. Development is relatively active.
|
||||
A .sln project is provided for convenience. The Windows SDK is required to compile using it, but it also works with gcc and llvm.
|
|
@ -1,28 +0,0 @@
|
|||
[BITS 32] ;... somehow.
|
||||
|
||||
|
||||
[GLOBAL load_gdt]
|
||||
[EXTERN gp]
|
||||
load_gdt:
|
||||
lgdt [gp]
|
||||
|
||||
mov ax, 0x10
|
||||
mov ds, ax
|
||||
mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
mov ss, ax
|
||||
jmp 0x08:flush ; Far jump and load the new CSD into the processor
|
||||
flush:
|
||||
ret
|
||||
|
||||
[GLOBAL load_idt]
|
||||
[EXTERN idtp]
|
||||
load_idt:
|
||||
lidt [idtp]
|
||||
ret
|
||||
|
||||
|
||||
SECTION .bss
|
||||
resb 8192
|
||||
_sys_stack:
|
|
@ -1,52 +0,0 @@
|
|||
/************************
|
||||
*** Team Kitty, 2019 ***
|
||||
*** Sync ***
|
||||
***********************/
|
||||
|
||||
/* The entry point of the UEFI app.
|
||||
* When the firmware loads the app,
|
||||
* it calls the efi_main function.
|
||||
*
|
||||
* When it is called, the processor
|
||||
* is running in 32-bit Protected mode.
|
||||
* It is given a map of memory, and there
|
||||
* are a bunch of Boot Services provided
|
||||
* by the UEFI firmware.
|
||||
*
|
||||
* See uefi/docs for more information.
|
||||
*/
|
||||
|
||||
//Example stolen from osdev.org/uefi_bare_bones
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_INPUT_KEY Key;
|
||||
|
||||
/* Store the system table for future use in other functions */
|
||||
ST = SystemTable;
|
||||
|
||||
/* Say hi */
|
||||
Status = ST->ConOut->OutputString(ST->ConOut, L"Hello World\n\r");
|
||||
if (EFI_ERROR(Status))
|
||||
return Status;
|
||||
|
||||
/* Now wait for a keystroke before continuing, otherwise your
|
||||
message will flash off the screen before you see it.
|
||||
|
||||
First, we need to empty the console input buffer to flush
|
||||
out any keystrokes entered before this point */
|
||||
Status = ST->ConIn->Reset(ST->ConIn, FALSE);
|
||||
if (EFI_ERROR(Status))
|
||||
return Status;
|
||||
|
||||
/* Now wait until a key becomes available. This is a simple
|
||||
polling implementation. You could try and use the WaitForKey
|
||||
event instead if you like */
|
||||
while ((Status = ST->ConIn->ReadKeyStroke(ST->ConIn, &Key)) == EFI_NOT_READY) ;
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
OUTPUT_FORMAT("elf32-i386")
|
||||
ENTRY(start)
|
||||
phys = 0x00100000;
|
||||
SECTIONS
|
||||
{
|
||||
.text phys : AT(phys) {
|
||||
code = .;
|
||||
*(.text)
|
||||
*(.rodata)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
.data : AT(phys + (data - code))
|
||||
{
|
||||
data = .;
|
||||
*(.data)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
.bss : AT(phys + (bss - code))
|
||||
{
|
||||
bss = .;
|
||||
*(.bss)
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
end = .;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
KERNEL_ARCH_CFLAGS=
|
||||
KERNEL_ARCH_CPPFLAGS=
|
||||
KERNEL_ARCH_LDFLAGS=
|
||||
KERNEL_ARCH_LIBS=
|
||||
|
||||
KERNEL_ARCH_OBJS= \
|
||||
$(ARCHDIR)/boot.o \
|
||||
$(ARCHDIR)/sys_clock.o \
|
||||
$(ARCHDIR)/tty.o
|
|
@ -1,35 +0,0 @@
|
|||
/************************
|
||||
*** Team Kitty, 2019 ***
|
||||
*** Sync ***
|
||||
***********************/
|
||||
|
||||
/* This file provides an interface to
|
||||
* the hardware timer / RTC. Not much
|
||||
* more to be said about it. */
|
||||
|
||||
#include <kernel/utils.h>
|
||||
#include <kernel.h>
|
||||
#include <kernel/serial.h>
|
||||
#include <kernel/descriptor_tables.h>
|
||||
|
||||
size_t timer_ticks = 0;
|
||||
size_t flag = 0;
|
||||
void timer_handler(struct int_frame* r) {
|
||||
gdb_end();
|
||||
timer_ticks++;
|
||||
|
||||
if(timer_ticks % 18 == 0) {
|
||||
if(++flag % 2 == 0) {
|
||||
serial_print(0x3F8, "Tick.");
|
||||
} else {
|
||||
serial_print(0x3F8, "Tock.");
|
||||
}
|
||||
}
|
||||
|
||||
if(timer_ticks > 18)
|
||||
timer_ticks = 0;
|
||||
}
|
||||
|
||||
void timer_install() {
|
||||
irq_install_handler(0, &timer_handler);
|
||||
}
|
348
arch/uefi/tty.c
348
arch/uefi/tty.c
|
@ -1,348 +0,0 @@
|
|||
/************************
|
||||
*** Team Kitty, 2019 ***
|
||||
*** Sync ***
|
||||
***********************/
|
||||
|
||||
/* This file provides all of the functionality
|
||||
* needed to interact with the Text-Mode VGA
|
||||
* buffer, which will soon be defunct due to
|
||||
* EFI and graphics.
|
||||
*
|
||||
* This file will be left for the forseeable
|
||||
* future, because it allows for easy debugging.
|
||||
* 17/07/19 Curle
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
//#include <string.h>
|
||||
|
||||
#include "kernel/tty.h"
|
||||
#include "kernel/utils.h"
|
||||
|
||||
static const size_t TERM_WIDTH = 80;
|
||||
static const size_t TERM_HEIGHT = 25;
|
||||
|
||||
static size_t terminal_row;
|
||||
static size_t terminal_column;
|
||||
|
||||
static uint8_t current_color;
|
||||
static uint16_t* term_buffer;
|
||||
volatile uint16_t* vga_buffer = (uint16_t*)0xB8000;
|
||||
|
||||
void screen_initialize(void) {
|
||||
|
||||
terminal_row = 0;
|
||||
terminal_column = 0;
|
||||
current_color = vga_color_set(LIGHT_GREY, BLACK);
|
||||
term_buffer = vga_buffer;
|
||||
|
||||
for (size_t y = 0; y < TERM_HEIGHT; y++) {
|
||||
for (size_t x = 0; x < TERM_WIDTH; x++) {
|
||||
const size_t offset = y * TERM_WIDTH + x;
|
||||
term_buffer[offset] = vga_entry(' ', current_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void term_setcolor(enum vga_colors color) { current_color = color; }
|
||||
|
||||
void term_putentryat(char c, uint8_t color, size_t x, size_t y) {
|
||||
const size_t offset = y * TERM_WIDTH + x;
|
||||
term_buffer[offset] = vga_entry(c, color);
|
||||
}
|
||||
|
||||
void term_putchar(char c) {
|
||||
unsigned char uc = c;
|
||||
|
||||
// Handle escaped characters, such as newline, and crtn.
|
||||
switch (uc) {
|
||||
case '\n':
|
||||
terminal_column = 0;
|
||||
terminal_row += 1;
|
||||
break;
|
||||
default:
|
||||
term_putentryat(uc, current_color, terminal_column, terminal_row);
|
||||
if (++terminal_column == TERM_WIDTH) {
|
||||
terminal_column = 0;
|
||||
if (++terminal_row == TERM_HEIGHT) {
|
||||
term_scroll(false);
|
||||
terminal_row = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct csi_sequence parse_csi(const char* data, size_t size) {
|
||||
enum State { PARAMETER, INTERMEDIATE, FINAL, INVALID };
|
||||
enum State state = PARAMETER;
|
||||
|
||||
struct csi_sequence sequence = {.parameter = NULL,
|
||||
.parameter_len = 0,
|
||||
.intermediate = NULL,
|
||||
.intermediate_len = 0,
|
||||
.final = NULL,
|
||||
.valid = false};
|
||||
|
||||
for (size_t j = 0; j < size; j++) {
|
||||
uint8_t c = data[j];
|
||||
if (state == PARAMETER && (c >= 0x30 && c <= 0x3F)) {
|
||||
if (!sequence.parameter)
|
||||
sequence.parameter = data + j;
|
||||
sequence.parameter_len++;
|
||||
} else if (c >= 0x20 && c <= 0x2F) {
|
||||
if (!sequence.intermediate)
|
||||
sequence.intermediate = data + j;
|
||||
sequence.intermediate_len++;
|
||||
state = INTERMEDIATE;
|
||||
} else if (c >= 0x40 && c <= 0x7F) {
|
||||
sequence.final = data + j;
|
||||
sequence.valid = true;
|
||||
state = FINAL;
|
||||
break;
|
||||
} else {
|
||||
// Parameter found in intermediate byte location, or byte out of
|
||||
// range
|
||||
state = INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sequence;
|
||||
}
|
||||
|
||||
void term_write(const char* data, size_t size) {
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
// Begin handling ANSI escape codes.
|
||||
if (data[i] == 0x1b) { // The current character is ESC - the start of ANSI codes.
|
||||
// term_writes("ANSI Code encountered: ");
|
||||
|
||||
bool string_terminated = false; // Flag used in some of the escape codes
|
||||
|
||||
// TODO: Should only progress if we have at least 2 more bytes
|
||||
|
||||
switch ((uint8_t)data[i + 1]) {
|
||||
case '[': // CSI - Control Sequence Introducer (The most common one, hence it comes first)
|
||||
{
|
||||
struct csi_sequence sequence = parse_csi(data + i + 2, size - (i + 2));
|
||||
if (sequence.valid) {
|
||||
// Send it off to our handler function to keep this part clean
|
||||
handleControlSequence(sequence);
|
||||
i += sequence.parameter_len + sequence.intermediate_len + 2; // Move past sequence
|
||||
}
|
||||
} break;
|
||||
// Single shifts are not handled, so just print them and exit
|
||||
case 'N': // SS2 - Single Shift Two
|
||||
term_writes("Single Shift Two\n");
|
||||
break;
|
||||
case 'O': // SS3 - Single Shift Three
|
||||
term_writes("Single Shift Three\n");
|
||||
break;
|
||||
|
||||
// Control Strings
|
||||
case 'P': // DCS - Device Control String
|
||||
term_writes("Device Control String");
|
||||
string_terminated = false;
|
||||
break;
|
||||
case '\\': // ST - String Terminator
|
||||
term_writes("String Terminator\n");
|
||||
string_terminated = true;
|
||||
break;
|
||||
case ']': // OSC - Operating System Command
|
||||
term_writes("Operating System Command\n");
|
||||
string_terminated = false;
|
||||
break;
|
||||
case 'X': // SOS - Start Of String
|
||||
term_writes("Start of String");
|
||||
string_terminated = false;
|
||||
break;
|
||||
case '^': // PM - Privacy Message
|
||||
term_writes("Privacy Message\n");
|
||||
break;
|
||||
case '_': // APC - Application Program Command
|
||||
term_writes("Application Program Command\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
term_putchar(data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void term_writes(const char* data) { term_write(data, strlen(data)); }
|
||||
|
||||
void puts(const char* string) {
|
||||
term_write(string, strlen(string));
|
||||
term_putchar('\n');
|
||||
}
|
||||
|
||||
void handleControlSequence(struct csi_sequence sequence) {
|
||||
// Check for our failsafes
|
||||
|
||||
if (sequence.valid) {
|
||||
int n = 0; // Default of the flag used for a few items
|
||||
|
||||
// Parse parameters, we only care about a max 2 of number only parameters
|
||||
// for now
|
||||
int params[2] = {0};
|
||||
int param_count = 0;
|
||||
if (sequence.parameter_len) {
|
||||
for (size_t i = 0; i < sequence.parameter_len && param_count < 1; i++) {
|
||||
char c = sequence.parameter[i];
|
||||
if (isDigit(c)) {
|
||||
n = (n * 10) + (sequence.parameter[i] - '0');
|
||||
} else if (c == ';') {
|
||||
params[param_count++] = n;
|
||||
}
|
||||
}
|
||||
params[param_count++] = n;
|
||||
}
|
||||
|
||||
switch (*(sequence.final)) {
|
||||
case 'H':
|
||||
case 'f': // CUP - Cursor Position
|
||||
// TODO: Check to see if we have 2 paramaters
|
||||
if (params[0])
|
||||
params[0]--;
|
||||
if (params[1])
|
||||
params[1]--;
|
||||
set_cursor(params[0], params[1]);
|
||||
break;
|
||||
case 'A': // CUU - Cursor Up
|
||||
if (!params[0])
|
||||
params[0] = 1;
|
||||
set_cursor(terminal_column, terminal_row - params[0]);
|
||||
break;
|
||||
case 'B': // CUD - Cursor Down
|
||||
if (!params[0])
|
||||
params[0] = 1;
|
||||
set_cursor(terminal_column, terminal_row + params[0]);
|
||||
break;
|
||||
case 'C': // CUF - Cursor Forward
|
||||
if (!params[0])
|
||||
params[0] = 1;
|
||||
set_cursor(terminal_column + params[0], terminal_row);
|
||||
break;
|
||||
case 'D': // CUB - Cursor Back
|
||||
if (!params[0])
|
||||
params[0] = 1;
|
||||
set_cursor(terminal_column - params[0], terminal_row);
|
||||
break;
|
||||
case 'E': // CNL - Cursor Next Line
|
||||
if (!params[0])
|
||||
params[0] = 1;
|
||||
set_cursor(0, terminal_row + params[0]);
|
||||
break;
|
||||
case 'F': // CPL - Cursor Previous Line
|
||||
if (!params[0])
|
||||
params[0] = 1;
|
||||
set_cursor(0, terminal_row - params[0]);
|
||||
break;
|
||||
case 'G': // CHA - Cursor Horizontal Absolute
|
||||
if (params[0])
|
||||
params[0]--;
|
||||
set_cursor(params[0], terminal_row);
|
||||
break;
|
||||
case 'J': // ED - Erase in Display
|
||||
{
|
||||
// current cursor pos = y * width + x
|
||||
int pos = terminal_row * 80 + terminal_column;
|
||||
if (params[0] == 0) { // Clear from cursor to end of screen
|
||||
for (; pos < (25 * 80); pos++) {
|
||||
vga_buffer[pos] = '\0';
|
||||
}
|
||||
} else if (params[0] == 1) { // Clear from cursor to beginning
|
||||
for (; pos > 0; pos--) {
|
||||
vga_buffer[pos] = '\0';
|
||||
}
|
||||
} else if (params[0] == 2 || params[0] == 3) { // Clear entire screen
|
||||
// TODO: Support scrollback buffer? (n = 3)
|
||||
for (int i = 0; i < (25 * 80); i++) {
|
||||
vga_buffer[0] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'K': // EL - Erase in Line
|
||||
{
|
||||
int pos = terminal_row * 80 + terminal_column;
|
||||
if (params[0] == 0) { // From cursor to end of line
|
||||
int endPos = (terminal_row + 1) * 80 - 1; // End of line = current row + 25 columns = current row + 1
|
||||
for (; pos < endPos; pos++) {
|
||||
vga_buffer[pos] = '\0';
|
||||
}
|
||||
} else if (params[0] == 1) { // From cursor to start of line
|
||||
int endPos = terminal_row * 80; // Start of line = end of previous line + 1 == current line
|
||||
for (; pos > endPos; pos--) {
|
||||
vga_buffer[pos] = '\0';
|
||||
}
|
||||
} else if (params[0] == 2) { // Entire current line
|
||||
pos = terminal_row * 80;
|
||||
int endPos = (terminal_row + 1) * 80 - 1;
|
||||
for (; pos < endPos; pos++) {
|
||||
vga_buffer[pos] = '\0';
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'S': // SU - Scroll Up
|
||||
term_scroll(true);
|
||||
break;
|
||||
case 'T': // SD - Scroll Down
|
||||
term_scroll(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isDigit(char c) { return c >= '0' && c <= '9'; }
|
||||
|
||||
void set_cursor(int n, int m) {
|
||||
terminal_column = n;
|
||||
terminal_row = m;
|
||||
}
|
||||
|
||||
void term_scroll(bool down) {
|
||||
|
||||
int current_pos;
|
||||
if (down) {
|
||||
current_pos = 25 * 80; // Start of the last line.
|
||||
} else {
|
||||
current_pos = 160; // Start of the second line.
|
||||
}
|
||||
|
||||
unsigned char* term_buffer = (unsigned char*)vga_buffer;
|
||||
|
||||
if (down) { // To scroll down, move every character into the one below it, or "pull" every character down
|
||||
while (current_pos > 80) {
|
||||
term_buffer[current_pos + 160] = vga_buffer[current_pos];
|
||||
term_buffer[current_pos + 159] = vga_buffer[current_pos - 1];
|
||||
current_pos -= 2;
|
||||
}
|
||||
} else {
|
||||
while (current_pos <= 4000) {
|
||||
term_buffer[current_pos - 160 /*The character immediately below it*/] =
|
||||
vga_buffer[current_pos]; // Move each character up a line
|
||||
term_buffer[current_pos - 159 /*The color of the character below*/] =
|
||||
vga_buffer[current_pos + 1]; // As well as its color
|
||||
current_pos += 2; // Move to next char
|
||||
}
|
||||
}
|
||||
|
||||
if (down) {
|
||||
current_pos = 0; // Start of first line
|
||||
for (; current_pos < 80; current_pos++) {
|
||||
term_buffer[current_pos] = '\0';
|
||||
current_pos += 2;
|
||||
}
|
||||
} else {
|
||||
; // Start of the last line
|
||||
// Wipe out the bottom line
|
||||
for (current_pos = 3840; current_pos <= 3920; current_pos += 2) {
|
||||
term_buffer[current_pos] = 0;
|
||||
}
|
||||
}
|
||||
terminal_row = 24; // Start writing on the last line
|
||||
terminal_column = 0;
|
||||
}
|
53
bochsrc.txt
53
bochsrc.txt
|
@ -1,53 +0,0 @@
|
|||
# configuration file generated by Bochs
|
||||
plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, iodebug=1
|
||||
config_interface: textconfig
|
||||
display_library: x
|
||||
memory: host=32, guest=32
|
||||
romimage: file="/usr/share/bochs/BIOS-bochs-latest", address=0x0, options=none
|
||||
vgaromimage: file="/usr/share/bochs/VGABIOS-lgpl-latest"
|
||||
boot: a
|
||||
floppy_bootsig_check: disabled=1
|
||||
floppya: 1_44=/dev/loop0, status=inserted
|
||||
# no floppyb
|
||||
ata0: enabled=0
|
||||
ata1: enabled=0
|
||||
ata2: enabled=0
|
||||
ata3: enabled=0
|
||||
optromimage1: file=none
|
||||
optromimage2: file=none
|
||||
optromimage3: file=none
|
||||
optromimage4: file=none
|
||||
optramimage1: file=none
|
||||
optramimage2: file=none
|
||||
optramimage3: file=none
|
||||
optramimage4: file=none
|
||||
pci: enabled=1, chipset=i440fx
|
||||
vga: extension=vbe, update_freq=5, realtime=1
|
||||
cpu: count=1:1:1, ips=1000000, quantum=16, model=bx_generic, reset_on_triple_fault=0, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
|
||||
cpuid: level=6, stepping=3, model=3, family=6, vendor_string="AuthenticAMD", brand_string="AMD Athlon(tm) processor"
|
||||
cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0
|
||||
cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, avx_f16c=0, avx_fma=0, bmi=0, xop=0, fma4=0
|
||||
cpuid: tbm=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0, smep=0, smap=0, mwait=1
|
||||
print_timestamps: enabled=0
|
||||
debugger_log: ../red.debug
|
||||
magic_break: enabled=1
|
||||
port_e9_hack: enabled=0
|
||||
private_colormap: enabled=0
|
||||
clock: sync=none, time0=local, rtc_sync=0
|
||||
# no cmosimage
|
||||
# no loader
|
||||
log: ../red.log
|
||||
logprefix: %t%e%d
|
||||
debug: action=ignore
|
||||
info: action=report
|
||||
error: action=report
|
||||
panic: action=ask
|
||||
keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none
|
||||
mouse: type=ps2, enabled=0, toggle=ctrl+mbutton
|
||||
speaker: enabled=1, mode=system
|
||||
parport1: enabled=1, file=none
|
||||
parport2: enabled=0
|
||||
com1: enabled=1, mode=null
|
||||
com2: enabled=0
|
||||
com3: enabled=0
|
||||
com4: enabled=0
|
141
debug.vbs
Normal file
141
debug.vbs
Normal file
|
@ -0,0 +1,141 @@
|
|||
' Visual Studio QEMU debugging script.
|
||||
'
|
||||
' I like invoking vbs as much as anyone else, but we need to download and unzip our
|
||||
' firmware file, as well as launch QEMU, and neither Powershell or a standard batch
|
||||
' can do that without having an extra console appearing.
|
||||
'
|
||||
' Note: You may get a prompt from the firewall when trying to download the BIOS file
|
||||
|
||||
' Modify these variables as needed
|
||||
QEMU_PATH = "C:\Program Files\qemu\"
|
||||
' You can add something like "-S -gdb tcp:127.0.0.1:1234" if you plan to use gdb to debug
|
||||
QEMU_OPTS = "-net none -monitor none -parallel none"
|
||||
' Set to True if you need to download a file that might be cached locally
|
||||
NO_CACHE = False
|
||||
|
||||
' You shouldn't have to modify anything below this
|
||||
TARGET = WScript.Arguments(1)
|
||||
|
||||
If (TARGET = "x86") Then
|
||||
UEFI_EXT = "ia32"
|
||||
QEMU_ARCH = "i386"
|
||||
FW_BASE = "OVMF"
|
||||
ElseIf (TARGET = "x64") Then
|
||||
UEFI_EXT = "x64"
|
||||
QEMU_ARCH = "x86_64"
|
||||
FW_BASE = "OVMF"
|
||||
ElseIf (TARGET = "ARM") Then
|
||||
UEFI_EXT = "arm"
|
||||
QEMU_ARCH = "arm"
|
||||
FW_BASE = "QEMU_EFI"
|
||||
' You can also add '-device VGA' to the options below, to get graphics output.
|
||||
' But if you do, be mindful that the keyboard input may not work... :(
|
||||
QEMU_OPTS = "-M virt -cpu cortex-a15 " & QEMU_OPTS
|
||||
ElseIf (TARGET = "ARM64") Then
|
||||
UEFI_EXT = "aa64"
|
||||
QEMU_ARCH = "aarch64"
|
||||
FW_BASE = "QEMU_EFI"
|
||||
QEMU_OPTS = "-M virt -cpu cortex-a57 " & QEMU_OPTS
|
||||
Else
|
||||
MsgBox("Unsupported debug target: " & TARGET)
|
||||
Call WScript.Quit(1)
|
||||
End If
|
||||
BOOT_NAME = "boot" & UEFI_EXT & ".efi"
|
||||
QEMU_EXE = "qemu-system-" & QEMU_ARCH & "w.exe"
|
||||
|
||||
FW_ARCH = UCase(UEFI_EXT)
|
||||
FW_DIR = "https://efi.akeo.ie/" & FW_BASE & "/"
|
||||
FW_ZIP = FW_BASE & "-" & FW_ARCH & ".zip"
|
||||
FW_FILE = FW_BASE & "_" & FW_ARCH & ".fd"
|
||||
FW_URL = FW_DIR & FW_ZIP
|
||||
|
||||
' Globals
|
||||
Set fso = CreateObject("Scripting.FileSystemObject")
|
||||
Set shell = CreateObject("WScript.Shell")
|
||||
|
||||
' Download a file from FTP
|
||||
Sub DownloadFtp(Server, Path)
|
||||
Set file = fso.CreateTextFile("ftp.txt", True)
|
||||
Call file.Write("open " & Server & vbCrLf &_
|
||||
"anonymous" & vbCrLf & "user" & vbCrLf & "bin" & vbCrLf &_
|
||||
"get " & Path & vbCrLf & "bye" & vbCrLf)
|
||||
Call file.Close()
|
||||
Call shell.Run("%comspec% /c ftp -s:ftp.txt > NUL", 0, True)
|
||||
Call fso.DeleteFile("ftp.txt")
|
||||
End Sub
|
||||
|
||||
' Download a file from HTTP
|
||||
Sub DownloadHttp(Url, File)
|
||||
Const BINARY = 1
|
||||
Const OVERWRITE = 2
|
||||
Set xHttp = createobject("Microsoft.XMLHTTP")
|
||||
Set bStrm = createobject("Adodb.Stream")
|
||||
Call xHttp.Open("GET", Url, False)
|
||||
If NO_CACHE = True Then
|
||||
Call xHttp.SetRequestHeader("If-None-Match", "some-random-string")
|
||||
Call xHttp.SetRequestHeader("Cache-Control", "no-cache,max-age=0")
|
||||
Call xHttp.SetRequestHeader("Pragma", "no-cache")
|
||||
End If
|
||||
Call xHttp.Send()
|
||||
If Not xHttp.Status = 200 Then
|
||||
Call WScript.Echo("Unable to access file - Error " & xHttp.Status)
|
||||
Call WScript.Quit(1)
|
||||
End If
|
||||
With bStrm
|
||||
.type = BINARY
|
||||
.open
|
||||
.write xHttp.responseBody
|
||||
.savetofile File, OVERWRITE
|
||||
End With
|
||||
End Sub
|
||||
|
||||
' Unzip a specific file from an archive
|
||||
Sub Unzip(Archive, File)
|
||||
Const NOCONFIRMATION = &H10&
|
||||
Const NOERRORUI = &H400&
|
||||
Const SIMPLEPROGRESS = &H100&
|
||||
unzipFlags = NOCONFIRMATION + NOERRORUI + SIMPLEPROGRESS
|
||||
Set objShell = CreateObject("Shell.Application")
|
||||
Set objSource = objShell.NameSpace(fso.GetAbsolutePathName(Archive)).Items()
|
||||
Set objTarget = objShell.NameSpace(fso.GetAbsolutePathName("."))
|
||||
' Only extract the file we are interested in
|
||||
For i = 0 To objSource.Count - 1
|
||||
If objSource.Item(i).Name = File Then
|
||||
Call objTarget.CopyHere(objSource.Item(i), unzipFlags)
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
|
||||
' Check that QEMU is available
|
||||
If Not fso.FileExists(QEMU_PATH & QEMU_EXE) Then
|
||||
Call WScript.Echo("'" & QEMU_PATH & QEMU_EXE & "' was not found." & vbCrLf &_
|
||||
"Please make sure QEMU is installed or edit the path in '.msvc\debug.vbs'.")
|
||||
Call WScript.Quit(1)
|
||||
End If
|
||||
|
||||
' Fetch the UEFI firmware and unzip it
|
||||
If Not fso.FileExists(FW_FILE) Then
|
||||
Call WScript.Echo("The UEFI firmware file, needed for QEMU, " &_
|
||||
"will be downloaded from: " & FW_URL & vbCrLf & vbCrLf &_
|
||||
"Note: Unless you delete the file, this should only happen once.")
|
||||
Call DownloadHttp(FW_URL, FW_ZIP)
|
||||
End If
|
||||
If Not fso.FileExists(FW_ZIP) And Not fso.FileExists(FW_FILE) Then
|
||||
Call WScript.Echo("There was a problem downloading the QEMU UEFI firmware.")
|
||||
Call WScript.Quit(1)
|
||||
End If
|
||||
If fso.FileExists(FW_ZIP) Then
|
||||
Call Unzip(FW_ZIP, FW_BASE & ".fd")
|
||||
Call fso.MoveFile(FW_BASE & ".fd", FW_FILE)
|
||||
Call fso.DeleteFile(FW_ZIP)
|
||||
End If
|
||||
If Not fso.FileExists(FW_FILE) Then
|
||||
Call WScript.Echo("There was a problem unzipping the QEMU UEFI firmware.")
|
||||
Call WScript.Quit(1)
|
||||
End If
|
||||
|
||||
' Copy the app file as boot application and run it in QEMU
|
||||
Call shell.Run("%COMSPEC% /c mkdir ""image\efi\boot""", 0, True)
|
||||
Call fso.CopyFile(WScript.Arguments(0), "image\efi\boot\" & BOOT_NAME, True)
|
||||
Call shell.Run("""" & QEMU_PATH & QEMU_EXE & """ " & QEMU_OPTS & " -L . -bios " & FW_FILE & " -hda fat:rw:image", 1, True)
|
6
gnu-efi/.gitignore
vendored
Normal file
6
gnu-efi/.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
*.efi
|
||||
*.efi.debug
|
||||
*.o
|
||||
*.a
|
||||
*.tar.*
|
||||
*.tar
|
1324
gnu-efi/ChangeLog
Normal file
1324
gnu-efi/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
183
gnu-efi/Make.defaults
Normal file
183
gnu-efi/Make.defaults
Normal file
|
@ -0,0 +1,183 @@
|
|||
# -*- makefile -*-
|
||||
# Copyright (c) 1999-2007 Hewlett-Packard Development Company, L.P.
|
||||
# Contributed by David Mosberger <davidm@hpl.hp.com>
|
||||
# Contributed by Stephane Eranian <eranian@hpl.hp.com>
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
# * Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
|
||||
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
|
||||
|
||||
#
|
||||
# Variables below overridable from command-line:
|
||||
# make VARNAME=value ...
|
||||
#
|
||||
|
||||
#
|
||||
# Where to install the package. GNU-EFI will create and access
|
||||
# lib and include under the root
|
||||
#
|
||||
INSTALLROOT := /
|
||||
PREFIX := /usr/local
|
||||
LIBDIR := $(PREFIX)/lib
|
||||
INSTALL := install
|
||||
|
||||
# Compilation tools
|
||||
HOSTCC := $(prefix)gcc
|
||||
CC := $(prefix)$(CROSS_COMPILE)gcc
|
||||
AS := $(prefix)$(CROSS_COMPILE)as
|
||||
LD := $(prefix)$(CROSS_COMPILE)ld
|
||||
AR := $(prefix)$(CROSS_COMPILE)ar
|
||||
RANLIB := $(prefix)$(CROSS_COMPILE)ranlib
|
||||
OBJCOPY := $(prefix)$(CROSS_COMPILE)objcopy
|
||||
|
||||
|
||||
# Host/target identification
|
||||
OS := $(shell uname -s)
|
||||
HOSTARCH ?= $(shell $(HOSTCC) -dumpmachine | cut -f1 -d- | sed -e s,i[3456789]86,ia32, -e 's,armv7.*,arm,' )
|
||||
ARCH ?= $(shell $(HOSTCC) -dumpmachine | cut -f1 -d- | sed -e s,i[3456789]86,ia32, -e 's,armv7.*,arm,' )
|
||||
|
||||
# Get ARCH from the compiler if cross compiling
|
||||
ifneq ($(CROSS_COMPILE),)
|
||||
override ARCH := $(shell $(CC) -dumpmachine | cut -f1 -d-| sed -e s,i[3456789]86,ia32, -e 's,armv7.*,arm,' )
|
||||
endif
|
||||
|
||||
# FreeBSD (and possibly others) reports amd64 instead of x86_64
|
||||
ifeq ($(ARCH),amd64)
|
||||
override ARCH := x86_64
|
||||
endif
|
||||
|
||||
#
|
||||
# Where to build the package
|
||||
#
|
||||
OBJDIR := $(TOPDIR)/$(ARCH)
|
||||
|
||||
#
|
||||
# Variables below derived from variables above
|
||||
#
|
||||
|
||||
# Arch-specific compilation flags
|
||||
CPPFLAGS += -DCONFIG_$(ARCH)
|
||||
|
||||
CFLAGS += -Wno-error=pragmas
|
||||
|
||||
ifeq ($(ARCH),ia64)
|
||||
CFLAGS += -mfixed-range=f32-f127
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),ia32)
|
||||
CFLAGS += -mno-mmx -mno-sse
|
||||
ifeq ($(HOSTARCH),x86_64)
|
||||
ARCH3264 = -m32
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
GCCVERSION := $(shell $(CC) -dumpversion | cut -f1 -d.)
|
||||
GCCMINOR := $(shell $(CC) -dumpversion | cut -f2 -d.)
|
||||
USING_CLANG := $(shell $(CC) -v 2>&1 | grep -q 'clang version' && echo clang)
|
||||
|
||||
# Rely on GCC MS ABI support?
|
||||
GCCNEWENOUGH := $(shell ( [ $(GCCVERSION) -gt "4" ] \
|
||||
|| ( [ $(GCCVERSION) -eq "4" ] \
|
||||
&& [ $(GCCMINOR) -ge "7" ] ) ) \
|
||||
&& echo 1)
|
||||
ifeq ($(GCCNEWENOUGH),1)
|
||||
CPPFLAGS += -DGNU_EFI_USE_MS_ABI -maccumulate-outgoing-args --std=c11
|
||||
else ifeq ($(USING_CLANG),clang)
|
||||
CPPFLAGS += -DGNU_EFI_USE_MS_ABI --std=c11
|
||||
endif
|
||||
|
||||
CFLAGS += -mno-red-zone
|
||||
ifeq ($(HOSTARCH),ia32)
|
||||
ARCH3264 = -m64
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter $(ARCH),ia32 x86_64))
|
||||
# Disable AVX, if the compiler supports that.
|
||||
CC_CAN_DISABLE_AVX=$(shell $(CC) -Werror -c -o /dev/null -xc -mno-avx - </dev/null >/dev/null 2>&1 && echo 1)
|
||||
ifeq ($(CC_CAN_DISABLE_AVX), 1)
|
||||
CFLAGS += -mno-avx
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),mips64el)
|
||||
CFLAGS += -march=mips64r2
|
||||
ARCH3264 = -mabi=64
|
||||
endif
|
||||
|
||||
#
|
||||
# Set HAVE_EFI_OBJCOPY if objcopy understands --target efi-[app|bsdrv|rtdrv],
|
||||
# otherwise we need to compose the PE/COFF header using the assembler
|
||||
#
|
||||
ifneq ($(ARCH),aarch64)
|
||||
ifneq ($(ARCH),arm)
|
||||
ifneq ($(ARCH),mips64el)
|
||||
export HAVE_EFI_OBJCOPY=y
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(ARCH),arm)
|
||||
export LIBGCC=$(shell $(CC) $(ARCH3264) -print-libgcc-file-name)
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),arm)
|
||||
CFLAGS += -marm
|
||||
endif
|
||||
|
||||
# Generic compilation flags
|
||||
INCDIR += -I$(SRCDIR) -I$(TOPDIR)/inc -I$(TOPDIR)/inc/$(ARCH) \
|
||||
-I$(TOPDIR)/inc/protocol
|
||||
|
||||
# Only enable -fpic for non MinGW compilers (unneeded on MinGW)
|
||||
GCCMACHINE := $(shell $(CC) -dumpmachine)
|
||||
ifneq (mingw32,$(findstring mingw32, $(GCCMACHINE)))
|
||||
CFLAGS += -fpic
|
||||
endif
|
||||
|
||||
ifeq (FreeBSD, $(findstring FreeBSD, $(OS)))
|
||||
CFLAGS += $(ARCH3264) -g -O2 -Wall -Wextra -Werror \
|
||||
-fshort-wchar -fno-strict-aliasing \
|
||||
-ffreestanding -fno-stack-protector
|
||||
else
|
||||
CFLAGS += $(ARCH3264) -g -O2 -Wall -Wextra -Werror \
|
||||
-fshort-wchar -fno-strict-aliasing \
|
||||
-ffreestanding -fno-stack-protector -fno-stack-check \
|
||||
-fno-stack-check \
|
||||
$(if $(findstring gcc,$(CC)),-fno-merge-all-constants,)
|
||||
endif
|
||||
|
||||
ARFLAGS := rDv
|
||||
ASFLAGS += $(ARCH3264)
|
||||
LDFLAGS += -nostdlib --warn-common --no-undefined --fatal-warnings \
|
||||
--build-id=sha1
|
58
gnu-efi/Make.rules
Normal file
58
gnu-efi/Make.rules
Normal file
|
@ -0,0 +1,58 @@
|
|||
#
|
||||
# Copyright (C) 1999-2007 Hewlett-Packard Co.
|
||||
# Contributed by David Mosberger <davidm@hpl.hp.com>
|
||||
# Contributed by Stephane Eranian <eranian@hpl.hp.com>
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
# * Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
|
||||
%.efi: %.so
|
||||
$(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
|
||||
-j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
|
||||
-j .reloc $(FORMAT) $*.so $@
|
||||
|
||||
%.efi.debug: %.so
|
||||
$(OBJCOPY) -j .debug_info -j .debug_abbrev -j .debug_aranges \
|
||||
-j .debug_line -j .debug_str -j .debug_ranges \
|
||||
-j .note.gnu.build-id \
|
||||
$(FORMAT) $*.so $@
|
||||
|
||||
%.so: %.o
|
||||
$(LD) $(LDFLAGS) $^ -o $@ $(LOADLIBES)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
%.S: %.c
|
||||
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -S $< -o $@
|
||||
|
||||
%.E: %.c
|
||||
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -E $< -o $@
|
129
gnu-efi/Makefile
Normal file
129
gnu-efi/Makefile
Normal file
|
@ -0,0 +1,129 @@
|
|||
#
|
||||
# Copyright (C) 1999-2007 Hewlett-Packard Co.
|
||||
# Contributed by David Mosberger <davidm@hpl.hp.com>
|
||||
# Contributed by Stephane Eranian <eranian@hpl.hp.com>
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
# * Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
|
||||
VERSION = 3.0.9
|
||||
|
||||
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
SRCDIR = $(dir $(MKFILE_PATH))
|
||||
|
||||
VPATH = $(SRCDIR)
|
||||
|
||||
include $(SRCDIR)/Make.defaults
|
||||
|
||||
SUBDIRS = lib gnuefi inc apps
|
||||
gnuefi: lib
|
||||
|
||||
all: check_gcc $(SUBDIRS)
|
||||
|
||||
mkvars:
|
||||
@echo AR=$(AR)
|
||||
@echo ARCH=$(ARCH)
|
||||
@echo ARCH3264=$(ARCH3264)
|
||||
@echo AS=$(AS)
|
||||
@echo ASFLAGS=$(ASFLAGS)
|
||||
@echo CC=$(CC)
|
||||
@echo CFLAGS=$(CFLAGS)
|
||||
@echo CPPFLAGS=$(CPPFLAGS)
|
||||
@echo GCCMINOR=$(GCCMINOR)
|
||||
@echo GCCNEWENOUGH=$(GCCNEWENOUGH)
|
||||
@echo GCCVERSION=$(GCCVERSION)
|
||||
@echo HOSTARCH=$(HOSTARCH)
|
||||
@echo INCDIR=$(INCDIR)
|
||||
@echo INSTALL=$(INSTALL)
|
||||
@echo INSTALLROOT=$(INSTALLROOT)
|
||||
@echo LD=$(LD)
|
||||
@echo LDFLAGS=$(LDFLAGS)
|
||||
@echo LIBDIR=$(LIBDIR)
|
||||
@echo OBJCOPY=$(OBJCOPY)
|
||||
@echo OS=$(OS)
|
||||
@echo prefix=$(prefix)
|
||||
@echo PREFIX=$(PREFIX)
|
||||
@echo RANLIB=$(RANLIB)
|
||||
@echo SRCDIR=$(SRCDIR)
|
||||
@echo TOPDIR=$(TOPDIR)
|
||||
|
||||
$(SUBDIRS):
|
||||
mkdir -p $(OBJDIR)/$@
|
||||
$(MAKE) -C $(OBJDIR)/$@ -f $(SRCDIR)/$@/Makefile SRCDIR=$(SRCDIR)/$@ ARCH=$(ARCH)
|
||||
|
||||
clean:
|
||||
rm -f *~
|
||||
@for d in $(SUBDIRS); do \
|
||||
if [ -d $(OBJDIR)/$$d ]; then \
|
||||
$(MAKE) -C $(OBJDIR)/$$d -f $(SRCDIR)/$$d/Makefile SRCDIR=$(SRCDIR)/$$d clean; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
install:
|
||||
@for d in $(SUBDIRS); do \
|
||||
mkdir -p $(OBJDIR)/$$d; \
|
||||
$(MAKE) -C $(OBJDIR)/$$d -f $(SRCDIR)/$$d/Makefile SRCDIR=$(SRCDIR)/$$d install; done
|
||||
|
||||
.PHONY: $(SUBDIRS) clean depend
|
||||
|
||||
#
|
||||
# on both platforms you must use gcc 3.0 or higher
|
||||
#
|
||||
check_gcc:
|
||||
ifeq ($(GCC_VERSION),2)
|
||||
@echo "you need to use a version of gcc >= 3.0, you are using `$(CC) --version`"
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
include $(SRCDIR)/Make.rules
|
||||
|
||||
test-archive:
|
||||
@rm -rf /tmp/gnu-efi-$(VERSION) /tmp/gnu-efi-$(VERSION)-tmp
|
||||
@mkdir -p /tmp/gnu-efi-$(VERSION)-tmp
|
||||
@git archive --format=tar $(shell git branch | awk '/^*/ { print $$2 }') | ( cd /tmp/gnu-efi-$(VERSION)-tmp/ ; tar x )
|
||||
@git diff | ( cd /tmp/gnu-efi-$(VERSION)-tmp/ ; patch -s -p1 -b -z .gitdiff )
|
||||
@mv /tmp/gnu-efi-$(VERSION)-tmp/ /tmp/gnu-efi-$(VERSION)/
|
||||
@dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/gnu-efi-$(VERSION).tar.bz2 gnu-efi-$(VERSION)
|
||||
@rm -rf /tmp/gnu-efi-$(VERSION)
|
||||
@echo "The archive is in gnu-efi-$(VERSION).tar.bz2"
|
||||
|
||||
tag:
|
||||
git tag $(VERSION) refs/heads/master
|
||||
|
||||
archive: tag
|
||||
@rm -rf /tmp/gnu-efi-$(VERSION) /tmp/gnu-efi-$(VERSION)-tmp
|
||||
@mkdir -p /tmp/gnu-efi-$(VERSION)-tmp
|
||||
@git archive --format=tar $(VERSION) | ( cd /tmp/gnu-efi-$(VERSION)-tmp/ ; tar x )
|
||||
@mv /tmp/gnu-efi-$(VERSION)-tmp/ /tmp/gnu-efi-$(VERSION)/
|
||||
@dir=$$PWD; cd /tmp; tar -c --bzip2 -f $$dir/gnu-efi-$(VERSION).tar.bz2 gnu-efi-$(VERSION)
|
||||
@rm -rf /tmp/gnu-efi-$(VERSION)
|
||||
@echo "The archive is in gnu-efi-$(VERSION).tar.bz2"
|
||||
|
30
gnu-efi/README.efilib
Normal file
30
gnu-efi/README.efilib
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
The files in the "lib" and "inc" subdirectories are using the EFI Application
|
||||
Toolkit distributed by Intel at http://developer.intel.com/technology/efi
|
||||
|
||||
This code is covered by the following agreement:
|
||||
|
||||
Copyright (c) 1998-2000 Intel Corporation
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted
|
||||
provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and
|
||||
the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
||||
and the following disclaimer in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. THE EFI SPECIFICATION AND ALL OTHER INFORMATION
|
||||
ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO WARRANTIES, AND ARE SUBJECT
|
||||
TO CHANGE WITHOUT NOTICE.
|
19
gnu-efi/README.elilo
Normal file
19
gnu-efi/README.elilo
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
IMPORTANT information related to the gnu-efi package
|
||||
----------------------------------------------------
|
||||
June 2001
|
||||
|
||||
As of version 3.0, the gnu-efi package is now split in two different packages:
|
||||
|
||||
-> gnu-efi-X.y: contains the EFI library, include files and crt0.
|
||||
|
||||
-> elilo-X.y : contains the ELILO bootloader.
|
||||
|
||||
Note that X.y don't need to match for both packages. However elilo-3.x
|
||||
requires at least gnu-efi-3.0. EFI support for x86_64 is provided in
|
||||
gnu-efi-3.0d.
|
||||
|
||||
Both packages can be downloaded from:
|
||||
|
||||
http://www.sf.net/projects/gnu-efi
|
||||
http://www.sf.net/projects/elilo
|
21
gnu-efi/README.git
Normal file
21
gnu-efi/README.git
Normal file
|
@ -0,0 +1,21 @@
|
|||
README.git
|
||||
|
||||
Generating releases from git a very simple process;
|
||||
|
||||
1) Edit the file "Makefile". Changing the "VERSION" line to the new version.
|
||||
2) Do a "git commit" just for the version number change.
|
||||
3) Then do a "make test-archive".
|
||||
That will make a file in the current directory gnu-efi-$VERSION.tar.bz2 ,
|
||||
with its top level directory gnu-efi-$VERSION/ and the source tree under that.
|
||||
|
||||
Once you've tested that and you're sure it's what you want to release,
|
||||
4) Do "make archive", which will tag a release in git and generate a
|
||||
final tarball from it.
|
||||
|
||||
You then push to the archive, being sure to include the tag:
|
||||
5) "git push origin master:master --tags"
|
||||
|
||||
And upload the archive wherever it's supposed to go.
|
||||
|
||||
|
||||
|
405
gnu-efi/README.gnuefi
Normal file
405
gnu-efi/README.gnuefi
Normal file
|
@ -0,0 +1,405 @@
|
|||
-------------------------------------------------
|
||||
Building EFI Applications Using the GNU Toolchain
|
||||
-------------------------------------------------
|
||||
|
||||
David Mosberger <davidm@hpl.hp.com>
|
||||
|
||||
23 September 1999
|
||||
|
||||
|
||||
Copyright (c) 1999-2007 Hewlett-Packard Co.
|
||||
Copyright (c) 2006-2010 Intel Co.
|
||||
|
||||
Last update: 04/09/2007
|
||||
|
||||
* Introduction
|
||||
|
||||
This document has two parts: the first part describes how to develop
|
||||
EFI applications for IA-64,x86 and x86_64 using the GNU toolchain and the EFI
|
||||
development environment contained in this directory. The second part
|
||||
describes some of the more subtle aspects of how this development
|
||||
environment works.
|
||||
|
||||
|
||||
|
||||
* Part 1: Developing EFI Applications
|
||||
|
||||
|
||||
** Prerequisites:
|
||||
|
||||
To develop x86 and x86_64 EFI applications, the following tools are needed:
|
||||
|
||||
- gcc-3.0 or newer (gcc 2.7.2 is NOT sufficient!)
|
||||
As of gnu-efi-3.0b, the Redhat 8.0 toolchain is known to work,
|
||||
but the Redhat 9.0 toolchain is not currently supported.
|
||||
|
||||
- A version of "objcopy" that supports EFI applications. To
|
||||
check if your version includes EFI support, issue the
|
||||
command:
|
||||
|
||||
objcopy --help
|
||||
|
||||
Verify that the line "supported targets" contains the string
|
||||
"efi-app-ia32" and "efi-app-x86_64" and that the "-j" option
|
||||
accepts wildcards. The binutils release binutils-2.24
|
||||
supports Intel64 EFI and accepts wildcard section names.
|
||||
|
||||
- For debugging purposes, it's useful to have a version of
|
||||
"objdump" that supports EFI applications as well. This
|
||||
allows inspect and disassemble EFI binaries.
|
||||
|
||||
To develop IA-64 EFI applications, the following tools are needed:
|
||||
|
||||
- A version of gcc newer than July 30th 1999 (older versions
|
||||
had problems with generating position independent code).
|
||||
As of gnu-efi-3.0b, gcc-3.1 is known to work well.
|
||||
|
||||
- A version of "objcopy" that supports EFI applications. To
|
||||
check if your version includes EFI support, issue the
|
||||
command:
|
||||
|
||||
objcopy --help
|
||||
|
||||
Verify that the line "supported targets" contains the string
|
||||
"efi-app-ia64" and that the "-j" option accepts wildcards.
|
||||
|
||||
- For debugging purposes, it's useful to have a version of
|
||||
"objdump" that supports EFI applications as well. This
|
||||
allows inspect and disassemble EFI binaries.
|
||||
|
||||
|
||||
** Directory Structure
|
||||
|
||||
This EFI development environment contains the following
|
||||
subdirectories:
|
||||
|
||||
inc: This directory contains the EFI-related include files. The
|
||||
files are taken from Intel's EFI source distribution, except
|
||||
that various fixes were applied to make it compile with the
|
||||
GNU toolchain.
|
||||
|
||||
lib: This directory contains the source code for Intel's EFI library.
|
||||
Again, the files are taken from Intel's EFI source
|
||||
distribution, with changes to make them compile with the GNU
|
||||
toolchain.
|
||||
|
||||
gnuefi: This directory contains the glue necessary to convert ELF64
|
||||
binaries to EFI binaries. Various runtime code bits, such as
|
||||
a self-relocator are included as well. This code has been
|
||||
contributed by the Hewlett-Packard Company and is distributed
|
||||
under the GNU GPL.
|
||||
|
||||
apps: This directory contains a few simple EFI test apps.
|
||||
|
||||
** Setup
|
||||
|
||||
It is necessary to edit the Makefile in the directory containing this
|
||||
README file before EFI applications can be built. Specifically, you
|
||||
should verify that macros CC, AS, LD, AR, RANLIB, and OBJCOPY point to
|
||||
the appropriate compiler, assembler, linker, ar, and ranlib binaries,
|
||||
respectively.
|
||||
|
||||
If you're working in a cross-development environment, be sure to set
|
||||
macro ARCH to the desired target architecture ("ia32" for x86, "x86_64" for
|
||||
x86_64 and "ia64" for IA-64). For convenience, this can also be done from
|
||||
the make command line (e.g., "make ARCH=ia64").
|
||||
|
||||
|
||||
** Building
|
||||
|
||||
To build the sample EFI applications provided in subdirectory "apps",
|
||||
simply invoke "make" in the toplevel directory (the directory
|
||||
containing this README file). This should build lib/libefi.a and
|
||||
gnuefi/libgnuefi.a first and then all the EFI applications such as a
|
||||
apps/t6.efi.
|
||||
|
||||
|
||||
** Running
|
||||
|
||||
Just copy the EFI application (e.g., apps/t6.efi) to the EFI
|
||||
filesystem, boot EFI, and then select "Invoke EFI application" to run
|
||||
the application you want to test. Alternatively, you can invoke the
|
||||
Intel-provided "nshell" application and then invoke your test binary
|
||||
via the command line interface that "nshell" provides.
|
||||
|
||||
|
||||
** Writing Your Own EFI Application
|
||||
|
||||
Suppose you have your own EFI application in a file called
|
||||
"apps/myefiapp.c". To get this application built by the GNU EFI build
|
||||
environment, simply add "myefiapp.efi" to macro TARGETS in
|
||||
apps/Makefile. Once this is done, invoke "make" in the top level
|
||||
directory. This should result in EFI application apps/myefiapp.efi,
|
||||
ready for execution.
|
||||
|
||||
The GNU EFI build environment allows to write EFI applications as
|
||||
described in Intel's EFI documentation, except for two differences:
|
||||
|
||||
- The EFI application's entry point is always called "efi_main". The
|
||||
declaration of this routine is:
|
||||
|
||||
EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab);
|
||||
|
||||
- UNICODE string literals must be written as W2U(L"Sample String")
|
||||
instead of just L"Sample String". The W2U() macro is defined in
|
||||
<efilib.h>. This header file also declares the function W2UCpy()
|
||||
which allows to convert a wide string into a UNICODE string and
|
||||
store the result in a programmer-supplied buffer.
|
||||
|
||||
- Calls to EFI services should be made via uefi_call_wrapper(). This
|
||||
ensures appropriate parameter passing for the architecture.
|
||||
|
||||
|
||||
* Part 2: Inner Workings
|
||||
|
||||
WARNING: This part contains all the gory detail of how the GNU EFI
|
||||
toolchain works. Normal users do not have to worry about such
|
||||
details. Reading this part incurs a definite risk of inducing severe
|
||||
headaches or other maladies.
|
||||
|
||||
The basic idea behind the GNU EFI build environment is to use the GNU
|
||||
toolchain to build a normal ELF binary that, at the end, is converted
|
||||
to an EFI binary. EFI binaries are really just PE32+ binaries. PE
|
||||
stands for "Portable Executable" and is the object file format
|
||||
Microsoft is using on its Windows platforms. PE is basically the COFF
|
||||
object file format with an MS-DOS2.0 compatible header slapped on in
|
||||
front of it. The "32" in PE32+ stands for 32 bits, meaning that PE32
|
||||
is a 32-bit object file format. The plus in "PE32+" indicates that
|
||||
this format has been hacked to allow loading a 4GB binary anywhere in
|
||||
a 64-bit address space (unlike ELF64, however, this is not a full
|
||||
64-bit object file format because the entire binary cannot span more
|
||||
than 4GB of address space). EFI binaries are plain PE32+ binaries
|
||||
except that the "subsystem id" differs from normal Windows binaries.
|
||||
There are two flavors of EFI binaries: "applications" and "drivers"
|
||||
and each has there own subsystem id and are identical otherwise. At
|
||||
present, the GNU EFI build environment supports the building of EFI
|
||||
applications only, though it would be trivial to generate drivers, as
|
||||
the only difference is the subsystem id. For more details on PE32+,
|
||||
see the spec at
|
||||
|
||||
http://msdn.microsoft.com/library/specs/msdn_pecoff.htm.
|
||||
|
||||
In theory, converting a suitable ELF64 binary to PE32+ is easy and
|
||||
could be accomplished with the "objcopy" utility by specifying option
|
||||
--target=efi-app-ia32 (x86) or --target=efi-app-ia64 (IA-64). But
|
||||
life never is that easy, so here some complicating factors:
|
||||
|
||||
(1) COFF sections are very different from ELF sections.
|
||||
|
||||
ELF binaries distinguish between program headers and sections.
|
||||
The program headers describe the memory segments that need to
|
||||
be loaded/initialized, whereas the sections describe what
|
||||
constitutes those segments. In COFF (and therefore PE32+) no
|
||||
such distinction is made. Thus, COFF sections need to be page
|
||||
aligned and have a size that is a multiple of the page size
|
||||
(4KB for EFI), whereas ELF allows sections at arbitrary
|
||||
addresses and with arbitrary sizes.
|
||||
|
||||
(2) EFI binaries should be relocatable.
|
||||
|
||||
Since EFI binaries are executed in physical mode, EFI cannot
|
||||
guarantee that a given binary can be loaded at its preferred
|
||||
address. EFI does _try_ to load a binary at it's preferred
|
||||
address, but if it can't do so, it will load it at another
|
||||
address and then relocate the binary using the contents of the
|
||||
.reloc section.
|
||||
|
||||
(3) On IA-64, the EFI entry point needs to point to a function
|
||||
descriptor, not to the code address of the entry point.
|
||||
|
||||
(4) The EFI specification assumes that wide characters use UNICODE
|
||||
encoding.
|
||||
|
||||
ANSI C does not specify the size or encoding that a wide
|
||||
character uses. These choices are "implementation defined".
|
||||
On most UNIX systems, the GNU toolchain uses a wchar_t that is
|
||||
4 bytes in size. The encoding used for such characters is
|
||||
(mostly) UCS4.
|
||||
|
||||
In the following sections, we address how the GNU EFI build
|
||||
environment addresses each of these issues.
|
||||
|
||||
|
||||
** (1) Accommodating COFF Sections
|
||||
|
||||
In order to satisfy the COFF constraint of page-sized and page-aligned
|
||||
sections, the GNU EFI build environment uses the special linker script
|
||||
in gnuefi/elf_$(ARCH)_efi.lds where $(ARCH) is the target architecture
|
||||
("ia32" for x86, "x86_64" for x86_64 and "ia64" for IA-64).
|
||||
This script is set up to create only eight COFF section, each page aligned
|
||||
and page sized.These eight sections are used to group together the much
|
||||
greater number of sections that are typically present in ELF object files.
|
||||
Specifically:
|
||||
|
||||
.hash (and/or .gnu.hash)
|
||||
Collects the ELF .hash info (this section _must_ be the first
|
||||
section in order to build a shared object file; the section is
|
||||
not actually loaded or used at runtime).
|
||||
|
||||
GNU binutils provides a mechanism to generate different hash info
|
||||
via --hash-style=<sysv|gnu|both> option. In this case output
|
||||
shared object will contain .hash section, .gnu.hash section or
|
||||
both. In order to generate correct output linker script preserves
|
||||
both types of hash sections.
|
||||
|
||||
.text
|
||||
Collects all sections containing executable code.
|
||||
|
||||
.data
|
||||
Collects read-only and read-write data, literal string data,
|
||||
global offset tables, the uninitialized data segment (bss) and
|
||||
various other sections containing data.
|
||||
|
||||
The reason read-only data is placed here instead of the in
|
||||
.text is to make it possible to disassemble the .text section
|
||||
without getting garbage due to read-only data. Besides, since
|
||||
EFI binaries execute in physical mode, differences in page
|
||||
protection do not matter.
|
||||
|
||||
The reason the uninitialized data is placed in this section is
|
||||
that the EFI loader appears to be unable to handle sections
|
||||
that are allocated but not loaded from the binary.
|
||||
|
||||
.dynamic, .dynsym, .rela, .rel, .reloc
|
||||
These sections contains the dynamic information necessary to
|
||||
self-relocate the binary (see below).
|
||||
|
||||
A couple of more points worth noting about the linker script:
|
||||
|
||||
o On IA-64, the global pointer symbol (__gp) needs to be placed such
|
||||
that the _entire_ EFI binary can be addressed using the signed
|
||||
22-bit offset that the "addl" instruction affords. Specifically,
|
||||
this means that __gp should be placed at ImageBase + 0x200000.
|
||||
Strictly speaking, only a couple of symbols need to be addressable
|
||||
in this fashion, so with some care it should be possible to build
|
||||
binaries much larger than 4MB. To get a list of symbols that need
|
||||
to be addressable in this fashion, grep the assembly files in
|
||||
directory gnuefi for the string "@gprel".
|
||||
|
||||
o The link address (ImageBase) of the binary is (arbitrarily) set to
|
||||
zero. This could be set to something larger to increase the chance
|
||||
of EFI being able to load the binary without requiring relocation.
|
||||
However, a start address of 0 makes debugging a wee bit easier
|
||||
(great for those of us who can add, but not subtract... ;-).
|
||||
|
||||
o The relocation related sections (.dynamic, .rel, .rela, .reloc)
|
||||
cannot be placed inside .data because some tools in the GNU
|
||||
toolchain rely on the existence of these sections.
|
||||
|
||||
o Some sections in the ELF binary intentionally get dropped when
|
||||
building the EFI binary. Particularly noteworthy are the dynamic
|
||||
relocation sections for the .plabel and .reloc sections. It would
|
||||
be _wrong_ to include these sections in the EFI binary because it
|
||||
would result in .reloc and .plabel being relocated twice (once by
|
||||
the EFI loader and once by the self-relocator; see below for a
|
||||
description of the latter). Specifically, only the sections
|
||||
mentioned with the -j option in the final "objcopy" command are
|
||||
retained in the EFI binary (see Make.rules).
|
||||
|
||||
|
||||
** (2) Building Relocatable Binaries
|
||||
|
||||
ELF binaries are normally linked for a fixed load address and are thus
|
||||
not relocatable. The only kind of ELF object that is relocatable are
|
||||
shared objects ("shared libraries"). However, even those objects are
|
||||
usually not completely position independent and therefore require
|
||||
runtime relocation by the dynamic loader. For example, IA-64 binaries
|
||||
normally require relocation of the global offset table.
|
||||
|
||||
The approach to building relocatable binaries in the GNU EFI build
|
||||
environment is to:
|
||||
|
||||
(a) build an ELF shared object
|
||||
|
||||
(b) link it together with a self-relocator that takes care of
|
||||
applying the dynamic relocations that may be present in the
|
||||
ELF shared object
|
||||
|
||||
(c) convert the resulting image to an EFI binary
|
||||
|
||||
The self-relocator is of course architecture dependent. The x86
|
||||
version can be found in gnuefi/reloc_ia32.c, the x86_64 version
|
||||
can be found in gnuefi/reloc_x86_64.c and the IA-64 version can be
|
||||
found in gnuefi/reloc_ia64.S.
|
||||
|
||||
The self-relocator operates as follows: the startup code invokes it
|
||||
right after EFI has handed off control to the EFI binary at symbol
|
||||
"_start". Upon activation, the self-relocator searches the .dynamic
|
||||
section (whose starting address is given by symbol _DYNAMIC) for the
|
||||
dynamic relocation information, which can be found in the DT_REL,
|
||||
DT_RELSZ, and DT_RELENT entries of the dynamic table (DT_RELA,
|
||||
DT_RELASZ, and DT_RELAENT in the case of rela relocations, as is the
|
||||
case for IA-64). The dynamic relocation information points to the ELF
|
||||
relocation table. Once this table is found, the self-relocator walks
|
||||
through it, applying each relocation one by one. Since the EFI
|
||||
binaries are fully resolved shared objects, only a subset of all
|
||||
possible relocations need to be supported. Specifically, on x86 only
|
||||
the R_386_RELATIVE relocation is needed. On IA-64, the relocations
|
||||
R_IA64_DIR64LSB, R_IA64_REL64LSB, and R_IA64_FPTR64LSB are needed.
|
||||
Note that the R_IA64_FPTR64LSB relocation requires access to the
|
||||
dynamic symbol table. This is why the .dynsym section is included in
|
||||
the EFI binary. Another complication is that this relocation requires
|
||||
memory to hold the function descriptors (aka "procedure labels" or
|
||||
"plabels"). Each function descriptor uses 16 bytes of memory. The
|
||||
IA-64 self-relocator currently reserves a static memory area that can
|
||||
hold 100 of these descriptors. If the self-relocator runs out of
|
||||
space, it causes the EFI binary to fail with error code 5
|
||||
(EFI_BUFFER_TOO_SMALL). When this happens, the manifest constant
|
||||
MAX_FUNCTION_DESCRIPTORS in gnuefi/reloc_ia64.S should be increased
|
||||
and the application recompiled. An easy way to count the number of
|
||||
function descriptors required by an EFI application is to run the
|
||||
command:
|
||||
|
||||
objdump --dynamic-reloc example.so | fgrep FPTR64 | wc -l
|
||||
|
||||
assuming "example" is the name of the desired EFI application.
|
||||
|
||||
|
||||
** (3) Creating the Function Descriptor for the IA-64 EFI Binaries
|
||||
|
||||
As mentioned above, the IA-64 PE32+ format assumes that the entry
|
||||
point of the binary is a function descriptor. A function descriptors
|
||||
consists of two double words: the first one is the code entry point
|
||||
and the second is the global pointer that should be loaded before
|
||||
calling the entry point. Since the ELF toolchain doesn't know how to
|
||||
generate a function descriptor for the entry point, the startup code
|
||||
in gnuefi/crt0-efi-ia64.S crafts one manually by with the code:
|
||||
|
||||
.section .plabel, "a"
|
||||
_start_plabel:
|
||||
data8 _start
|
||||
data8 __gp
|
||||
|
||||
this places the procedure label for entry point _start in a section
|
||||
called ".plabel". Now, the only problem is that _start and __gp need
|
||||
to be relocated _before_ EFI hands control over to the EFI binary.
|
||||
Fortunately, PE32+ defines a section called ".reloc" that can achieve
|
||||
this. Thus, in addition to manually crafting the function descriptor,
|
||||
the startup code also crafts a ".reloc" section that has will cause
|
||||
the EFI loader to relocate the function descriptor before handing over
|
||||
control to the EFI binary (again, see the PECOFF spec mentioned above
|
||||
for details).
|
||||
|
||||
A final question may be why .plabel and .reloc need to go in their own
|
||||
COFF sections. The answer is simply: we need to be able to discard
|
||||
the relocation entries that are generated for these sections. By
|
||||
placing them in these sections, the relocations end up in sections
|
||||
".rela.plabel" and ".rela.reloc" which makes it easy to filter them
|
||||
out in the filter script. Also, the ".reloc" section needs to be in
|
||||
its own section so that the objcopy program can recognize it and can
|
||||
create the correct directory entries in the PE32+ binary.
|
||||
|
||||
|
||||
** (4) Convenient and Portable Generation of UNICODE String Literals
|
||||
|
||||
As of gnu-efi-3.0, we make use (and somewhat abuse) the gcc option
|
||||
that forces wide characters (WCHAR_T) to use short integers (2 bytes)
|
||||
instead of integers (4 bytes). This way we match the Unicode character
|
||||
size. By abuse, we mean that we rely on the fact that the regular ASCII
|
||||
characters are encoded the same way between (short) wide characters
|
||||
and Unicode and basically only use the first byte. This allows us
|
||||
to just use them interchangeably.
|
||||
|
||||
The gcc option to force short wide characters is : -fshort-wchar
|
||||
|
||||
* * * The End * * *
|
184
gnu-efi/apps/AllocPages.c
Normal file
184
gnu-efi/apps/AllocPages.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) 2013 Jerry Hoemann <jerry.hoemann@hp.com>
|
||||
*
|
||||
*
|
||||
* Application to allocate memory at EFI. Syntax of command
|
||||
* mimics the EFI Boot Service "AllocatePages."
|
||||
*
|
||||
* See UEFI spec 2.3, Section 6.2.
|
||||
*
|
||||
*
|
||||
|
||||
|
||||
|
||||
|
||||
FS1:\> memmap
|
||||
Type Start End #pages Attributes
|
||||
BS_Code 0000000000000000-0000000000000FFF 0000000000000001 000000000000000F
|
||||
Available 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F
|
||||
Reserved 000000000008E000-000000000008FFFF 0000000000000002 000000000000000F
|
||||
Available 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F
|
||||
Available 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F
|
||||
BS_Code 0000000010000000-0000000010061FFF 0000000000000062 000000000000000F
|
||||
Available 0000000010062000-000000005CDFFFFF 000000000004CD9E 000000000000000F
|
||||
ACPI_NVS 000000005CE00000-000000005DDFFFFF 0000000000001000 000000000000000F
|
||||
BS_Data 000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F
|
||||
Available 000000005E000000-000000005EF1CFFF 0000000000000F1D 000000000000000F
|
||||
BS_Data 000000005EF1D000-00000000709FBFFF 0000000000011ADF 000000000000000F
|
||||
Available 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F
|
||||
LoaderCode 00000000710E4000-00000000711FEFFF 000000000000011B 000000000000000F
|
||||
Available 00000000711FF000-0000000071901FFF 0000000000000703 000000000000000F
|
||||
BS_Code 0000000071902000-00000000721FEFFF 00000000000008FD 000000000000000F
|
||||
|
||||
|
||||
Example to allocat 5 pages type BootCode at address 20000000 (hex)
|
||||
|
||||
|
||||
FS1:\> AllocPages.efi 2 3 5 20000000
|
||||
AllocatePage: __AllocType__ __MemType__ __NumPages__ [__Addr__]
|
||||
__AllocType__ {0,1,2} -- Any, MaxAddr, Addr
|
||||
__MemType__ {0..13}, Reserved ==0, LCode==1, LData==2, BSCode==3, BSData==4, ...
|
||||
__NumPages__ {0..F000000}
|
||||
[__Addr__] 0... 3FFFFFFFFFFF
|
||||
All numbers in hex no leading 0x
|
||||
|
||||
AllocatPage(2,3,5,20000000)
|
||||
|
||||
|
||||
Example to allocat 5 pages type BootCode at address 30000000 (hex)
|
||||
|
||||
|
||||
FS1:\> AllocPages.efi 2 3 5 30000000
|
||||
AllocatePage: __AllocType__ __MemType__ __NumPages__ [__Addr__]
|
||||
__AllocType__ {0,1,2} -- Any, MaxAddr, Addr
|
||||
__MemType__ {0..13}, Reserved ==0, LCode==1, LData==2, BSCode==3, BSData==4, ...
|
||||
__NumPages__ {0..F000000}
|
||||
[__Addr__] 0... 3FFFFFFFFFFF
|
||||
All numbers in hex no leading 0x
|
||||
|
||||
|
||||
|
||||
FS1:\> memmap
|
||||
Type Start End #pages Attributes
|
||||
BS_Code 0000000000000000-0000000000000FFF 0000000000000001 000000000000000F
|
||||
Available 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F
|
||||
Reserved 000000000008E000-000000000008FFFF 0000000000000002 000000000000000F
|
||||
Available 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F
|
||||
Available 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F
|
||||
BS_Code 0000000010000000-0000000010061FFF 0000000000000062 000000000000000F
|
||||
Available 0000000010062000-000000001FFFFFFF 000000000000FF9E 000000000000000F
|
||||
BS_Code 0000000020000000-0000000020004FFF 0000000000000005 000000000000000F
|
||||
Available 0000000020005000-000000002FFFFFFF 000000000000FFFB 000000000000000F
|
||||
BS_Code 0000000030000000-0000000030004FFF 0000000000000005 000000000000000F
|
||||
Available 0000000030005000-000000005CDFFFFF 000000000002CDFB 000000000000000F
|
||||
ACPI_NVS 000000005CE00000-000000005DDFFFFF 0000000000001000 000000000000000F
|
||||
BS_Data 000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F
|
||||
Available 000000005E000000-000000005EF1CFFF 0000000000000F1D 000000000000000F
|
||||
BS_Data 000000005EF1D000-00000000709FBFFF 0000000000011ADF 000000000000000F
|
||||
Available 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F
|
||||
LoaderCode 00000000710E4000-00000000711FEFFF 000000000000011B 000000000000000F
|
||||
Available 00000000711FF000-0000000071901FFF 0000000000000703 000000000000000F
|
||||
BS_Code 0000000071902000-00000000721FEFFF 00000000000008FD 000000000000000F
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
|
||||
#define MAX_NUM_PAGES 0x000000000F000000
|
||||
#define MAX_ADDR ((1ULL << 46) - 1)
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef DEBUG
|
||||
#endif
|
||||
#define DEBUG 0
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
|
||||
EFI_STATUS efi_status;
|
||||
CHAR16 **argv;
|
||||
INTN argc;
|
||||
INTN err = 0;
|
||||
#if DEBUG
|
||||
INTN c = 0;
|
||||
#endif
|
||||
INTN AllocType = -1;
|
||||
INTN MemType = -1;
|
||||
INTN NumPages = -1;
|
||||
EFI_PHYSICAL_ADDRESS Addr = 0;
|
||||
|
||||
InitializeLib(image, systab);
|
||||
|
||||
Print(L"AllocatePage: __AllocType__ __MemType__ __NumPages__ [__Addr__]\n");
|
||||
Print(L"__AllocType__ {0,1,2} -- Any, MaxAddr, Addr\n");
|
||||
Print(L"__MemType__ {0..13}, Reserved ==0, LCode==1, LData==2, BSCode==3, BSData==4, ...\n");
|
||||
Print(L"__NumPages__ {0..%x}\n", MAX_NUM_PAGES);
|
||||
Print(L"[__Addr__] 0... %llx\n", MAX_ADDR);
|
||||
Print(L"All numbers in hex no leading 0x\n");
|
||||
Print(L"\n");
|
||||
|
||||
#if DEBUG
|
||||
Print(L"Now get argc/argv\n");
|
||||
#endif
|
||||
argc = GetShellArgcArgv(image, &argv);
|
||||
#if DEBUG
|
||||
Print(L"argc = %d\n", argc);
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
for (c = 0; c < argc; c++ ) {
|
||||
Print(L"argv[%d] = <%s>\n", c, argv[c]);
|
||||
}
|
||||
#endif
|
||||
if ( (argc < 4) || (argc > 5) ) {
|
||||
Print(L"Wrong argument count\n");
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
AllocType = xtoi(argv[1]);
|
||||
MemType = xtoi(argv[2]);
|
||||
NumPages = xtoi(argv[3]);
|
||||
if ( argc == 5 ) Addr = xtoi(argv[4]);
|
||||
|
||||
if ( (AllocType < 0) || (AllocType > 2)) {
|
||||
Print(L"Invalid AllocType\n");
|
||||
err++;
|
||||
}
|
||||
if ( (MemType < 0) || (MemType > 13) ) {
|
||||
Print(L"Invalid MemType\n");
|
||||
err++;
|
||||
}
|
||||
if ( (NumPages < 0) || (NumPages > MAX_NUM_PAGES) ) {
|
||||
Print(L"Inavlid NumPages\n");
|
||||
err++;
|
||||
}
|
||||
if ( Addr > MAX_ADDR ) {
|
||||
Print(L"Inavlid Address\n");
|
||||
err++;
|
||||
}
|
||||
if ( err ) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Print(L"AllocatPage(%d,%d,%d,%lx)\n", AllocType, MemType, NumPages, Addr);
|
||||
|
||||
efi_status = uefi_call_wrapper(BS->AllocatePages, 4, AllocType, MemType, NumPages, &Addr);
|
||||
|
||||
if ( EFI_ERROR(efi_status) ) {
|
||||
Print(L"Allocate Pages Failed: %d\n", efi_status);
|
||||
return efi_status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
145
gnu-efi/apps/FreePages.c
Normal file
145
gnu-efi/apps/FreePages.c
Normal file
|
@ -0,0 +1,145 @@
|
|||
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Jerry Hoemann <jerry.hoemann@hp.com>
|
||||
*
|
||||
* Application to allocate memory at EFI. Syntax of command
|
||||
* mimics the EFI Boot Service "FreePages."
|
||||
*
|
||||
* See UEFI spec 2.3, Section 6.2.
|
||||
*
|
||||
|
||||
Example freeing a 5 page BS_Code setment at address: 0000000020000000 (hex)
|
||||
|
||||
|
||||
FS1:\> memmap
|
||||
Type Start End #pages Attributes
|
||||
BS_Code 0000000000000000-0000000000000FFF 0000000000000001 000000000000000F
|
||||
Available 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F
|
||||
Reserved 000000000008E000-000000000008FFFF 0000000000000002 000000000000000F
|
||||
Available 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F
|
||||
Available 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F
|
||||
BS_Code 0000000010000000-0000000010061FFF 0000000000000062 000000000000000F
|
||||
Available 0000000010062000-000000001FFFFFFF 000000000000FF9E 000000000000000F
|
||||
BS_Code 0000000020000000-0000000020004FFF 0000000000000005 000000000000000F
|
||||
Available 0000000020005000-000000005DDFFFFF 000000000003DDFB 000000000000000F
|
||||
BS_Data 000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F
|
||||
Available 000000005E000000-000000006DE7CFFF 000000000000FE7D 000000000000000F
|
||||
ACPI_NVS 000000006DE7D000-000000006EE7CFFF 0000000000001000 000000000000000F
|
||||
BS_Data 000000006EE7D000-00000000709FBFFF 0000000000001B7F 000000000000000F
|
||||
Available 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F
|
||||
|
||||
|
||||
FS1:\> FreePages 0000000020000000 5
|
||||
FreePages: __PhysAddr__ __PgCnt__
|
||||
__PhysAddr__ 0... 3FFFFFFFFFFF
|
||||
__PgCnt__ [0..F000000]
|
||||
All numbers hex w/ no leading 0x
|
||||
|
||||
FreePages(20000000,5)
|
||||
|
||||
|
||||
|
||||
FS1:\> memmap
|
||||
Type Start End #pages Attributes
|
||||
BS_Code 0000000000000000-0000000000000FFF 0000000000000001 000000000000000F
|
||||
Available 0000000000001000-000000000008DFFF 000000000000008D 000000000000000F
|
||||
Reserved 000000000008E000-000000000008FFFF 0000000000000002 000000000000000F
|
||||
Available 0000000000090000-000000000009FFFF 0000000000000010 000000000000000F
|
||||
Available 0000000000100000-000000000FFFFFFF 000000000000FF00 000000000000000F
|
||||
BS_Code 0000000010000000-0000000010061FFF 0000000000000062 000000000000000F
|
||||
Available 0000000010062000-000000005DDFFFFF 000000000004DD9E 000000000000000F
|
||||
BS_Data 000000005DE00000-000000005DFFFFFF 0000000000000200 000000000000000F
|
||||
Available 000000005E000000-000000006DE7CFFF 000000000000FE7D 000000000000000F
|
||||
ACPI_NVS 000000006DE7D000-000000006EE7CFFF 0000000000001000 000000000000000F
|
||||
BS_Data 000000006EE7D000-00000000709FBFFF 0000000000001B7F 000000000000000F
|
||||
Available 00000000709FC000-00000000710E3FFF 00000000000006E8 000000000000000F
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
/*
|
||||
* FreePages: __PhysAddr__ __PgCnt__
|
||||
*
|
||||
*/
|
||||
|
||||
#define MAX_NUM_PAGES 0x000000000F000000
|
||||
|
||||
#define MAX_ADDR ((1ULL << 46) - 1)
|
||||
|
||||
#ifdef DEBUG
|
||||
#undef DEBUG
|
||||
#endif
|
||||
#define DEBUG 0
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
|
||||
EFI_STATUS efi_status;
|
||||
CHAR16 **argv;
|
||||
INTN argc = 0;
|
||||
#if DEBUG
|
||||
INTN c = 0;
|
||||
#endif
|
||||
INTN err = 0;
|
||||
|
||||
INTN PgCnt = -1;
|
||||
EFI_PHYSICAL_ADDRESS PhysAddr = 0;
|
||||
|
||||
InitializeLib(image, systab);
|
||||
|
||||
Print(L"FreePages: __PhysAddr__ __PgCnt__\n");
|
||||
Print(L"__PhysAddr__ 0... %llx\n", MAX_ADDR);
|
||||
Print(L"__PgCnt__ [0..%lx]\n", MAX_NUM_PAGES);
|
||||
Print(L"All numbers hex w/ no leading 0x\n");
|
||||
Print(L"\n");
|
||||
|
||||
#if DEBUG
|
||||
Print(L"Now parse argc/argv\n");
|
||||
#endif
|
||||
argc = GetShellArgcArgv(image, &argv);
|
||||
#if DEBUG
|
||||
Print(L"argc = %d\n", argc);
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
for (c = 0; c < argc; c++ ) {
|
||||
Print(L"argv[%d] = <%s>\n", c, argv[c]);
|
||||
}
|
||||
#endif
|
||||
if (argc != 3) {
|
||||
Print(L"Invalid argument count\n");
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
PhysAddr = xtoi(argv[1]);
|
||||
PgCnt = xtoi(argv[2]);
|
||||
|
||||
if ( (PgCnt < 0) || (PgCnt > MAX_NUM_PAGES) ) {
|
||||
Print(L"Inavlid PgCnt\n");
|
||||
err++;
|
||||
}
|
||||
if ( PhysAddr > MAX_ADDR ) {
|
||||
Print(L"Inavlid Address\n");
|
||||
err++;
|
||||
}
|
||||
if ( err ) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Print(L"FreePages(%lx,%d)\n", PhysAddr, PgCnt);
|
||||
|
||||
efi_status = uefi_call_wrapper(BS->FreePages, 2, PhysAddr, PgCnt);
|
||||
|
||||
if ( EFI_ERROR(efi_status) ) {
|
||||
Print(L"Free Pages Failed: %d\n", efi_status);
|
||||
return efi_status;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
95
gnu-efi/apps/Makefile
Normal file
95
gnu-efi/apps/Makefile
Normal file
|
@ -0,0 +1,95 @@
|
|||
#
|
||||
# Copyright (C) 1999-2001 Hewlett-Packard Co.
|
||||
# Contributed by David Mosberger <davidm@hpl.hp.com>
|
||||
# Contributed by Stephane Eranian <eranian@hpl.hp.com>
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
# * Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
|
||||
SRCDIR = .
|
||||
|
||||
VPATH = $(SRCDIR)
|
||||
|
||||
include $(SRCDIR)/../Make.defaults
|
||||
|
||||
TOPDIR = $(SRCDIR)/..
|
||||
|
||||
CDIR=$(TOPDIR)/..
|
||||
LINUX_HEADERS = /usr/src/sys/build
|
||||
CPPFLAGS += -D__KERNEL__ -I$(LINUX_HEADERS)/include
|
||||
CRTOBJS = ../gnuefi/crt0-efi-$(ARCH).o
|
||||
|
||||
LDSCRIPT = $(TOPDIR)/gnuefi/elf_$(ARCH)_efi.lds
|
||||
ifneq (,$(findstring FreeBSD,$(OS)))
|
||||
LDSCRIPT = $(TOPDIR)/gnuefi/elf_$(ARCH)_fbsd_efi.lds
|
||||
endif
|
||||
|
||||
LDFLAGS += -shared -Bsymbolic -L../lib -L../gnuefi $(CRTOBJS)
|
||||
|
||||
LOADLIBES += -lefi -lgnuefi
|
||||
LOADLIBES += $(LIBGCC)
|
||||
LOADLIBES += -T $(LDSCRIPT)
|
||||
|
||||
TARGET_APPS = t.efi t2.efi t3.efi t4.efi t5.efi t6.efi \
|
||||
printenv.efi t7.efi t8.efi tcc.efi modelist.efi \
|
||||
route80h.efi drv0_use.efi AllocPages.efi exit.efi \
|
||||
FreePages.efi setjmp.efi debughook.efi debughook.efi.debug \
|
||||
bltgrid.efi lfbgrid.efi setdbg.efi unsetdbg.efi
|
||||
TARGET_BSDRIVERS = drv0.efi
|
||||
TARGET_RTDRIVERS =
|
||||
|
||||
ifneq ($(HAVE_EFI_OBJCOPY),)
|
||||
|
||||
FORMAT := --target efi-app-$(ARCH)
|
||||
$(TARGET_BSDRIVERS): FORMAT=--target efi-bsdrv-$(ARCH)
|
||||
$(TARGET_RTDRIVERS): FORMAT=--target efi-rtdrv-$(ARCH)
|
||||
|
||||
else
|
||||
|
||||
SUBSYSTEM := 0xa
|
||||
$(TARGET_BSDRIVERS): SUBSYSTEM = 0xb
|
||||
$(TARGET_RTDRIVERS): SUBSYSTEM = 0xc
|
||||
|
||||
FORMAT := -O binary
|
||||
LDFLAGS += --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
|
||||
|
||||
endif
|
||||
|
||||
TARGETS = $(TARGET_APPS) $(TARGET_BSDRIVERS) $(TARGET_RTDRIVERS)
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS) *~ *.o *.so
|
||||
|
||||
.PHONY: install
|
||||
|
||||
include $(SRCDIR)/../Make.rules
|
131
gnu-efi/apps/bltgrid.c
Normal file
131
gnu-efi/apps/bltgrid.c
Normal file
|
@ -0,0 +1,131 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
extern EFI_GUID GraphicsOutputProtocol;
|
||||
|
||||
static void
|
||||
fill_boxes(UINT32 *PixelBuffer, UINT32 Width, UINT32 Height)
|
||||
{
|
||||
UINT32 y, x = 0;
|
||||
/*
|
||||
* This assums BGRR, but it doesn't really matter; we pick red and
|
||||
* green so it'll just be blue/green if the pixel format is backwards.
|
||||
*/
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Red = {0, 0, 0xff, 0},
|
||||
Green = {0, 0xff, 0, 0},
|
||||
*Color;
|
||||
|
||||
for (y = 0; y < Height; y++) {
|
||||
Color = ((y / 32) % 2 == 0) ? &Red : &Green;
|
||||
for (x = 0; x < Width; x++) {
|
||||
if (x % 32 == 0 && x != 0)
|
||||
Color = (Color == &Red) ? &Green : &Red;
|
||||
PixelBuffer[y * Width + x] = *(UINT32 *)Color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_boxes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
|
||||
{
|
||||
int i, imax;
|
||||
EFI_STATUS rc;
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
|
||||
UINTN NumPixels;
|
||||
UINT32 *PixelBuffer;
|
||||
UINT32 BufferSize;
|
||||
|
||||
if (gop->Mode) {
|
||||
imax = gop->Mode->MaxMode;
|
||||
} else {
|
||||
Print(L"gop->Mode is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < imax; i++) {
|
||||
UINTN SizeOfInfo;
|
||||
rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i, &SizeOfInfo,
|
||||
&info);
|
||||
if (EFI_ERROR(rc) && rc == EFI_NOT_STARTED) {
|
||||
Print(L"gop->QueryMode() returned %r\n", rc);
|
||||
Print(L"Trying to start GOP with SetMode().\n");
|
||||
rc = uefi_call_wrapper(gop->SetMode, 2, gop,
|
||||
gop->Mode ? gop->Mode->Mode : 0);
|
||||
rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i,
|
||||
&SizeOfInfo, &info);
|
||||
}
|
||||
|
||||
if (EFI_ERROR(rc)) {
|
||||
Print(L"%d: Bad response from QueryMode: %r (%d)\n",
|
||||
i, rc, rc);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CompareMem(info, gop->Mode->Info, sizeof (*info)))
|
||||
continue;
|
||||
|
||||
NumPixels = info->VerticalResolution * info->HorizontalResolution;
|
||||
BufferSize = NumPixels * sizeof(UINT32);
|
||||
|
||||
PixelBuffer = AllocatePool(BufferSize);
|
||||
if (!PixelBuffer) {
|
||||
Print(L"Allocation of 0x%08lx bytes failed.\n",
|
||||
sizeof(UINT32) * NumPixels);
|
||||
return;
|
||||
}
|
||||
|
||||
fill_boxes(PixelBuffer,
|
||||
info->HorizontalResolution, info->VerticalResolution);
|
||||
|
||||
uefi_call_wrapper(gop->Blt, 10, gop,
|
||||
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)PixelBuffer,
|
||||
EfiBltBufferToVideo,
|
||||
0, 0, 0, 0,
|
||||
info->HorizontalResolution,
|
||||
info->VerticalResolution,
|
||||
0);
|
||||
return;
|
||||
}
|
||||
Print(L"Never found the active video mode?\n");
|
||||
}
|
||||
|
||||
static EFI_STATUS
|
||||
SetWatchdog(UINTN seconds)
|
||||
{
|
||||
EFI_STATUS rc;
|
||||
rc = uefi_call_wrapper(BS->SetWatchdogTimer, 4, seconds, 0x1ffff,
|
||||
0, NULL);
|
||||
if (EFI_ERROR(rc)) {
|
||||
CHAR16 Buffer[64];
|
||||
StatusToString(Buffer, rc);
|
||||
Print(L"Bad response from QueryMode: %s (%d)\n", Buffer, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_STATUS rc;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
|
||||
|
||||
InitializeLib(image_handle, systab);
|
||||
|
||||
SetWatchdog(10);
|
||||
|
||||
rc = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&gop);
|
||||
if (EFI_ERROR(rc)) {
|
||||
Print(L"Could not locate GOP: %r\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!gop) {
|
||||
Print(L"LocateProtocol(GOP, &gop) returned %r but GOP is NULL\n", rc);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
draw_boxes(gop);
|
||||
|
||||
SetWatchdog(0);
|
||||
return EFI_SUCCESS;
|
||||
}
|
97
gnu-efi/apps/debughook.c
Normal file
97
gnu-efi/apps/debughook.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
GetVariableAttr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner,
|
||||
UINT32 *attributes)
|
||||
{
|
||||
EFI_STATUS efi_status;
|
||||
|
||||
*len = 0;
|
||||
|
||||
efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
|
||||
NULL, len, NULL);
|
||||
if (efi_status != EFI_BUFFER_TOO_SMALL)
|
||||
return efi_status;
|
||||
|
||||
*data = AllocateZeroPool(*len);
|
||||
if (!*data)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
efi_status = uefi_call_wrapper(RT->GetVariable, 5, var, &owner,
|
||||
attributes, len, *data);
|
||||
|
||||
if (efi_status != EFI_SUCCESS) {
|
||||
FreePool(*data);
|
||||
*data = NULL;
|
||||
}
|
||||
return efi_status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
GetVariable(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner)
|
||||
{
|
||||
return GetVariableAttr(var, data, len, owner, NULL);
|
||||
}
|
||||
|
||||
EFI_GUID DUMMY_GUID =
|
||||
{0x55aad538, 0x8f82, 0x4e2a, {0xa4,0xf0,0xbe, 0x59, 0x13, 0xb6, 0x5f, 0x1e}};
|
||||
|
||||
#if defined(__clang__)
|
||||
# define _OPTNONE __attribute__((optnone))
|
||||
#else
|
||||
# define _OPTNONE __attribute__((__optimize__("0")))
|
||||
#endif
|
||||
|
||||
static _OPTNONE void
|
||||
DebugHook(void)
|
||||
{
|
||||
EFI_GUID guid = DUMMY_GUID;
|
||||
UINT8 *data = NULL;
|
||||
UINTN dataSize = 0;
|
||||
EFI_STATUS efi_status;
|
||||
register volatile unsigned long long x = 0;
|
||||
extern char _text, _data;
|
||||
|
||||
if (x)
|
||||
return;
|
||||
|
||||
efi_status = GetVariable(L"DUMMY_DEBUG", &data, &dataSize, guid);
|
||||
if (EFI_ERROR(efi_status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Print(L"add-symbol-file /usr/lib/debug/boot/efi/debughook.debug "
|
||||
L"0x%08x -s .data 0x%08x\n", &_text, &_data);
|
||||
|
||||
Print(L"Pausing for debugger attachment.\n");
|
||||
Print(L"To disable this, remove the EFI variable DUMMY_DEBUG-%g .\n",
|
||||
&guid);
|
||||
x = 1;
|
||||
while (x++) {
|
||||
/* Make this so it can't /totally/ DoS us. */
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__i686__)
|
||||
if (x > 4294967294ULL)
|
||||
break;
|
||||
__asm__ __volatile__("pause");
|
||||
#elif defined(__aarch64__)
|
||||
if (x > 1000)
|
||||
break;
|
||||
__asm__ __volatile__("wfi");
|
||||
#else
|
||||
if (x > 12000)
|
||||
break;
|
||||
uefi_call_wrapper(BS->Stall, 1, 5000);
|
||||
#endif
|
||||
}
|
||||
x = 1;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
InitializeLib(image, systab);
|
||||
DebugHook();
|
||||
return EFI_SUCCESS;
|
||||
}
|
191
gnu-efi/apps/drv0.c
Normal file
191
gnu-efi/apps/drv0.c
Normal file
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright (C) 2013 David Decotigny <decot@googlers.com>
|
||||
*
|
||||
* Sample EFI shell session, together with drv0_use.efi:
|
||||
*
|
||||
* # Loading first instance:
|
||||
*
|
||||
* fs0:\> load drv0.efi
|
||||
* Driver instance loaded successfully.
|
||||
* load: Image fs0:\drv0.efi loaded at 2FD7C000 - Success
|
||||
*
|
||||
* # Testing 1st instance:
|
||||
*
|
||||
* fs0:\> drv0_use.efi
|
||||
* Playing with driver instance 0...
|
||||
* Hello Sample UEFI Driver!
|
||||
* Hello was called 1 time(s).
|
||||
*
|
||||
* fs0:\> drv0_use.efi
|
||||
* Playing with driver instance 0...
|
||||
* Hello Sample UEFI Driver!
|
||||
* Hello was called 2 time(s).
|
||||
*
|
||||
* # Loading another instance:
|
||||
*
|
||||
* fs0:\> load drv0.efi
|
||||
* Driver instance loaded successfully.
|
||||
* load: Image fs0:\drv0.efi loaded at 2FD6D000 - Success
|
||||
*
|
||||
* # Using both instances:
|
||||
*
|
||||
* fs0:\> drv0_use.efi
|
||||
* Playing with driver instance 0...
|
||||
* Hello Sample UEFI Driver!
|
||||
* Hello was called 3 time(s).
|
||||
* Playing with driver instance 1...
|
||||
* Hello Sample UEFI Driver!
|
||||
* Hello was called 1 time(s).
|
||||
*
|
||||
* fs0:\> drv0_use.efi
|
||||
* Playing with driver instance 0...
|
||||
* Hello Sample UEFI Driver!
|
||||
* Hello was called 4 time(s).
|
||||
* Playing with driver instance 1...
|
||||
* Hello Sample UEFI Driver!
|
||||
* Hello was called 2 time(s).
|
||||
*
|
||||
* # Removing 1st instance:
|
||||
*
|
||||
* fs0:\> dh
|
||||
* Handle dump
|
||||
* 1: Image(DxeCore)
|
||||
* [...]
|
||||
* 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
|
||||
* 7A: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
|
||||
*
|
||||
* fs0:\> unload 79
|
||||
* 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
|
||||
* Unload driver image (y/n)? y
|
||||
* Driver instance unloaded.
|
||||
* unload: Success
|
||||
*
|
||||
* # Only 2nd instance remaining:
|
||||
*
|
||||
* fs0:\> drv0_use.efi
|
||||
* Playing with driver instance 0...
|
||||
* Hello Sample UEFI Driver!
|
||||
* Hello was called 3 time(s).
|
||||
*
|
||||
* # Removing 2nd/last instance:
|
||||
*
|
||||
* fs0:\> dh
|
||||
* Handle dump
|
||||
* 1: Image(DxeCore)
|
||||
* [...]
|
||||
* 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
|
||||
*
|
||||
* fs0:\> unload 79
|
||||
* 79: Image(\/drv0.efi) ImageDevPath (..A,0x800,0x17F7DF)/\/drv0.efi)
|
||||
* Unload driver image (y/n)? y
|
||||
* Driver instance unloaded.
|
||||
* unload: Success
|
||||
*
|
||||
* # Expect error: no other drv0 instance left
|
||||
*
|
||||
* fs0:\> drv0_use.efi
|
||||
* Error looking up handles for proto: 14
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include "drv0.h"
|
||||
|
||||
|
||||
static const EFI_GUID GnuEfiAppsDrv0ProtocolGuid
|
||||
= GNU_EFI_APPS_DRV0_PROTOCOL_GUID;
|
||||
|
||||
static struct {
|
||||
GNU_EFI_APPS_DRV0_PROTOCOL Proto;
|
||||
UINTN Counter;
|
||||
} InternalGnuEfiAppsDrv0ProtocolData;
|
||||
|
||||
|
||||
static
|
||||
EFI_STATUS
|
||||
EFI_FUNCTION
|
||||
Drv0SayHello(
|
||||
IN const CHAR16 *HelloWho
|
||||
)
|
||||
{
|
||||
if (! HelloWho)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
Print(L"Hello %s!\n", HelloWho);
|
||||
InternalGnuEfiAppsDrv0ProtocolData.Counter ++;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
EFI_STATUS
|
||||
EFI_FUNCTION
|
||||
Drv0GetNumberOfHello(
|
||||
OUT UINTN *NumberOfHello
|
||||
)
|
||||
{
|
||||
if (! NumberOfHello)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
*NumberOfHello = InternalGnuEfiAppsDrv0ProtocolData.Counter;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
EFI_STATUS
|
||||
EFI_FUNCTION
|
||||
Drv0Unload(IN EFI_HANDLE ImageHandle)
|
||||
{
|
||||
LibUninstallProtocolInterfaces(ImageHandle,
|
||||
&GnuEfiAppsDrv0ProtocolGuid,
|
||||
&InternalGnuEfiAppsDrv0ProtocolData.Proto,
|
||||
NULL);
|
||||
Print(L"Driver instance unloaded.\n", ImageHandle);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SysTab)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_LOADED_IMAGE *LoadedImage = NULL;
|
||||
|
||||
InitializeLib(ImageHandle, SysTab);
|
||||
|
||||
/* Initialize global protocol definition + data */
|
||||
InternalGnuEfiAppsDrv0ProtocolData.Proto.SayHello
|
||||
= (GNU_EFI_APPS_DRV0_SAY_HELLO) Drv0SayHello;
|
||||
InternalGnuEfiAppsDrv0ProtocolData.Proto.GetNumberOfHello
|
||||
= (GNU_EFI_APPS_DRV0_GET_NUMBER_OF_HELLO) Drv0GetNumberOfHello;
|
||||
InternalGnuEfiAppsDrv0ProtocolData.Counter = 0;
|
||||
|
||||
/* Grab handle to this image: we'll attach our proto instance to it */
|
||||
Status = uefi_call_wrapper(BS->OpenProtocol, 6,
|
||||
ImageHandle, &LoadedImageProtocol,
|
||||
(void**)&LoadedImage, ImageHandle,
|
||||
NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(Status)) {
|
||||
Print(L"Could not open loaded image protocol: %d\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Attach our proto to the current driver image */
|
||||
Status = LibInstallProtocolInterfaces(
|
||||
&ImageHandle, &GnuEfiAppsDrv0ProtocolGuid,
|
||||
&InternalGnuEfiAppsDrv0ProtocolData.Proto, NULL);
|
||||
if (EFI_ERROR(Status)) {
|
||||
Print(L"Error registering driver instance: %d\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Register Unload callback, used to unregister current protocol
|
||||
* instance from system */
|
||||
LoadedImage->Unload = (EFI_IMAGE_UNLOAD)Drv0Unload;
|
||||
|
||||
Print(L"Driver instance loaded successfully.\n");
|
||||
return EFI_SUCCESS; /* at this point, this instance stays resident
|
||||
* until image is unloaded, eg. with shell's unload,
|
||||
* ExitBootServices() */
|
||||
}
|
35
gnu-efi/apps/drv0.h
Normal file
35
gnu-efi/apps/drv0.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef _GNU_EFI_APPS_DRV0_H_
|
||||
#define _GNU_EFI_APPS_DRV0_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* UEFI naming conventions */
|
||||
#define GNU_EFI_APPS_DRV0_PROTOCOL_GUID \
|
||||
{ 0xe4dcafd0, 0x586c, 0x4b3d, {0x86, 0xe7, 0x28, 0xde, 0x7f, 0xcc, 0x04, 0xb9} }
|
||||
|
||||
INTERFACE_DECL(_GNU_EFI_APPS_DRV0_PROTOCOL);
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *GNU_EFI_APPS_DRV0_SAY_HELLO) (
|
||||
IN const CHAR16 *HelloWho
|
||||
);
|
||||
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *GNU_EFI_APPS_DRV0_GET_NUMBER_OF_HELLO) (
|
||||
OUT UINTN *NumberOfHello
|
||||
);
|
||||
|
||||
typedef struct _GNU_EFI_APPS_DRV0_PROTOCOL {
|
||||
GNU_EFI_APPS_DRV0_SAY_HELLO SayHello;
|
||||
GNU_EFI_APPS_DRV0_GET_NUMBER_OF_HELLO GetNumberOfHello;
|
||||
} GNU_EFI_APPS_DRV0_PROTOCOL;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
79
gnu-efi/apps/drv0_use.c
Normal file
79
gnu-efi/apps/drv0_use.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (C) 2013 David Decotigny <decot@googlers.com>
|
||||
*
|
||||
* See drv0.c for an example session.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include "drv0.h"
|
||||
|
||||
|
||||
static EFI_GUID GnuEfiAppsDrv0ProtocolGuid
|
||||
= GNU_EFI_APPS_DRV0_PROTOCOL_GUID;
|
||||
|
||||
|
||||
static
|
||||
EFI_STATUS
|
||||
PlayWithGnuEfiAppsDrv0Protocol(IN EFI_HANDLE DrvHandle) {
|
||||
EFI_STATUS Status;
|
||||
GNU_EFI_APPS_DRV0_PROTOCOL *drv = NULL;
|
||||
UINTN NumberOfHello = 0;
|
||||
|
||||
Status = uefi_call_wrapper(BS->OpenProtocol, 6,
|
||||
DrvHandle,
|
||||
&GnuEfiAppsDrv0ProtocolGuid,
|
||||
(void**)&drv,
|
||||
DrvHandle,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(Status)) {
|
||||
Print(L"Cannot open proto: %d\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = uefi_call_wrapper(drv->SayHello, 2, L"Sample UEFI Driver");
|
||||
if (EFI_ERROR(Status)) {
|
||||
Print(L"Cannot call SayHello: %d\n", Status);
|
||||
}
|
||||
|
||||
Status = uefi_call_wrapper(drv->GetNumberOfHello, 2, &NumberOfHello);
|
||||
if (EFI_ERROR(Status)) {
|
||||
Print(L"Cannot call GetNumberOfHello: %d\n", Status);
|
||||
} else {
|
||||
Print(L"Hello was called %d time(s).\n", NumberOfHello);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE Image, EFI_SYSTEM_TABLE *SysTab)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *Handles = NULL;
|
||||
UINTN i, NoHandles = 0;
|
||||
|
||||
InitializeLib(Image, SysTab);
|
||||
|
||||
Status = LibLocateHandle(ByProtocol, &GnuEfiAppsDrv0ProtocolGuid,
|
||||
NULL, &NoHandles, &Handles);
|
||||
if (EFI_ERROR(Status)) {
|
||||
Print(L"Error looking up handles for proto: %d\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < NoHandles ; ++i)
|
||||
{
|
||||
Print(L"Playing with driver instance %d...\n", i);
|
||||
Status = PlayWithGnuEfiAppsDrv0Protocol(Handles[i]);
|
||||
if (EFI_ERROR(Status))
|
||||
Print(L"Error playing with instance %d, skipping\n", i);
|
||||
}
|
||||
|
||||
if (Handles)
|
||||
FreePool(Handles);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
12
gnu-efi/apps/exit.c
Normal file
12
gnu-efi/apps/exit.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
InitializeLib(image_handle, systab);
|
||||
|
||||
Exit(EFI_SUCCESS, 0, NULL);
|
||||
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
170
gnu-efi/apps/lfbgrid.c
Normal file
170
gnu-efi/apps/lfbgrid.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
extern EFI_GUID GraphicsOutputProtocol;
|
||||
|
||||
#define be32_to_cpu(x) __builtin_bswap32(x)
|
||||
|
||||
static void
|
||||
fill_boxes(UINT32 *PixelBuffer, UINT32 Width, UINT32 Height, UINT32 Pitch,
|
||||
EFI_GRAPHICS_PIXEL_FORMAT Format, EFI_PIXEL_BITMASK Info )
|
||||
{
|
||||
UINT32 Red, Green;
|
||||
UINT32 y, x, color;
|
||||
|
||||
switch(Format) {
|
||||
case PixelRedGreenBlueReserved8BitPerColor:
|
||||
Red = be32_to_cpu(0xff000000);
|
||||
Green = be32_to_cpu(0x00ff0000);
|
||||
break;
|
||||
case PixelBlueGreenRedReserved8BitPerColor:
|
||||
Red = be32_to_cpu(0x0000ff00);
|
||||
Green = be32_to_cpu(0x00ff0000);
|
||||
break;
|
||||
case PixelBitMask:
|
||||
Red = Info.RedMask;
|
||||
Green = Info.GreenMask;
|
||||
break;
|
||||
case PixelBltOnly:
|
||||
return;
|
||||
default:
|
||||
Print(L"Invalid pixel format\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (y = 0; y < Height; y++) {
|
||||
color = ((y / 32) % 2 == 0) ? Red : Green;
|
||||
for (x = 0; x < Width; x++) {
|
||||
if (x % 32 == 0 && x != 0)
|
||||
color = (color == Red) ? Green : Red;
|
||||
PixelBuffer[y * Pitch + x] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_boxes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
|
||||
{
|
||||
int i, imax;
|
||||
EFI_STATUS rc;
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
|
||||
UINTN NumPixels;
|
||||
UINT32 *PixelBuffer;
|
||||
UINT32 CopySize, BufferSize;
|
||||
#if defined(__x86_64__) || defined(__aarch64__)
|
||||
UINT64 FrameBufferAddr;
|
||||
#elif defined(__i386__) || defined(__arm__)
|
||||
UINT32 FrameBufferAddr;
|
||||
#else
|
||||
#error YOUR ARCH HERE
|
||||
#endif
|
||||
|
||||
if (gop->Mode) {
|
||||
imax = gop->Mode->MaxMode;
|
||||
} else {
|
||||
Print(L"gop->Mode is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < imax; i++) {
|
||||
UINTN SizeOfInfo;
|
||||
rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i, &SizeOfInfo,
|
||||
&info);
|
||||
if (EFI_ERROR(rc) && rc == EFI_NOT_STARTED) {
|
||||
Print(L"gop->QueryMode() returned %r\n", rc);
|
||||
Print(L"Trying to start GOP with SetMode().\n");
|
||||
rc = uefi_call_wrapper(gop->SetMode, 2, gop,
|
||||
gop->Mode ? gop->Mode->Mode : 0);
|
||||
rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i,
|
||||
&SizeOfInfo, &info);
|
||||
}
|
||||
|
||||
if (EFI_ERROR(rc)) {
|
||||
Print(L"%d: Bad response from QueryMode: %r (%d)\n",
|
||||
i, rc, rc);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CompareMem(info, gop->Mode->Info, sizeof (*info)))
|
||||
continue;
|
||||
|
||||
NumPixels = info->VerticalResolution * info->PixelsPerScanLine;
|
||||
BufferSize = NumPixels * sizeof(UINT32);
|
||||
if (BufferSize == gop->Mode->FrameBufferSize) {
|
||||
CopySize = BufferSize;
|
||||
} else {
|
||||
CopySize = BufferSize < gop->Mode->FrameBufferSize ?
|
||||
BufferSize : gop->Mode->FrameBufferSize;
|
||||
Print(L"height * pitch * pixelsize = %lu buf fb size is %lu; using %lu\n",
|
||||
BufferSize, gop->Mode->FrameBufferSize, CopySize);
|
||||
}
|
||||
|
||||
PixelBuffer = AllocatePool(BufferSize);
|
||||
if (!PixelBuffer) {
|
||||
Print(L"Allocation of 0x%08lx bytes failed.\n",
|
||||
sizeof(UINT32) * NumPixels);
|
||||
return;
|
||||
}
|
||||
|
||||
fill_boxes(PixelBuffer, info->HorizontalResolution,
|
||||
info->VerticalResolution, info->PixelsPerScanLine,
|
||||
info->PixelFormat, info->PixelInformation);
|
||||
|
||||
if (info->PixelFormat == PixelBltOnly) {
|
||||
Print(L"No linear framebuffer on this device.\n");
|
||||
return;
|
||||
}
|
||||
#if defined(__x86_64__) || defined(__aarch64__)
|
||||
FrameBufferAddr = (UINT64)gop->Mode->FrameBufferBase;
|
||||
#elif defined(__i386__) || defined(__arm__)
|
||||
FrameBufferAddr = (UINT32)(UINT64)gop->Mode->FrameBufferBase;
|
||||
#else
|
||||
#error YOUR ARCH HERE
|
||||
#endif
|
||||
|
||||
CopyMem((VOID *)FrameBufferAddr, PixelBuffer, CopySize);
|
||||
return;
|
||||
}
|
||||
Print(L"Never found the active video mode?\n");
|
||||
}
|
||||
|
||||
static EFI_STATUS
|
||||
SetWatchdog(UINTN seconds)
|
||||
{
|
||||
EFI_STATUS rc;
|
||||
rc = uefi_call_wrapper(BS->SetWatchdogTimer, 4, seconds, 0x1ffff,
|
||||
0, NULL);
|
||||
if (EFI_ERROR(rc)) {
|
||||
CHAR16 Buffer[64];
|
||||
StatusToString(Buffer, rc);
|
||||
Print(L"Bad response from QueryMode: %s (%d)\n", Buffer, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_STATUS rc;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
|
||||
|
||||
InitializeLib(image_handle, systab);
|
||||
|
||||
SetWatchdog(10);
|
||||
|
||||
rc = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&gop);
|
||||
if (EFI_ERROR(rc)) {
|
||||
Print(L"Could not locate GOP: %r\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!gop) {
|
||||
Print(L"LocateProtocol(GOP, &gop) returned %r but GOP is NULL\n", rc);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
draw_boxes(gop);
|
||||
|
||||
SetWatchdog(0);
|
||||
return EFI_SUCCESS;
|
||||
}
|
108
gnu-efi/apps/modelist.c
Normal file
108
gnu-efi/apps/modelist.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
extern EFI_GUID GraphicsOutputProtocol;
|
||||
|
||||
static void
|
||||
print_modes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
|
||||
{
|
||||
int i, imax;
|
||||
EFI_STATUS rc;
|
||||
|
||||
if (gop->Mode) {
|
||||
imax = gop->Mode->MaxMode;
|
||||
Print(L"GOP reports MaxMode %d\n", imax);
|
||||
} else {
|
||||
Print(L"gop->Mode is NULL\n");
|
||||
imax = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < imax; i++) {
|
||||
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
|
||||
UINTN SizeOfInfo;
|
||||
rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i, &SizeOfInfo,
|
||||
&info);
|
||||
if (EFI_ERROR(rc) && rc == EFI_NOT_STARTED) {
|
||||
Print(L"gop->QueryMode() returned %r\n", rc);
|
||||
Print(L"Trying to start GOP with SetMode().\n");
|
||||
rc = uefi_call_wrapper(gop->SetMode, 2, gop,
|
||||
gop->Mode ? gop->Mode->Mode : 0);
|
||||
rc = uefi_call_wrapper(gop->QueryMode, 4, gop, i,
|
||||
&SizeOfInfo, &info);
|
||||
}
|
||||
|
||||
if (EFI_ERROR(rc)) {
|
||||
Print(L"%d: Bad response from QueryMode: %r (%d)\n",
|
||||
i, rc, rc);
|
||||
continue;
|
||||
}
|
||||
Print(L"%c%d: %dx%d ",
|
||||
(gop->Mode &&
|
||||
CompareMem(info,gop->Mode->Info,sizeof(*info)) == 0
|
||||
) ? '*' : ' ',
|
||||
i, info->HorizontalResolution, info->VerticalResolution);
|
||||
switch(info->PixelFormat) {
|
||||
case PixelRedGreenBlueReserved8BitPerColor:
|
||||
Print(L"RGBR");
|
||||
break;
|
||||
case PixelBlueGreenRedReserved8BitPerColor:
|
||||
Print(L"BGRR");
|
||||
break;
|
||||
case PixelBitMask:
|
||||
Print(L"R:%08x G:%08x B:%08x X:%08x",
|
||||
info->PixelInformation.RedMask,
|
||||
info->PixelInformation.GreenMask,
|
||||
info->PixelInformation.BlueMask,
|
||||
info->PixelInformation.ReservedMask);
|
||||
break;
|
||||
case PixelBltOnly:
|
||||
Print(L"(blt only)");
|
||||
break;
|
||||
default:
|
||||
Print(L"(Invalid pixel format)");
|
||||
break;
|
||||
}
|
||||
Print(L" pitch %d\n", info->PixelsPerScanLine);
|
||||
}
|
||||
}
|
||||
|
||||
static EFI_STATUS
|
||||
SetWatchdog(UINTN seconds)
|
||||
{
|
||||
EFI_STATUS rc;
|
||||
rc = uefi_call_wrapper(BS->SetWatchdogTimer, 4, seconds, 0x1ffff,
|
||||
0, NULL);
|
||||
if (EFI_ERROR(rc)) {
|
||||
CHAR16 Buffer[64];
|
||||
StatusToString(Buffer, rc);
|
||||
Print(L"Bad response from QueryMode: %s (%d)\n", Buffer, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_STATUS rc;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
|
||||
|
||||
InitializeLib(image_handle, systab);
|
||||
|
||||
SetWatchdog(10);
|
||||
|
||||
rc = LibLocateProtocol(&GraphicsOutputProtocol, (void **)&gop);
|
||||
if (EFI_ERROR(rc)) {
|
||||
Print(L"Could not locate GOP: %r\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!gop) {
|
||||
Print(L"LocateProtocol(GOP, &gop) returned %r but GOP is NULL\n", rc);
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
print_modes(gop);
|
||||
|
||||
SetWatchdog(0);
|
||||
return EFI_SUCCESS;
|
||||
}
|
32
gnu-efi/apps/printenv.c
Normal file
32
gnu-efi/apps/printenv.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
CHAR16 name[256], *val, fmt[20];
|
||||
EFI_GUID vendor;
|
||||
UINTN size;
|
||||
|
||||
InitializeLib(image, systab);
|
||||
|
||||
name[0] = 0;
|
||||
vendor = NullGuid;
|
||||
|
||||
Print(L"GUID Variable Name Value\n");
|
||||
Print(L"=================================== ==================== ========\n");
|
||||
|
||||
StrCpy(fmt, L"%.-35g %.-20s %s\n");
|
||||
while (1) {
|
||||
size = sizeof(name);
|
||||
status = uefi_call_wrapper(RT->GetNextVariableName, 3, &size, name, &vendor);
|
||||
if (status != EFI_SUCCESS)
|
||||
break;
|
||||
|
||||
val = LibGetVariable(name, &vendor);
|
||||
Print(fmt, &vendor, name, val);
|
||||
FreePool(val);
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
136
gnu-efi/apps/route80h.c
Normal file
136
gnu-efi/apps/route80h.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
/* this example program changes the Reserved Page Route (RPR) bit on ICH10's General
|
||||
* Control And Status Register (GCS) from LPC to PCI. In practical terms, it routes
|
||||
* outb to port 80h to the PCI bus. */
|
||||
|
||||
#define GCS_OFFSET_ADDR 0x3410
|
||||
#define GCS_RPR_SHIFT 2
|
||||
#define GCS_RPR_PCI 1
|
||||
#define GCS_RPR_LPC 0
|
||||
|
||||
#define VENDOR_ID_INTEL 0x8086
|
||||
#define DEVICE_ID_LPCIF 0x3a16
|
||||
#define DEVICE_ID_COUGARPOINT_LPCIF 0x1c56
|
||||
|
||||
static EFI_HANDLE ImageHandle;
|
||||
|
||||
typedef struct {
|
||||
uint16_t vendor_id; /* 00-01 */
|
||||
uint16_t device_id; /* 02-03 */
|
||||
char pad[0xEB]; /* 04-EF */
|
||||
uint32_t rcba; /* F0-F3 */
|
||||
uint32_t reserved[3]; /* F4-FF */
|
||||
} lpcif_t;
|
||||
|
||||
static inline void set_bit(volatile uint32_t *flag, int bit, int value)
|
||||
{
|
||||
uint32_t val = *flag;
|
||||
Print(L"current value is 0x%2x\n", val);
|
||||
|
||||
if (value) {
|
||||
val |= (1 << bit);
|
||||
} else {
|
||||
val &= ~(1 << bit);
|
||||
}
|
||||
Print(L"setting value to 0x%2x\n", val);
|
||||
*flag = val;
|
||||
val = *flag;
|
||||
Print(L"new value is 0x%2x\n", val);
|
||||
}
|
||||
|
||||
static int is_device(EFI_PCI_IO *pciio, uint16_t vendor_id, uint16_t device_id)
|
||||
{
|
||||
lpcif_t lpcif;
|
||||
EFI_STATUS rc;
|
||||
|
||||
rc = uefi_call_wrapper(pciio->Pci.Read, 5, pciio, EfiPciIoWidthUint16, 0, 2, &lpcif);
|
||||
if (EFI_ERROR(rc))
|
||||
return 0;
|
||||
|
||||
if (vendor_id == lpcif.vendor_id && device_id == lpcif.device_id)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EFI_STATUS find_pci_device(uint16_t vendor_id, uint16_t device_id,
|
||||
EFI_PCI_IO **pciio)
|
||||
{
|
||||
EFI_STATUS rc;
|
||||
EFI_HANDLE *Handles;
|
||||
UINTN NoHandles, i;
|
||||
|
||||
if (!pciio)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
rc = LibLocateHandle(ByProtocol, &PciIoProtocol, NULL, &NoHandles,
|
||||
&Handles);
|
||||
if (EFI_ERROR(rc))
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < NoHandles; i++) {
|
||||
void *pciio_tmp = NULL;
|
||||
rc = uefi_call_wrapper(BS->OpenProtocol, 6, Handles[i],
|
||||
&PciIoProtocol, &pciio_tmp, ImageHandle,
|
||||
NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(rc))
|
||||
continue;
|
||||
*pciio = pciio_tmp;
|
||||
if (!is_device(*pciio, vendor_id, device_id)) {
|
||||
*pciio = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
InitializeLib(image_handle, systab);
|
||||
EFI_PCI_IO *pciio = NULL;
|
||||
lpcif_t lpcif;
|
||||
EFI_STATUS rc = EFI_SUCCESS;
|
||||
struct {
|
||||
uint16_t vendor;
|
||||
uint16_t device;
|
||||
} devices[] = {
|
||||
{ VENDOR_ID_INTEL, DEVICE_ID_LPCIF },
|
||||
{ VENDOR_ID_INTEL, DEVICE_ID_COUGARPOINT_LPCIF },
|
||||
{ 0, 0 }
|
||||
};
|
||||
int i;
|
||||
|
||||
ImageHandle = image_handle;
|
||||
for (i = 0; devices[i].vendor != 0; i++) {
|
||||
rc = find_pci_device(devices[i].vendor, devices[i].device, &pciio);
|
||||
if (EFI_ERROR(rc))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rc == EFI_NOT_FOUND) {
|
||||
Print(L"Device not found.\n");
|
||||
return rc;
|
||||
} else if (EFI_ERROR(rc)) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = uefi_call_wrapper(pciio->Pci.Read, 5, pciio, EfiPciIoWidthUint32,
|
||||
EFI_FIELD_OFFSET(lpcif_t, rcba), 1, &lpcif.rcba);
|
||||
if (EFI_ERROR(rc))
|
||||
return rc;
|
||||
if (!(lpcif.rcba & 1)) {
|
||||
Print(L"rcrb is not mapped, cannot route port 80h\n");
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
lpcif.rcba &= ~1UL;
|
||||
|
||||
Print(L"rcba: 0x%8x\n", lpcif.rcba, lpcif.rcba);
|
||||
set_bit((uint32_t *)(intptr_t)(lpcif.rcba + GCS_OFFSET_ADDR),
|
||||
GCS_RPR_SHIFT, GCS_RPR_PCI);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
37
gnu-efi/apps/setdbg.c
Normal file
37
gnu-efi/apps/setdbg.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_GUID GRUB_EFI_GRUB_VARIABLE_GUID = {0x91376aff,0xcba6,0x42be,{0x94,0x9d,0x06,0xfd,0xe8,0x11,0x28,0xe8}};
|
||||
EFI_GUID SHIM_GUID = {0x605dab50,0xe046,0x4300,{0xab,0xb6,0x3d,0xd8,0x10,0xdd,0x8b,0x23}};
|
||||
|
||||
char grubenv[] = "# GRUB Environment Block\n\
|
||||
debug=tcp,http,net\n\
|
||||
####################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################";
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
InitializeLib(image, systab);
|
||||
#if 0
|
||||
UINT8 data = 1;
|
||||
|
||||
status = RT->SetVariable(L"SHIM_DEBUG", &SHIM_GUID,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(data), &data);
|
||||
if (EFI_ERROR(status))
|
||||
Print(L"SetVariable failed: %r\n", status);
|
||||
#endif
|
||||
|
||||
status = RT->SetVariable(L"GRUB_ENV", &SHIM_GUID,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(grubenv)-1, grubenv);
|
||||
if (EFI_ERROR(status))
|
||||
Print(L"SetVariable(GRUB_ENV) failed: %r\n", status);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
31
gnu-efi/apps/setjmp.c
Normal file
31
gnu-efi/apps/setjmp.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main(
|
||||
EFI_HANDLE image_handle,
|
||||
EFI_SYSTEM_TABLE *systab
|
||||
)
|
||||
{
|
||||
jmp_buf env;
|
||||
int rc;
|
||||
|
||||
InitializeLib(image_handle, systab);
|
||||
rc = setjmp(&env);
|
||||
Print(L"setjmp() = %d\n", rc);
|
||||
|
||||
if (rc == 3) {
|
||||
Print(L"3 worked\n");
|
||||
longjmp(&env, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rc == 1) {
|
||||
Print(L"0 got to be one yay\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
longjmp(&env, 3);
|
||||
return 0;
|
||||
}
|
27
gnu-efi/apps/t.c
Normal file
27
gnu-efi/apps/t.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
static CHAR16 *
|
||||
a2u (char *str)
|
||||
{
|
||||
static CHAR16 mem[2048];
|
||||
int i;
|
||||
|
||||
for (i = 0; str[i]; ++i)
|
||||
mem[i] = (CHAR16) str[i];
|
||||
mem[i] = 0;
|
||||
return mem;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
|
||||
|
||||
InitializeLib(image_handle, systab);
|
||||
conout = systab->ConOut;
|
||||
uefi_call_wrapper(conout->OutputString, 2, conout, (CHAR16 *)L"Hello World!\n\r");
|
||||
uefi_call_wrapper(conout->OutputString, 2, conout, a2u("Hello World!\n\r"));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
14
gnu-efi/apps/t2.c
Normal file
14
gnu-efi/apps/t2.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
|
||||
|
||||
InitializeLib(image, systab);
|
||||
conout = systab->ConOut;
|
||||
uefi_call_wrapper(conout->OutputString, 2, conout, L"Hello World!\n\r");
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
95
gnu-efi/apps/t3.c
Normal file
95
gnu-efi/apps/t3.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main(
|
||||
EFI_HANDLE image_handle,
|
||||
EFI_SYSTEM_TABLE *systab
|
||||
)
|
||||
{
|
||||
EFI_GUID loaded_image_protocol = LOADED_IMAGE_PROTOCOL;
|
||||
EFI_STATUS efi_status;
|
||||
EFI_LOADED_IMAGE *li;
|
||||
UINTN pat = PoolAllocationType;
|
||||
VOID *void_li_p;
|
||||
|
||||
InitializeLib(image_handle, systab);
|
||||
PoolAllocationType = 2; /* klooj */
|
||||
|
||||
Print(L"Hello World! (0xd=0x%x, 13=%d)\n", 13, 13);
|
||||
|
||||
Print(L"before InitializeLib(): PoolAllocationType=%d\n",
|
||||
pat);
|
||||
|
||||
Print(L" after InitializeLib(): PoolAllocationType=%d\n",
|
||||
PoolAllocationType);
|
||||
|
||||
/*
|
||||
* Locate loaded_image_handle instance.
|
||||
*/
|
||||
|
||||
Print(L"BS->HandleProtocol() ");
|
||||
|
||||
efi_status = uefi_call_wrapper(
|
||||
BS->HandleProtocol,
|
||||
3,
|
||||
image_handle,
|
||||
&loaded_image_protocol,
|
||||
&void_li_p);
|
||||
li = void_li_p;
|
||||
|
||||
Print(L"%xh (%r)\n", efi_status, efi_status);
|
||||
|
||||
if (efi_status != EFI_SUCCESS) {
|
||||
return efi_status;
|
||||
}
|
||||
|
||||
Print(L" li: %xh\n", li);
|
||||
|
||||
if (!li) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Print(L" li->Revision: %xh\n", li->Revision);
|
||||
Print(L" li->ParentHandle: %xh\n", li->ParentHandle);
|
||||
Print(L" li->SystemTable: %xh\n", li->SystemTable);
|
||||
Print(L" li->DeviceHandle: %xh\n", li->DeviceHandle);
|
||||
Print(L" li->FilePath: %xh\n", li->FilePath);
|
||||
Print(L" li->Reserved: %xh\n", li->Reserved);
|
||||
Print(L" li->LoadOptionsSize: %xh\n", li->LoadOptionsSize);
|
||||
Print(L" li->LoadOptions: %xh\n", li->LoadOptions);
|
||||
Print(L" li->ImageBase: %xh\n", li->ImageBase);
|
||||
Print(L" li->ImageSize: %xh\n", li->ImageSize);
|
||||
Print(L" li->ImageCodeType: %xh\n", li->ImageCodeType);
|
||||
Print(L" li->ImageDataType: %xh\n", li->ImageDataType);
|
||||
Print(L" li->Unload: %xh\n", li->Unload);
|
||||
|
||||
#if 0
|
||||
typedef struct {
|
||||
UINT32 Revision;
|
||||
EFI_HANDLE ParentHandle;
|
||||
struct _EFI_SYSTEM_TABLE *SystemTable;
|
||||
|
||||
// Source location of image
|
||||
EFI_HANDLE DeviceHandle;
|
||||
EFI_DEVICE_PATH *FilePath;
|
||||
VOID *Reserved;
|
||||
|
||||
// Images load options
|
||||
UINT32 LoadOptionsSize;
|
||||
VOID *LoadOptions;
|
||||
|
||||
// Location of where image was loaded
|
||||
VOID *ImageBase;
|
||||
UINT64 ImageSize;
|
||||
EFI_MEMORY_TYPE ImageCodeType;
|
||||
EFI_MEMORY_TYPE ImageDataType;
|
||||
|
||||
// If the driver image supports a dynamic unload request
|
||||
EFI_IMAGE_UNLOAD Unload;
|
||||
|
||||
} EFI_LOADED_IMAGE;
|
||||
#endif
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
14
gnu-efi/apps/t4.c
Normal file
14
gnu-efi/apps/t4.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
UINTN index;
|
||||
|
||||
InitializeLib(image, systab);
|
||||
uefi_call_wrapper(systab->ConOut->OutputString, 2, systab->ConOut, L"Hello application started\r\n");
|
||||
uefi_call_wrapper(systab->ConOut->OutputString, 2, systab->ConOut, L"\r\n\r\n\r\nHit any key to exit\r\n");
|
||||
uefi_call_wrapper(systab->BootServices->WaitForEvent, 3, 1, &systab->ConIn->WaitForKey, &index);
|
||||
return EFI_SUCCESS;
|
||||
}
|
13
gnu-efi/apps/t5.c
Normal file
13
gnu-efi/apps/t5.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
InitializeLib(image, systab);
|
||||
Print(L"HelloLib application started\n");
|
||||
Print(L"\n\n\nHit any key to exit this image\n");
|
||||
WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
|
||||
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, L"\n\n");
|
||||
return EFI_SUCCESS;
|
||||
}
|
43
gnu-efi/apps/t6.c
Normal file
43
gnu-efi/apps/t6.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
typedef EFI_STATUS (*foo_t)(EFI_HANDLE, EFI_GUID *, VOID **);
|
||||
typedef struct {
|
||||
unsigned long addr;
|
||||
unsigned long gp;
|
||||
} fdesc_t;
|
||||
|
||||
EFI_LOADED_IMAGE my_loaded;
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_LOADED_IMAGE *loaded_image = NULL;
|
||||
#if 0
|
||||
EFI_DEVICE_PATH *dev_path;
|
||||
#endif
|
||||
EFI_STATUS status;
|
||||
|
||||
InitializeLib(image, systab);
|
||||
status = uefi_call_wrapper(systab->BootServices->HandleProtocol,
|
||||
3,
|
||||
image,
|
||||
&LoadedImageProtocol,
|
||||
(void **) &loaded_image);
|
||||
if (EFI_ERROR(status)) {
|
||||
Print(L"handleprotocol: %r\n", status);
|
||||
}
|
||||
|
||||
#if 0
|
||||
BS->HandleProtocol(loaded_image->DeviceHandle, &DevicePathProtocol, (void **) &dev_path);
|
||||
|
||||
Print(L"Image device : %s\n", DevicePathToStr(dev_path));
|
||||
Print(L"Image file : %s\n", DevicePathToStr(loaded_image->FilePath));
|
||||
#endif
|
||||
Print(L"Image base : %lx\n", loaded_image->ImageBase);
|
||||
Print(L"Image size : %lx\n", loaded_image->ImageSize);
|
||||
Print(L"Load options size : %lx\n", loaded_image->LoadOptionsSize);
|
||||
Print(L"Load options : %s\n", loaded_image->LoadOptions);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
25
gnu-efi/apps/t7.c
Normal file
25
gnu-efi/apps/t7.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_INPUT_KEY efi_input_key;
|
||||
EFI_STATUS efi_status;
|
||||
|
||||
InitializeLib(image, systab);
|
||||
|
||||
Print(L"HelloLib application started\n");
|
||||
|
||||
Print(L"\n\n\nHit any key to exit this image\n");
|
||||
WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
|
||||
|
||||
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, L"\n\n");
|
||||
|
||||
efi_status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &efi_input_key);
|
||||
|
||||
Print(L"ScanCode: %xh UnicodeChar: %xh CallRtStatus: %x\n",
|
||||
efi_input_key.ScanCode, efi_input_key.UnicodeChar, efi_status);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
19
gnu-efi/apps/t8.c
Normal file
19
gnu-efi/apps/t8.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
INTN Argc, i;
|
||||
CHAR16 **Argv;
|
||||
|
||||
InitializeLib(ImageHandle, SystemTable);
|
||||
Argc = GetShellArgcArgv(ImageHandle, &Argv);
|
||||
|
||||
Print(L"Hello World, started with Argc=%d\n", Argc);
|
||||
for (i = 0 ; i < Argc ; ++i)
|
||||
Print(L" Argv[%d] = '%s'\n", i, Argv[i]);
|
||||
|
||||
Print(L"Bye.\n");
|
||||
return EFI_SUCCESS;
|
||||
}
|
431
gnu-efi/apps/tcc.c
Normal file
431
gnu-efi/apps/tcc.c
Normal file
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
* Test if our calling convention gymnastics actually work
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#if 0
|
||||
extern void dump_stack(void);
|
||||
asm( ".globl dump_stack\n"
|
||||
"dump_stack:\n"
|
||||
" movq %rsp, %rdi\n"
|
||||
" jmp *dump_stack_helper@GOTPCREL(%rip)\n"
|
||||
".size dump_stack, .-dump_stack");
|
||||
|
||||
void dump_stack_helper(uint64_t rsp_val)
|
||||
{
|
||||
uint64_t *rsp = (uint64_t *)rsp_val;
|
||||
int x;
|
||||
|
||||
Print(L"%%rsp: 0x%08x%08x stack:\r\n",
|
||||
(rsp_val & 0xffffffff00000000) >>32,
|
||||
rsp_val & 0xffffffff);
|
||||
for (x = 0; x < 8; x++) {
|
||||
Print(L"%08x: ", ((uint64_t)rsp) & 0xffffffff);
|
||||
Print(L"%016x ", *rsp++);
|
||||
Print(L"%016x ", *rsp++);
|
||||
Print(L"%016x ", *rsp++);
|
||||
Print(L"%016x\r\n", *rsp++);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_failure_callback(void)
|
||||
{
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
EFI_STATUS test_failure(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_failure_callback, 0);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call0_callback(void)
|
||||
{
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call0(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call0_callback, 0);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call1_callback(UINT32 a)
|
||||
{
|
||||
if (a != 0x12345678) {
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call1(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call1_callback, 1,0x12345678);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call2_callback(UINT32 a, UINT32 b)
|
||||
{
|
||||
if (a != 0x12345678) {
|
||||
return EFI_LOAD_ERROR;
|
||||
}
|
||||
if (b != 0x23456789) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call2(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call2_callback, 2,
|
||||
0x12345678, 0x23456789);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call3_callback(UINT32 a, UINT32 b,
|
||||
UINT32 c)
|
||||
{
|
||||
if (a != 0x12345678)
|
||||
return EFI_LOAD_ERROR;
|
||||
if (b != 0x23456789)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (c != 0x3456789a)
|
||||
return EFI_UNSUPPORTED;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call3(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call3_callback, 3,
|
||||
0x12345678, 0x23456789, 0x3456789a);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call4_callback(UINT32 a, UINT32 b,
|
||||
UINT32 c, UINT32 d)
|
||||
{
|
||||
if (a != 0x12345678)
|
||||
return EFI_LOAD_ERROR;
|
||||
if (b != 0x23456789)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (c != 0x3456789a)
|
||||
return EFI_UNSUPPORTED;
|
||||
if (d != 0x456789ab)
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call4(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call4_callback, 4,
|
||||
0x12345678, 0x23456789, 0x3456789a, 0x456789ab);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call5_callback(UINT32 a, UINT32 b,
|
||||
UINT32 c, UINT32 d, UINT32 e)
|
||||
{
|
||||
if (a != 0x12345678)
|
||||
return EFI_LOAD_ERROR;
|
||||
if (b != 0x23456789)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (c != 0x3456789a)
|
||||
return EFI_UNSUPPORTED;
|
||||
if (d != 0x456789ab)
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
if (e != 0x56789abc)
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call5(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call5_callback, 5,
|
||||
0x12345678, 0x23456789, 0x3456789a, 0x456789ab, 0x56789abc);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call6_callback(UINT32 a, UINT32 b,
|
||||
UINT32 c, UINT32 d, UINT32 e, UINT32 f)
|
||||
{
|
||||
if (a != 0x12345678)
|
||||
return EFI_LOAD_ERROR;
|
||||
if (b != 0x23456789)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (c != 0x3456789a)
|
||||
return EFI_UNSUPPORTED;
|
||||
if (d != 0x456789ab)
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
if (e != 0x56789abc)
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
if (f != 0x6789abcd)
|
||||
return EFI_NOT_READY;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call6(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call6_callback, 6,
|
||||
0x12345678, 0x23456789, 0x3456789a, 0x456789ab, 0x56789abc,
|
||||
0x6789abcd);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call7_callback(UINT32 a, UINT32 b,
|
||||
UINT32 c, UINT32 d, UINT32 e, UINT32 f, UINT32 g)
|
||||
{
|
||||
if (a != 0x12345678)
|
||||
return EFI_LOAD_ERROR;
|
||||
if (b != 0x23456789)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (c != 0x3456789a)
|
||||
return EFI_UNSUPPORTED;
|
||||
if (d != 0x456789ab)
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
if (e != 0x56789abc)
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
if (f != 0x6789abcd)
|
||||
return EFI_NOT_READY;
|
||||
if (g != 0x789abcde)
|
||||
return EFI_DEVICE_ERROR;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call7(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call7_callback, 7,
|
||||
0x12345678, 0x23456789, 0x3456789a, 0x456789ab,
|
||||
0x56789abc, 0x6789abcd, 0x789abcde);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call8_callback(UINT32 a, UINT32 b,
|
||||
UINT32 c, UINT32 d, UINT32 e, UINT32 f, UINT32 g, UINT32 h)
|
||||
{
|
||||
if (a != 0x12345678)
|
||||
return EFI_LOAD_ERROR;
|
||||
if (b != 0x23456789)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (c != 0x3456789a)
|
||||
return EFI_UNSUPPORTED;
|
||||
if (d != 0x456789ab)
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
if (e != 0x56789abc)
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
if (f != 0x6789abcd)
|
||||
return EFI_NOT_READY;
|
||||
if (g != 0x789abcde)
|
||||
return EFI_DEVICE_ERROR;
|
||||
if (h != 0x89abcdef)
|
||||
return EFI_WRITE_PROTECTED;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call8(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call8_callback, 8,
|
||||
0x12345678,
|
||||
0x23456789,
|
||||
0x3456789a,
|
||||
0x456789ab,
|
||||
0x56789abc,
|
||||
0x6789abcd,
|
||||
0x789abcde,
|
||||
0x89abcdef);
|
||||
}
|
||||
|
||||
EFI_STATUS EFI_FUNCTION test_call9_callback(UINT32 a, UINT32 b,
|
||||
UINT32 c, UINT32 d, UINT32 e, UINT32 f, UINT32 g, UINT32 h, UINT32 i)
|
||||
{
|
||||
if (a != 0x12345678)
|
||||
return EFI_LOAD_ERROR;
|
||||
if (b != 0x23456789)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (c != 0x3456789a)
|
||||
return EFI_UNSUPPORTED;
|
||||
if (d != 0x456789ab)
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
if (e != 0x56789abc)
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
if (f != 0x6789abcd)
|
||||
return EFI_NOT_READY;
|
||||
if (g != 0x789abcde)
|
||||
return EFI_DEVICE_ERROR;
|
||||
if (h != 0x89abcdef)
|
||||
return EFI_WRITE_PROTECTED;
|
||||
if (i != 0x9abcdef0)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call9(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call9_callback, 9,
|
||||
0x12345678,
|
||||
0x23456789,
|
||||
0x3456789a,
|
||||
0x456789ab,
|
||||
0x56789abc,
|
||||
0x6789abcd,
|
||||
0x789abcde,
|
||||
0x89abcdef,
|
||||
0x9abcdef0);
|
||||
}
|
||||
|
||||
extern EFI_STATUS test_call10(void);
|
||||
EFI_STATUS EFI_FUNCTION test_call10_callback(UINT32 a, UINT32 b,
|
||||
UINT32 c, UINT32 d, UINT32 e, UINT32 f, UINT32 g, UINT32 h, UINT32 i,
|
||||
UINT32 j)
|
||||
{
|
||||
if (a != 0x12345678)
|
||||
return EFI_LOAD_ERROR;
|
||||
if (b != 0x23456789)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (c != 0x3456789a)
|
||||
return EFI_UNSUPPORTED;
|
||||
if (d != 0x456789ab)
|
||||
return EFI_BAD_BUFFER_SIZE;
|
||||
if (e != 0x56789abc)
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
if (f != 0x6789abcd)
|
||||
return EFI_NOT_READY;
|
||||
if (g != 0x789abcde)
|
||||
return EFI_DEVICE_ERROR;
|
||||
if (h != 0x89abcdef)
|
||||
return EFI_WRITE_PROTECTED;
|
||||
if (i != 0x9abcdef0)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
if (j != 0xabcdef01)
|
||||
return EFI_VOLUME_CORRUPTED;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS test_call10(void)
|
||||
{
|
||||
return uefi_call_wrapper(test_call10_callback, 10,
|
||||
0x12345678,
|
||||
0x23456789,
|
||||
0x3456789a,
|
||||
0x456789ab,
|
||||
0x56789abc,
|
||||
0x6789abcd,
|
||||
0x789abcde,
|
||||
0x89abcdef,
|
||||
0x9abcdef0,
|
||||
0xabcdef01);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE *image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_STATUS rc = EFI_SUCCESS;
|
||||
|
||||
InitializeLib(image, systab);
|
||||
PoolAllocationType = 2; /* klooj */
|
||||
|
||||
#ifdef __x86_64__
|
||||
__asm__ volatile("out %0,%1" : : "a" ((uint8_t)0x14), "dN" (0x80));
|
||||
#endif
|
||||
|
||||
Print(L"Hello\r\n");
|
||||
rc = test_failure();
|
||||
if (EFI_ERROR(rc)) {
|
||||
Print(L"Returning Failure works\n");
|
||||
} else {
|
||||
Print(L"Returning failure doesn't work.\r\n");
|
||||
Print(L"%%rax was 0x%016x, should have been 0x%016x\n",
|
||||
rc, EFI_UNSUPPORTED);
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
rc = test_call0();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"0 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"0 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call1();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"1 arg works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"1 arg failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call2();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"2 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"2 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call3();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"3 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"3 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call4();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"4 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"4 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call5();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"5 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"5 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call6();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"6 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"6 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call7();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"7 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"7 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call8();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"8 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"8 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call9();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"9 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"9 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = test_call10();
|
||||
if (!EFI_ERROR(rc)) {
|
||||
Print(L"10 args works just fine here.\r\n");
|
||||
} else {
|
||||
Print(L"10 args failed: 0x%016x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
9
gnu-efi/apps/tpause.c
Normal file
9
gnu-efi/apps/tpause.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
Print(L"Press `q' to quit, any other key to continue:\n");
|
||||
|
||||
}
|
43
gnu-efi/apps/trivial.S
Normal file
43
gnu-efi/apps/trivial.S
Normal file
|
@ -0,0 +1,43 @@
|
|||
.text
|
||||
.align 4
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
#if 0
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %ebx # save ebx
|
||||
movl 12(%ebp),%eax # eax <- systab
|
||||
movl 24(%eax),%ebx # ebx <- systab->FirmwareVendor
|
||||
pushl %ebx
|
||||
movl 44(%eax),%ebx # ebx <- systab->ConOut
|
||||
pushl %ebx
|
||||
movl 4(%ebx),%eax # eax <- conout->OutputString
|
||||
call *%eax
|
||||
movl -4(%ebp),%ebx # restore ebx
|
||||
leave
|
||||
ret
|
||||
|
||||
#else
|
||||
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %ebx
|
||||
call 0f
|
||||
0: popl %eax
|
||||
addl $hello-0b,%eax
|
||||
pushl %eax
|
||||
movl 12(%ebp),%eax # eax <- systab
|
||||
movl 44(%eax),%ebx # ebx <- systab->ConOut
|
||||
pushl %ebx
|
||||
movl 4(%ebx),%eax # eax <- conout->OutputString
|
||||
call *%eax
|
||||
movl -4(%ebp),%ebx
|
||||
leave
|
||||
ret
|
||||
|
||||
.section .rodata
|
||||
.align 2
|
||||
hello: .byte 'h',0,'e',0,'l',0,'l',0,'o',0,'\n',0,'\r',0,0,0
|
||||
|
||||
#endif
|
37
gnu-efi/apps/unsetdbg.c
Normal file
37
gnu-efi/apps/unsetdbg.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_GUID GRUB_EFI_GRUB_VARIABLE_GUID = {0x91376aff,0xcba6,0x42be,{0x94,0x9d,0x06,0xfd,0xe8,0x11,0x28,0xe8}};
|
||||
EFI_GUID SHIM_GUID = {0x605dab50,0xe046,0x4300,{0xab,0xb6,0x3d,0xd8,0x10,0xdd,0x8b,0x23}};
|
||||
|
||||
char grubenv[] = "# GRUB Environment Block\n\
|
||||
debug=all\n\
|
||||
#############################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################";
|
||||
|
||||
EFI_STATUS
|
||||
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
{
|
||||
EFI_STATUS status;
|
||||
UINT8 data = 1;
|
||||
InitializeLib(image, systab);
|
||||
|
||||
status = RT->SetVariable(L"SHIM_DEBUG", &SHIM_GUID,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
0, &data);
|
||||
if (EFI_ERROR(status))
|
||||
Print(L"SetVariable failed: %r\n", status);
|
||||
|
||||
#if 0
|
||||
status = RT->SetVariable(L"GRUB_ENV", &SHIM_GUID,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(grubenv)-1, grubenv);
|
||||
if (EFI_ERROR(status))
|
||||
Print(L"SetVariable(GRUB_ENV) failed: %r\n", status);
|
||||
#endif
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
75
gnu-efi/gnuefi/Makefile
Normal file
75
gnu-efi/gnuefi/Makefile
Normal file
|
@ -0,0 +1,75 @@
|
|||
#
|
||||
# Copyright (C) 1999-2001 Hewlett-Packard Co.
|
||||
# Contributed by David Mosberger <davidm@hpl.hp.com>
|
||||
# Contributed by Stephane Eranian <eranian@hpl.hp.com>
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
# * Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
|
||||
SRCDIR = .
|
||||
|
||||
VPATH = $(SRCDIR)
|
||||
|
||||
include $(SRCDIR)/../Make.defaults
|
||||
|
||||
TOPDIR = $(SRCDIR)/..
|
||||
|
||||
CDIR=$(TOPDIR)/..
|
||||
FILES = reloc_$(ARCH)
|
||||
|
||||
OBJS = $(FILES:%=%.o)
|
||||
|
||||
# on aarch64, avoid jump tables before all relocations have been processed
|
||||
reloc_aarch64.o: CFLAGS += -fno-jump-tables
|
||||
|
||||
TARGETS = crt0-efi-$(ARCH).o libgnuefi.a
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
libgnuefi.a: $(patsubst %,libgnuefi.a(%),$(OBJS))
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS) *~ *.o $(OBJS)
|
||||
|
||||
install:
|
||||
mkdir -p $(INSTALLROOT)$(LIBDIR)
|
||||
$(INSTALL) -m 644 $(TARGETS) $(INSTALLROOT)$(LIBDIR)
|
||||
ifneq (,$(findstring FreeBSD,$(OS)))
|
||||
ifeq ($(ARCH),x86_64)
|
||||
$(INSTALL) -m 644 $(SRCDIR)/elf_$(ARCH)_fbsd_efi.lds $(INSTALLROOT)$(LIBDIR)
|
||||
else
|
||||
$(INSTALL) -m 644 $(SRCDIR)/elf_$(ARCH)_efi.lds $(INSTALLROOT)$(LIBDIR)
|
||||
endif
|
||||
else
|
||||
$(INSTALL) -m 644 $(SRCDIR)/elf_$(ARCH)_efi.lds $(INSTALLROOT)$(LIBDIR)
|
||||
endif
|
||||
|
||||
include $(SRCDIR)/../Make.rules
|
130
gnu-efi/gnuefi/crt0-efi-aarch64.S
Normal file
130
gnu-efi/gnuefi/crt0-efi-aarch64.S
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* crt0-efi-aarch64.S - PE/COFF header for AArch64 EFI applications
|
||||
*
|
||||
* Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice and this list of conditions, without modification.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation;
|
||||
* either version 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
.section .text.head
|
||||
|
||||
/*
|
||||
* Magic "MZ" signature for PE/COFF
|
||||
*/
|
||||
.globl ImageBase
|
||||
ImageBase:
|
||||
.ascii "MZ"
|
||||
.skip 58 // 'MZ' + pad + offset == 64
|
||||
.long pe_header - ImageBase // Offset to the PE header.
|
||||
pe_header:
|
||||
.ascii "PE"
|
||||
.short 0
|
||||
coff_header:
|
||||
.short 0xaa64 // AArch64
|
||||
.short 2 // nr_sections
|
||||
.long 0 // TimeDateStamp
|
||||
.long 0 // PointerToSymbolTable
|
||||
.long 1 // NumberOfSymbols
|
||||
.short section_table - optional_header // SizeOfOptionalHeader
|
||||
.short 0x206 // Characteristics.
|
||||
// IMAGE_FILE_DEBUG_STRIPPED |
|
||||
// IMAGE_FILE_EXECUTABLE_IMAGE |
|
||||
// IMAGE_FILE_LINE_NUMS_STRIPPED
|
||||
optional_header:
|
||||
.short 0x20b // PE32+ format
|
||||
.byte 0x02 // MajorLinkerVersion
|
||||
.byte 0x14 // MinorLinkerVersion
|
||||
.long _data - _start // SizeOfCode
|
||||
.long _data_size // SizeOfInitializedData
|
||||
.long 0 // SizeOfUninitializedData
|
||||
.long _start - ImageBase // AddressOfEntryPoint
|
||||
.long _start - ImageBase // BaseOfCode
|
||||
|
||||
extra_header_fields:
|
||||
.quad 0 // ImageBase
|
||||
.long 0x1000 // SectionAlignment
|
||||
.long 0x200 // FileAlignment
|
||||
.short 0 // MajorOperatingSystemVersion
|
||||
.short 0 // MinorOperatingSystemVersion
|
||||
.short 0 // MajorImageVersion
|
||||
.short 0 // MinorImageVersion
|
||||
.short 0 // MajorSubsystemVersion
|
||||
.short 0 // MinorSubsystemVersion
|
||||
.long 0 // Win32VersionValue
|
||||
|
||||
.long _edata - ImageBase // SizeOfImage
|
||||
|
||||
// Everything before the kernel image is considered part of the header
|
||||
.long _start - ImageBase // SizeOfHeaders
|
||||
.long 0 // CheckSum
|
||||
.short EFI_SUBSYSTEM // Subsystem
|
||||
.short 0 // DllCharacteristics
|
||||
.quad 0 // SizeOfStackReserve
|
||||
.quad 0 // SizeOfStackCommit
|
||||
.quad 0 // SizeOfHeapReserve
|
||||
.quad 0 // SizeOfHeapCommit
|
||||
.long 0 // LoaderFlags
|
||||
.long 0x6 // NumberOfRvaAndSizes
|
||||
|
||||
.quad 0 // ExportTable
|
||||
.quad 0 // ImportTable
|
||||
.quad 0 // ResourceTable
|
||||
.quad 0 // ExceptionTable
|
||||
.quad 0 // CertificationTable
|
||||
.quad 0 // BaseRelocationTable
|
||||
|
||||
// Section table
|
||||
section_table:
|
||||
.ascii ".text\0\0\0"
|
||||
.long _data - _start // VirtualSize
|
||||
.long _start - ImageBase // VirtualAddress
|
||||
.long _data - _start // SizeOfRawData
|
||||
.long _start - ImageBase // PointerToRawData
|
||||
|
||||
.long 0 // PointerToRelocations (0 for executables)
|
||||
.long 0 // PointerToLineNumbers (0 for executables)
|
||||
.short 0 // NumberOfRelocations (0 for executables)
|
||||
.short 0 // NumberOfLineNumbers (0 for executables)
|
||||
.long 0x60000020 // Characteristics (section flags)
|
||||
|
||||
.ascii ".data\0\0\0"
|
||||
.long _data_size // VirtualSize
|
||||
.long _data - ImageBase // VirtualAddress
|
||||
.long _data_size // SizeOfRawData
|
||||
.long _data - ImageBase // PointerToRawData
|
||||
|
||||
.long 0 // PointerToRelocations (0 for executables)
|
||||
.long 0 // PointerToLineNumbers (0 for executables)
|
||||
.short 0 // NumberOfRelocations (0 for executables)
|
||||
.short 0 // NumberOfLineNumbers (0 for executables)
|
||||
.long 0xc0000040 // Characteristics (section flags)
|
||||
|
||||
.align 12
|
||||
_start:
|
||||
stp x29, x30, [sp, #-32]!
|
||||
mov x29, sp
|
||||
|
||||
stp x0, x1, [sp, #16]
|
||||
mov x2, x0
|
||||
mov x3, x1
|
||||
adr x0, ImageBase
|
||||
adrp x1, _DYNAMIC
|
||||
add x1, x1, #:lo12:_DYNAMIC
|
||||
bl _relocate
|
||||
cbnz x0, 0f
|
||||
|
||||
ldp x0, x1, [sp, #16]
|
||||
bl efi_main
|
||||
|
||||
0: ldp x29, x30, [sp], #32
|
||||
ret
|
145
gnu-efi/gnuefi/crt0-efi-arm.S
Normal file
145
gnu-efi/gnuefi/crt0-efi-arm.S
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* crt0-efi-arm.S - PE/COFF header for ARM EFI applications
|
||||
*
|
||||
* Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice and this list of conditions, without modification.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation;
|
||||
* either version 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
.section .text.head
|
||||
|
||||
/*
|
||||
* Magic "MZ" signature for PE/COFF
|
||||
*/
|
||||
.globl ImageBase
|
||||
ImageBase:
|
||||
.ascii "MZ"
|
||||
.skip 58 // 'MZ' + pad + offset == 64
|
||||
.long pe_header - ImageBase // Offset to the PE header.
|
||||
pe_header:
|
||||
.ascii "PE"
|
||||
.short 0
|
||||
coff_header:
|
||||
.short 0x1c2 // Mixed ARM/Thumb
|
||||
.short 2 // nr_sections
|
||||
.long 0 // TimeDateStamp
|
||||
.long 0 // PointerToSymbolTable
|
||||
.long 1 // NumberOfSymbols
|
||||
.short section_table - optional_header // SizeOfOptionalHeader
|
||||
.short 0x306 // Characteristics.
|
||||
// IMAGE_FILE_32BIT_MACHINE |
|
||||
// IMAGE_FILE_DEBUG_STRIPPED |
|
||||
// IMAGE_FILE_EXECUTABLE_IMAGE |
|
||||
// IMAGE_FILE_LINE_NUMS_STRIPPED
|
||||
optional_header:
|
||||
.short 0x10b // PE32+ format
|
||||
.byte 0x02 // MajorLinkerVersion
|
||||
.byte 0x14 // MinorLinkerVersion
|
||||
.long _edata - _start // SizeOfCode
|
||||
.long 0 // SizeOfInitializedData
|
||||
.long 0 // SizeOfUninitializedData
|
||||
.long _start - ImageBase // AddressOfEntryPoint
|
||||
.long _start - ImageBase // BaseOfCode
|
||||
.long 0 // BaseOfData
|
||||
|
||||
extra_header_fields:
|
||||
.long 0 // ImageBase
|
||||
.long 0x20 // SectionAlignment
|
||||
.long 0x8 // FileAlignment
|
||||
.short 0 // MajorOperatingSystemVersion
|
||||
.short 0 // MinorOperatingSystemVersion
|
||||
.short 0 // MajorImageVersion
|
||||
.short 0 // MinorImageVersion
|
||||
.short 0 // MajorSubsystemVersion
|
||||
.short 0 // MinorSubsystemVersion
|
||||
.long 0 // Win32VersionValue
|
||||
|
||||
.long _edata - ImageBase // SizeOfImage
|
||||
|
||||
// Everything before the kernel image is considered part of the header
|
||||
.long _start - ImageBase // SizeOfHeaders
|
||||
.long 0 // CheckSum
|
||||
.short EFI_SUBSYSTEM // Subsystem
|
||||
.short 0 // DllCharacteristics
|
||||
.long 0 // SizeOfStackReserve
|
||||
.long 0 // SizeOfStackCommit
|
||||
.long 0 // SizeOfHeapReserve
|
||||
.long 0 // SizeOfHeapCommit
|
||||
.long 0 // LoaderFlags
|
||||
.long 0x6 // NumberOfRvaAndSizes
|
||||
|
||||
.quad 0 // ExportTable
|
||||
.quad 0 // ImportTable
|
||||
.quad 0 // ResourceTable
|
||||
.quad 0 // ExceptionTable
|
||||
.quad 0 // CertificationTable
|
||||
.quad 0 // BaseRelocationTable
|
||||
|
||||
// Section table
|
||||
section_table:
|
||||
|
||||
/*
|
||||
* The EFI application loader requires a relocation section
|
||||
* because EFI applications must be relocatable. This is a
|
||||
* dummy section as far as we are concerned.
|
||||
*/
|
||||
.ascii ".reloc"
|
||||
.byte 0
|
||||
.byte 0 // end of 0 padding of section name
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0 // SizeOfRawData
|
||||
.long 0 // PointerToRawData
|
||||
.long 0 // PointerToRelocations
|
||||
.long 0 // PointerToLineNumbers
|
||||
.short 0 // NumberOfRelocations
|
||||
.short 0 // NumberOfLineNumbers
|
||||
.long 0x42100040 // Characteristics (section flags)
|
||||
|
||||
|
||||
.ascii ".text"
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0 // end of 0 padding of section name
|
||||
.long _edata - _start // VirtualSize
|
||||
.long _start - ImageBase // VirtualAddress
|
||||
.long _edata - _start // SizeOfRawData
|
||||
.long _start - ImageBase // PointerToRawData
|
||||
|
||||
.long 0 // PointerToRelocations (0 for executables)
|
||||
.long 0 // PointerToLineNumbers (0 for executables)
|
||||
.short 0 // NumberOfRelocations (0 for executables)
|
||||
.short 0 // NumberOfLineNumbers (0 for executables)
|
||||
.long 0xe0500020 // Characteristics (section flags)
|
||||
|
||||
_start:
|
||||
stmfd sp!, {r0-r2, lr}
|
||||
|
||||
mov r2, r0
|
||||
mov r3, r1
|
||||
adr r1, .L_DYNAMIC
|
||||
ldr r0, [r1]
|
||||
add r1, r0, r1
|
||||
adr r0, ImageBase
|
||||
bl _relocate
|
||||
teq r0, #0
|
||||
bne 0f
|
||||
|
||||
ldmfd sp, {r0-r1}
|
||||
bl efi_main
|
||||
|
||||
0: add sp, sp, #12
|
||||
ldr pc, [sp], #4
|
||||
|
||||
.L_DYNAMIC:
|
||||
.word _DYNAMIC - .
|
76
gnu-efi/gnuefi/crt0-efi-ia32.S
Normal file
76
gnu-efi/gnuefi/crt0-efi-ia32.S
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* crt0-efi-ia32.S - x86 EFI startup code.
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
pushl 12(%ebp) # copy "image" argument
|
||||
pushl 8(%ebp) # copy "systab" argument
|
||||
|
||||
call 0f
|
||||
0: popl %eax
|
||||
movl %eax,%ebx
|
||||
|
||||
addl $ImageBase-0b,%eax # %eax = ldbase
|
||||
addl $_DYNAMIC-0b,%ebx # %ebx = _DYNAMIC
|
||||
|
||||
pushl %ebx # pass _DYNAMIC as second argument
|
||||
pushl %eax # pass ldbase as first argument
|
||||
call _relocate
|
||||
popl %ebx
|
||||
popl %ebx
|
||||
testl %eax,%eax
|
||||
jne .exit
|
||||
|
||||
call efi_main # call app with "image" and "systab" argument
|
||||
|
||||
.exit: leave
|
||||
ret
|
||||
|
||||
// hand-craft a dummy .reloc section so EFI knows it's a relocatable executable:
|
||||
|
||||
.data
|
||||
dummy: .long 0
|
||||
|
||||
#define IMAGE_REL_ABSOLUTE 0
|
||||
.section .reloc
|
||||
.long dummy // Page RVA
|
||||
.long 10 // Block Size (2*4+2)
|
||||
.word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy
|
87
gnu-efi/gnuefi/crt0-efi-ia64.S
Normal file
87
gnu-efi/gnuefi/crt0-efi-ia64.S
Normal file
|
@ -0,0 +1,87 @@
|
|||
/* crt0-efi-ia64.S - IA-64 EFI startup code.
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
.text
|
||||
.psr abi64
|
||||
.psr lsb
|
||||
.lsb
|
||||
|
||||
.proc _start
|
||||
_start:
|
||||
alloc loc0=ar.pfs,2,2,2,0
|
||||
mov loc1=rp
|
||||
movl out0=@gprel(ImageBase) // out0 <- ImageBase (ldbase)
|
||||
;;
|
||||
add out0=out0,gp
|
||||
movl out1=@gprel(_DYNAMIC) // out1 <- _DYNAMIC
|
||||
;; // avoid WAW on CFM
|
||||
add out1=out1,gp
|
||||
br.call.sptk.few rp=_relocate
|
||||
.Lret0:
|
||||
cmp.ne p6,p0=r0,r8 // r8 == EFI_SUCCESS?
|
||||
(p6) br.cond.sptk.few .exit // no ->
|
||||
|
||||
.Lret1:
|
||||
|
||||
mov out0=in0 // image handle
|
||||
mov out1=in1 // systab
|
||||
br.call.sptk.few rp=efi_main
|
||||
.Lret2:
|
||||
.exit:
|
||||
mov ar.pfs=loc0
|
||||
mov rp=loc1
|
||||
;;
|
||||
br.ret.sptk.few rp
|
||||
|
||||
.endp _start
|
||||
|
||||
|
||||
// PE32+ wants a PLABEL, not the code address of the entry point:
|
||||
|
||||
.align 16
|
||||
.global _start_plabel
|
||||
.section .plabel, "a"
|
||||
_start_plabel:
|
||||
data8 _start
|
||||
data8 __gp
|
||||
|
||||
// hand-craft a .reloc section for the plabel:
|
||||
|
||||
#define IMAGE_REL_BASED_DIR64 10
|
||||
|
||||
.section .reloc, "a"
|
||||
data4 _start_plabel // Page RVA
|
||||
data4 12 // Block Size (2*4+2*2)
|
||||
data2 (IMAGE_REL_BASED_DIR64<<12) + 0 // reloc for plabel's entry point
|
||||
data2 (IMAGE_REL_BASED_DIR64<<12) + 8 // reloc for plabel's global pointer
|
188
gnu-efi/gnuefi/crt0-efi-mips64el.S
Normal file
188
gnu-efi/gnuefi/crt0-efi-mips64el.S
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* crt0-efi-mips64el.S - PE/COFF header for MIPS64 EFI applications
|
||||
*
|
||||
* Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
|
||||
* Copright (C) 2017 Heiher <r@hev.cc>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice and this list of conditions, without modification.
|
||||
* 2. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation;
|
||||
* either version 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
.section .text.head
|
||||
|
||||
/*
|
||||
* Magic "MZ" signature for PE/COFF
|
||||
*/
|
||||
.globl ImageBase
|
||||
ImageBase:
|
||||
.ascii "MZ"
|
||||
.skip 58 // 'MZ' + pad + offset == 64
|
||||
.long pe_header - ImageBase // Offset to the PE header.
|
||||
pe_header:
|
||||
.ascii "PE"
|
||||
.short 0
|
||||
coff_header:
|
||||
.short 0x166 // MIPS little endian
|
||||
.short 2 // nr_sections
|
||||
.long 0 // TimeDateStamp
|
||||
.long 0 // PointerToSymbolTable
|
||||
.long 1 // NumberOfSymbols
|
||||
.short section_table - optional_header // SizeOfOptionalHeader
|
||||
.short 0x206 // Characteristics.
|
||||
// IMAGE_FILE_DEBUG_STRIPPED |
|
||||
// IMAGE_FILE_EXECUTABLE_IMAGE |
|
||||
// IMAGE_FILE_LINE_NUMS_STRIPPED
|
||||
optional_header:
|
||||
.short 0x20b // PE32+ format
|
||||
.byte 0x02 // MajorLinkerVersion
|
||||
.byte 0x14 // MinorLinkerVersion
|
||||
.long _edata - _start // SizeOfCode
|
||||
.long 0 // SizeOfInitializedData
|
||||
.long 0 // SizeOfUninitializedData
|
||||
.long _start - ImageBase // AddressOfEntryPoint
|
||||
.long _start - ImageBase // BaseOfCode
|
||||
|
||||
extra_header_fields:
|
||||
.quad 0 // ImageBase
|
||||
.long 0x20 // SectionAlignment
|
||||
.long 0x8 // FileAlignment
|
||||
.short 0 // MajorOperatingSystemVersion
|
||||
.short 0 // MinorOperatingSystemVersion
|
||||
.short 0 // MajorImageVersion
|
||||
.short 0 // MinorImageVersion
|
||||
.short 0 // MajorSubsystemVersion
|
||||
.short 0 // MinorSubsystemVersion
|
||||
.long 0 // Win32VersionValue
|
||||
|
||||
.long _edata - ImageBase // SizeOfImage
|
||||
|
||||
// Everything before the kernel image is considered part of the header
|
||||
.long _start - ImageBase // SizeOfHeaders
|
||||
.long 0 // CheckSum
|
||||
.short EFI_SUBSYSTEM // Subsystem
|
||||
.short 0 // DllCharacteristics
|
||||
.quad 0 // SizeOfStackReserve
|
||||
.quad 0 // SizeOfStackCommit
|
||||
.quad 0 // SizeOfHeapReserve
|
||||
.quad 0 // SizeOfHeapCommit
|
||||
.long 0 // LoaderFlags
|
||||
.long 0x6 // NumberOfRvaAndSizes
|
||||
|
||||
.quad 0 // ExportTable
|
||||
.quad 0 // ImportTable
|
||||
.quad 0 // ResourceTable
|
||||
.quad 0 // ExceptionTable
|
||||
.quad 0 // CertificationTable
|
||||
.quad 0 // BaseRelocationTable
|
||||
|
||||
// Section table
|
||||
section_table:
|
||||
|
||||
/*
|
||||
* The EFI application loader requires a relocation section
|
||||
* because EFI applications must be relocatable. This is a
|
||||
* dummy section as far as we are concerned.
|
||||
*/
|
||||
.ascii ".reloc"
|
||||
.byte 0
|
||||
.byte 0 // end of 0 padding of section name
|
||||
.long 0
|
||||
.long 0
|
||||
.long 0 // SizeOfRawData
|
||||
.long 0 // PointerToRawData
|
||||
.long 0 // PointerToRelocations
|
||||
.long 0 // PointerToLineNumbers
|
||||
.short 0 // NumberOfRelocations
|
||||
.short 0 // NumberOfLineNumbers
|
||||
.long 0x42100040 // Characteristics (section flags)
|
||||
|
||||
|
||||
.ascii ".text"
|
||||
.byte 0
|
||||
.byte 0
|
||||
.byte 0 // end of 0 padding of section name
|
||||
.long _edata - _start // VirtualSize
|
||||
.long _start - ImageBase // VirtualAddress
|
||||
.long _edata - _start // SizeOfRawData
|
||||
.long _start - ImageBase // PointerToRawData
|
||||
|
||||
.long 0 // PointerToRelocations (0 for executables)
|
||||
.long 0 // PointerToLineNumbers (0 for executables)
|
||||
.short 0 // NumberOfRelocations (0 for executables)
|
||||
.short 0 // NumberOfLineNumbers (0 for executables)
|
||||
.long 0xe0500020 // Characteristics (section flags)
|
||||
|
||||
.set push
|
||||
.set noreorder
|
||||
.align 4
|
||||
|
||||
.globl _start
|
||||
.ent _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
daddiu $sp, -32
|
||||
sd $ra, ($sp)
|
||||
|
||||
// Get pc & gp
|
||||
.align 3
|
||||
bal 1f
|
||||
sd $gp, 8($sp)
|
||||
_pc:
|
||||
.dword _gp
|
||||
.dword _DYNAMIC
|
||||
.dword _relocate
|
||||
1:
|
||||
// pc in ra
|
||||
ld $gp, ($ra)
|
||||
dli $t0, _pc
|
||||
dsubu $gp, $t0
|
||||
daddu $gp, $ra
|
||||
|
||||
sd $a0, 16($sp)
|
||||
sd $a1, 24($sp)
|
||||
|
||||
// a2: ImageHandle
|
||||
move $a2, $a0
|
||||
// a3: SystemTable
|
||||
move $a3, $a1
|
||||
// a0: ImageBase
|
||||
dli $t1, ImageBase - _pc
|
||||
daddu $a0, $ra, $t1
|
||||
// a1: DynamicSection
|
||||
ld $t1, 8($ra)
|
||||
dsubu $t1, $t0
|
||||
daddu $a1, $ra, $t1
|
||||
// call _relocate
|
||||
ld $t1, 16($ra)
|
||||
dsubu $t1, $t0
|
||||
daddu $t9, $ra, $t1
|
||||
jalr $t9
|
||||
nop
|
||||
bnez $v0, 1b
|
||||
nop
|
||||
|
||||
// a0: ImageHandle
|
||||
ld $a0, 16($sp)
|
||||
// call efi_main
|
||||
dla $t9, efi_main
|
||||
jalr $t9
|
||||
// a1: SystemTable
|
||||
ld $a1, 24($sp)
|
||||
|
||||
1:
|
||||
ld $gp, 8($sp)
|
||||
ld $ra, ($sp)
|
||||
jr $ra
|
||||
daddiu $sp, 32
|
||||
.end _start
|
||||
|
||||
.set pop
|
76
gnu-efi/gnuefi/crt0-efi-x86_64.S
Normal file
76
gnu-efi/gnuefi/crt0-efi-x86_64.S
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* crt0-efi-x86_64.S - x86_64 EFI startup code.
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
Copyright (C) 2005 Intel Co.
|
||||
Contributed by Fenghua Yu <fenghua.yu@intel.com>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
.text
|
||||
.align 4
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
subq $8, %rsp
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
|
||||
0:
|
||||
lea ImageBase(%rip), %rdi
|
||||
lea _DYNAMIC(%rip), %rsi
|
||||
|
||||
popq %rcx
|
||||
popq %rdx
|
||||
pushq %rcx
|
||||
pushq %rdx
|
||||
call _relocate
|
||||
|
||||
popq %rdi
|
||||
popq %rsi
|
||||
|
||||
call efi_main
|
||||
addq $8, %rsp
|
||||
|
||||
.exit:
|
||||
ret
|
||||
|
||||
// hand-craft a dummy .reloc section so EFI knows it's a relocatable executable:
|
||||
|
||||
.data
|
||||
dummy: .long 0
|
||||
|
||||
#define IMAGE_REL_ABSOLUTE 0
|
||||
.section .reloc, "a"
|
||||
label1:
|
||||
.long dummy-label1 // Page RVA
|
||||
.long 10 // Block Size (2*4+2)
|
||||
.word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy
|
||||
|
63
gnu-efi/gnuefi/elf_aarch64_efi.lds
Normal file
63
gnu-efi/gnuefi/elf_aarch64_efi.lds
Normal file
|
@ -0,0 +1,63 @@
|
|||
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x0 : {
|
||||
_text = .;
|
||||
*(.text.head)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.srodata)
|
||||
*(.rodata*)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
_text_size = . - _text;
|
||||
.dynamic : { *(.dynamic) }
|
||||
.data : ALIGN(4096)
|
||||
{
|
||||
_data = .;
|
||||
*(.sdata)
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
it all into .data: */
|
||||
. = ALIGN(16);
|
||||
_bss = .;
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
. = ALIGN(16);
|
||||
_bss_end = .;
|
||||
}
|
||||
|
||||
.rela.dyn : { *(.rela.dyn) }
|
||||
.rela.plt : { *(.rela.plt) }
|
||||
.rela.got : { *(.rela.got) }
|
||||
.rela.data : { *(.rela.data) *(.rela.data*) }
|
||||
. = ALIGN(512);
|
||||
_edata = .;
|
||||
_data_size = . - _data;
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.rel.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
63
gnu-efi/gnuefi/elf_arm_efi.lds
Normal file
63
gnu-efi/gnuefi/elf_arm_efi.lds
Normal file
|
@ -0,0 +1,63 @@
|
|||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x0 : {
|
||||
_text = .;
|
||||
*(.text.head)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.srodata)
|
||||
*(.rodata*)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
_text_size = . - _text;
|
||||
.dynamic : { *(.dynamic) }
|
||||
.data :
|
||||
{
|
||||
_data = .;
|
||||
*(.sdata)
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
it all into .data: */
|
||||
. = ALIGN(16);
|
||||
_bss = .;
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(COMMON)
|
||||
. = ALIGN(16);
|
||||
_bss_end = .;
|
||||
}
|
||||
|
||||
.rel.dyn : { *(.rel.dyn) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rel.data : { *(.rel.data) *(.rel.data*) }
|
||||
_edata = .;
|
||||
_data_size = . - _etext;
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.rel.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
86
gnu-efi/gnuefi/elf_ia32_efi.lds
Normal file
86
gnu-efi/gnuefi/elf_ia32_efi.lds
Normal file
|
@ -0,0 +1,86 @@
|
|||
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
|
||||
OUTPUT_ARCH(i386)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
ImageBase = .;
|
||||
/* .hash and/or .gnu.hash MUST come first! */
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
. = ALIGN(4096);
|
||||
.text :
|
||||
{
|
||||
_text = .;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
_text_size = . - _text;
|
||||
. = ALIGN(4096);
|
||||
.sdata :
|
||||
{
|
||||
_data = .;
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.srodata)
|
||||
*(.sdata)
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.data :
|
||||
{
|
||||
*(.rodata*)
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.sdata)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
it all into .data: */
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
.rel :
|
||||
{
|
||||
*(.rel.data)
|
||||
*(.rel.data.*)
|
||||
*(.rel.got)
|
||||
*(.rel.stab)
|
||||
*(.data.rel.ro.local)
|
||||
*(.data.rel.local)
|
||||
*(.data.rel.ro)
|
||||
*(.data.rel*)
|
||||
}
|
||||
_edata = .;
|
||||
_data_size = . - _etext;
|
||||
. = ALIGN(4096);
|
||||
.reloc : /* This is the PECOFF .reloc section! */
|
||||
{
|
||||
*(.reloc)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.rel.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
86
gnu-efi/gnuefi/elf_ia32_fbsd_efi.lds
Normal file
86
gnu-efi/gnuefi/elf_ia32_fbsd_efi.lds
Normal file
|
@ -0,0 +1,86 @@
|
|||
OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd")
|
||||
OUTPUT_ARCH(i386)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
ImageBase = .;
|
||||
/* .hash and/or .gnu.hash MUST come first! */
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
. = ALIGN(4096);
|
||||
.text :
|
||||
{
|
||||
_text = .;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
_text_size = . - _text;
|
||||
. = ALIGN(4096);
|
||||
.sdata :
|
||||
{
|
||||
_data = .;
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.srodata)
|
||||
*(.sdata)
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.data :
|
||||
{
|
||||
*(.rodata*)
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.sdata)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
it all into .data: */
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
.rel :
|
||||
{
|
||||
*(.rel.data)
|
||||
*(.rel.data.*)
|
||||
*(.rel.got)
|
||||
*(.rel.stab)
|
||||
*(.data.rel.ro.local)
|
||||
*(.data.rel.local)
|
||||
*(.data.rel.ro)
|
||||
*(.data.rel*)
|
||||
}
|
||||
_edata = .;
|
||||
_data_size = . - _etext;
|
||||
. = ALIGN(4096);
|
||||
.reloc : /* This is the PECOFF .reloc section! */
|
||||
{
|
||||
*(.reloc)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.rel.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
81
gnu-efi/gnuefi/elf_ia64_efi.lds
Normal file
81
gnu-efi/gnuefi/elf_ia64_efi.lds
Normal file
|
@ -0,0 +1,81 @@
|
|||
OUTPUT_FORMAT("elf64-ia64-little")
|
||||
OUTPUT_ARCH(ia64)
|
||||
ENTRY(_start_plabel)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
ImageBase = .;
|
||||
/* .hash and/or .gnu.hash MUST come first! */
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
. = ALIGN(4096);
|
||||
.text :
|
||||
{
|
||||
_text = .;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
_text_size = . - _text;
|
||||
. = ALIGN(4096);
|
||||
__gp = ALIGN (8) + 0x200000;
|
||||
.sdata :
|
||||
{
|
||||
_data = .;
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.srodata)
|
||||
*(.sdata)
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.data :
|
||||
{
|
||||
*(.rodata*)
|
||||
*(.ctors)
|
||||
*(.data*)
|
||||
*(.gnu.linkonce.d*)
|
||||
*(.plabel) /* data whose relocs we want to ignore */
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
it all into .data: */
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
.rela :
|
||||
{
|
||||
*(.rela.text)
|
||||
*(.rela.data*)
|
||||
*(.rela.sdata)
|
||||
*(.rela.got)
|
||||
*(.rela.gnu.linkonce.d*)
|
||||
*(.rela.stab)
|
||||
*(.rela.ctors)
|
||||
}
|
||||
_edata = .;
|
||||
_data_size = . - _etext;
|
||||
. = ALIGN(4096);
|
||||
.reloc : /* This is the PECOFF .reloc section! */
|
||||
{
|
||||
*(.reloc)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.rela.plabel)
|
||||
*(.rela.reloc)
|
||||
*(.IA_64.unwind*)
|
||||
*(.IA64.unwind*)
|
||||
}
|
||||
}
|
64
gnu-efi/gnuefi/elf_mips64el_efi.lds
Normal file
64
gnu-efi/gnuefi/elf_mips64el_efi.lds
Normal file
|
@ -0,0 +1,64 @@
|
|||
OUTPUT_FORMAT("elf64-tradlittlemips", "elf64-tradbigmips", "elf64-tradlittlemips")
|
||||
OUTPUT_ARCH(mips)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x0 : {
|
||||
_text = .;
|
||||
*(.text.head)
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
*(.srodata)
|
||||
*(.rodata*)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
_text_size = . - _text;
|
||||
.dynamic : { *(.dynamic) }
|
||||
.data :
|
||||
{
|
||||
_data = .;
|
||||
*(.sdata)
|
||||
*(.data)
|
||||
*(.data1)
|
||||
*(.data.*)
|
||||
*(.got.plt)
|
||||
HIDDEN (_gp = ALIGN (16) + 0x7ff0);
|
||||
*(.got)
|
||||
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
it all into .data: */
|
||||
. = ALIGN(16);
|
||||
_bss = .;
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
. = ALIGN(16);
|
||||
_bss_end = .;
|
||||
}
|
||||
|
||||
.rel.dyn : { *(.rel.dyn) }
|
||||
.rel.plt : { *(.rel.plt) }
|
||||
.rel.got : { *(.rel.got) }
|
||||
.rel.data : { *(.rel.data) *(.rel.data*) }
|
||||
_edata = .;
|
||||
_data_size = . - _etext;
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.rel.reloc)
|
||||
*(.eh_frame)
|
||||
*(.MIPS.abiflags)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
76
gnu-efi/gnuefi/elf_x86_64_efi.lds
Normal file
76
gnu-efi/gnuefi/elf_x86_64_efi.lds
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* Same as elf_x86_64_fbsd_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */
|
||||
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
ImageBase = .;
|
||||
/* .hash and/or .gnu.hash MUST come first! */
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
. = ALIGN(4096);
|
||||
.eh_frame :
|
||||
{
|
||||
*(.eh_frame)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.text :
|
||||
{
|
||||
_text = .;
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.gnu.linkonce.t.*)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
_text_size = . - _text;
|
||||
. = ALIGN(4096);
|
||||
.reloc :
|
||||
{
|
||||
*(.reloc)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.data :
|
||||
{
|
||||
_data = .;
|
||||
*(.rodata*)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.data*)
|
||||
*(.sdata)
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
it all into .data: */
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
*(.rel.local)
|
||||
}
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
|
||||
_edata = .;
|
||||
_data_size = . - _etext;
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
.rela :
|
||||
{
|
||||
*(.rela.data*)
|
||||
*(.rela.got)
|
||||
*(.rela.stab)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
.ignored.reloc :
|
||||
{
|
||||
*(.rela.reloc)
|
||||
*(.eh_frame)
|
||||
*(.note.GNU-stack)
|
||||
}
|
||||
.comment 0 : { *(.comment) }
|
||||
}
|
70
gnu-efi/gnuefi/elf_x86_64_fbsd_efi.lds
Normal file
70
gnu-efi/gnuefi/elf_x86_64_fbsd_efi.lds
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* Same as elf_x86_64_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */
|
||||
OUTPUT_FORMAT("elf64-x86-64-freebsd", "elf64-x86-64-freebsd", "elf64-x86-64-freebsd")
|
||||
OUTPUT_ARCH(i386:x86-64)
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = 0;
|
||||
ImageBase = .;
|
||||
/* .hash and/or .gnu.hash MUST come first! */
|
||||
.hash : { *(.hash) }
|
||||
.gnu.hash : { *(.gnu.hash) }
|
||||
. = ALIGN(4096);
|
||||
.eh_frame :
|
||||
{
|
||||
*(.eh_frame)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.text :
|
||||
{
|
||||
_text = .;
|
||||
*(.text)
|
||||
. = ALIGN(16);
|
||||
}
|
||||
_etext = .;
|
||||
_text_size = . - _text;
|
||||
.reloc :
|
||||
{
|
||||
*(.reloc)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
.data :
|
||||
{
|
||||
_data = .;
|
||||
*(.rodata*)
|
||||
*(.got.plt)
|
||||
*(.got)
|
||||
*(.data*)
|
||||
*(.sdata)
|
||||
/* the EFI loader doesn't seem to like a .bss section, so we stick
|
||||
it all into .data: */
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
*(.rel.local)
|
||||
}
|
||||
.note.gnu.build-id : { *(.note.gnu.build-id) }
|
||||
|
||||
. = ALIGN(4096);
|
||||
.dynamic : { *(.dynamic) }
|
||||
. = ALIGN(4096);
|
||||
.rela :
|
||||
{
|
||||
*(.rela.data*)
|
||||
*(.rela.got)
|
||||
*(.rela.stab)
|
||||
}
|
||||
_edata = .;
|
||||
_data_size = . - _etext;
|
||||
. = ALIGN(4096);
|
||||
.dynsym : { *(.dynsym) }
|
||||
. = ALIGN(4096);
|
||||
.dynstr : { *(.dynstr) }
|
||||
. = ALIGN(4096);
|
||||
.ignored.reloc :
|
||||
{
|
||||
*(.rela.reloc)
|
||||
}
|
||||
}
|
97
gnu-efi/gnuefi/reloc_aarch64.c
Normal file
97
gnu-efi/gnuefi/reloc_aarch64.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* reloc_aarch64.c - position independent x86 ELF shared object relocator
|
||||
Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn,
|
||||
EFI_HANDLE image EFI_UNUSED,
|
||||
EFI_SYSTEM_TABLE *systab EFI_UNUSED)
|
||||
{
|
||||
long relsz = 0, relent = 0;
|
||||
Elf64_Rela *rel = 0;
|
||||
unsigned long *addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_RELA:
|
||||
rel = (Elf64_Rela*)
|
||||
((unsigned long)dyn[i].d_un.d_ptr
|
||||
+ ldbase);
|
||||
break;
|
||||
|
||||
case DT_RELASZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELAENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rel && relent == 0)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (!rel || relent == 0)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF64_R_TYPE (rel->r_info)) {
|
||||
case R_AARCH64_NONE:
|
||||
break;
|
||||
|
||||
case R_AARCH64_RELATIVE:
|
||||
addr = (unsigned long *)
|
||||
(ldbase + rel->r_offset);
|
||||
*addr = ldbase + rel->r_addend;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf64_Rela*) ((char *) rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
97
gnu-efi/gnuefi/reloc_arm.c
Normal file
97
gnu-efi/gnuefi/reloc_arm.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* reloc_arm.c - position independent x86 ELF shared object relocator
|
||||
Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
EFI_STATUS _relocate (long ldbase, Elf32_Dyn *dyn,
|
||||
EFI_HANDLE image EFI_UNUSED,
|
||||
EFI_SYSTEM_TABLE *systab EFI_UNUSED)
|
||||
{
|
||||
long relsz = 0, relent = 0;
|
||||
Elf32_Rel *rel = 0;
|
||||
unsigned long *addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_REL:
|
||||
rel = (Elf32_Rel*)
|
||||
((unsigned long)dyn[i].d_un.d_ptr
|
||||
+ ldbase);
|
||||
break;
|
||||
|
||||
case DT_RELSZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rel && relent == 0)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (!rel || relent == 0)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF32_R_TYPE (rel->r_info)) {
|
||||
case R_ARM_NONE:
|
||||
break;
|
||||
|
||||
case R_ARM_RELATIVE:
|
||||
addr = (unsigned long *)
|
||||
(ldbase + rel->r_offset);
|
||||
*addr += ldbase;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf32_Rel*) ((char *) rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
99
gnu-efi/gnuefi/reloc_ia32.c
Normal file
99
gnu-efi/gnuefi/reloc_ia32.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* reloc_ia32.c - position independent x86 ELF shared object relocator
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
EFI_STATUS _relocate (long ldbase, Elf32_Dyn *dyn,
|
||||
EFI_HANDLE image EFI_UNUSED,
|
||||
EFI_SYSTEM_TABLE *systab EFI_UNUSED)
|
||||
{
|
||||
long relsz = 0, relent = 0;
|
||||
Elf32_Rel *rel = 0;
|
||||
unsigned long *addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_REL:
|
||||
rel = (Elf32_Rel*)
|
||||
((unsigned long)dyn[i].d_un.d_ptr
|
||||
+ ldbase);
|
||||
break;
|
||||
|
||||
case DT_RELSZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELA:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rel && relent == 0)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (!rel || relent == 0)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF32_R_TYPE (rel->r_info)) {
|
||||
case R_386_NONE:
|
||||
break;
|
||||
|
||||
case R_386_RELATIVE:
|
||||
addr = (unsigned long *)
|
||||
(ldbase + rel->r_offset);
|
||||
*addr += ldbase;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf32_Rel*) ((char *) rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
227
gnu-efi/gnuefi/reloc_ia64.S
Normal file
227
gnu-efi/gnuefi/reloc_ia64.S
Normal file
|
@ -0,0 +1,227 @@
|
|||
/* reloc_ia64.S - position independent IA-64 ELF shared object relocator
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is written in assembly because the entire code needs to be position
|
||||
* independent. Note that the compiler does not generate code that's position
|
||||
* independent by itself because it relies on the global offset table being
|
||||
* relocated.
|
||||
*/
|
||||
.text
|
||||
.psr abi64
|
||||
.psr lsb
|
||||
.lsb
|
||||
|
||||
/*
|
||||
* This constant determines how many R_IA64_FPTR64LSB relocations we
|
||||
* can deal with. If you get EFI_BUFFER_TOO_SMALL errors, you may
|
||||
* need to increase this number.
|
||||
*/
|
||||
#define MAX_FUNCTION_DESCRIPTORS 750
|
||||
|
||||
#define ST_VALUE_OFF 8 /* offset of st_value in elf sym */
|
||||
|
||||
#define EFI_SUCCESS 0
|
||||
#define EFI_LOAD_ERROR 1
|
||||
#define EFI_BUFFER_TOO_SMALL 5
|
||||
|
||||
#define DT_NULL 0 /* Marks end of dynamic section */
|
||||
#define DT_RELA 7 /* Address of Rela relocs */
|
||||
#define DT_RELASZ 8 /* Total size of Rela relocs */
|
||||
#define DT_RELAENT 9 /* Size of one Rela reloc */
|
||||
#define DT_SYMTAB 6 /* Address of symbol table */
|
||||
#define DT_SYMENT 11 /* Size of one symbol table entry */
|
||||
|
||||
#define R_IA64_NONE 0
|
||||
#define R_IA64_REL64MSB 0x6e
|
||||
#define R_IA64_REL64LSB 0x6f
|
||||
#define R_IA64_DIR64MSB 0x26
|
||||
#define R_IA64_DIR64LSB 0x27
|
||||
#define R_IA64_FPTR64MSB 0x46
|
||||
#define R_IA64_FPTR64LSB 0x47
|
||||
|
||||
#define ldbase in0 /* load address (address of .text) */
|
||||
#define dyn in1 /* address of _DYNAMIC */
|
||||
|
||||
#define d_tag r16
|
||||
#define d_val r17
|
||||
#define rela r18
|
||||
#define relasz r19
|
||||
#define relaent r20
|
||||
#define addr r21
|
||||
#define r_info r22
|
||||
#define r_offset r23
|
||||
#define r_addend r24
|
||||
#define r_type r25
|
||||
#define r_sym r25 /* alias of r_type ! */
|
||||
#define fptr r26
|
||||
#define fptr_limit r27
|
||||
#define symtab f8
|
||||
#define syment f9
|
||||
#define ftmp f10
|
||||
|
||||
#define target r16
|
||||
#define val r17
|
||||
|
||||
#define NLOC 0
|
||||
|
||||
#define Pnull p6
|
||||
#define Prela p7
|
||||
#define Prelasz p8
|
||||
#define Prelaent p9
|
||||
#define Psymtab p10
|
||||
#define Psyment p11
|
||||
|
||||
#define Pnone p6
|
||||
#define Prel p7
|
||||
#define Pfptr p8
|
||||
|
||||
#define Pmore p6
|
||||
|
||||
#define Poom p6 /* out-of-memory */
|
||||
|
||||
.global _relocate
|
||||
.proc _relocate
|
||||
_relocate:
|
||||
alloc r2=ar.pfs,2,0,0,0
|
||||
movl fptr = @gprel(fptr_mem_base)
|
||||
;;
|
||||
add fptr = fptr, gp
|
||||
movl fptr_limit = @gprel(fptr_mem_limit)
|
||||
;;
|
||||
add fptr_limit = fptr_limit, gp
|
||||
|
||||
search_dynamic:
|
||||
ld8 d_tag = [dyn],8
|
||||
;;
|
||||
ld8 d_val = [dyn],8
|
||||
cmp.eq Pnull,p0 = DT_NULL,d_tag
|
||||
(Pnull) br.cond.sptk.few apply_relocs
|
||||
cmp.eq Prela,p0 = DT_RELA,d_tag
|
||||
cmp.eq Prelasz,p0 = DT_RELASZ,d_tag
|
||||
cmp.eq Psymtab,p0 = DT_SYMTAB,d_tag
|
||||
cmp.eq Psyment,p0 = DT_SYMENT,d_tag
|
||||
cmp.eq Prelaent,p0 = DT_RELAENT,d_tag
|
||||
;;
|
||||
(Prela) add rela = d_val, ldbase
|
||||
(Prelasz) mov relasz = d_val
|
||||
(Prelaent) mov relaent = d_val
|
||||
(Psymtab) add val = d_val, ldbase
|
||||
;;
|
||||
(Psyment) setf.sig syment = d_val
|
||||
;;
|
||||
(Psymtab) setf.sig symtab = val
|
||||
br.sptk.few search_dynamic
|
||||
|
||||
apply_loop:
|
||||
ld8 r_offset = [rela]
|
||||
add addr = 8,rela
|
||||
sub relasz = relasz,relaent
|
||||
;;
|
||||
|
||||
ld8 r_info = [addr],8
|
||||
;;
|
||||
ld8 r_addend = [addr]
|
||||
add target = ldbase, r_offset
|
||||
|
||||
add rela = rela,relaent
|
||||
extr.u r_type = r_info, 0, 32
|
||||
;;
|
||||
cmp.eq Pnone,p0 = R_IA64_NONE,r_type
|
||||
cmp.eq Prel,p0 = R_IA64_REL64LSB,r_type
|
||||
cmp.eq Pfptr,p0 = R_IA64_FPTR64LSB,r_type
|
||||
(Prel) br.cond.sptk.few apply_REL64
|
||||
;;
|
||||
cmp.eq Prel,p0 = R_IA64_DIR64LSB,r_type // treat DIR64 just like REL64
|
||||
|
||||
(Pnone) br.cond.sptk.few apply_relocs
|
||||
(Prel) br.cond.sptk.few apply_REL64
|
||||
(Pfptr) br.cond.sptk.few apply_FPTR64
|
||||
|
||||
mov r8 = EFI_LOAD_ERROR
|
||||
br.ret.sptk.few rp
|
||||
|
||||
apply_relocs:
|
||||
cmp.ltu Pmore,p0=0,relasz
|
||||
(Pmore) br.cond.sptk.few apply_loop
|
||||
|
||||
mov r8 = EFI_SUCCESS
|
||||
br.ret.sptk.few rp
|
||||
|
||||
apply_REL64:
|
||||
ld8 val = [target]
|
||||
;;
|
||||
add val = val,ldbase
|
||||
;;
|
||||
st8 [target] = val
|
||||
br.cond.sptk.few apply_relocs
|
||||
|
||||
// FPTR relocs are a bit more interesting: we need to lookup
|
||||
// the symbol's value in symtab, allocate 16 bytes of memory,
|
||||
// store the value in [target] in the first and the gp in the
|
||||
// second dword.
|
||||
apply_FPTR64:
|
||||
st8 [target] = fptr
|
||||
extr.u r_sym = r_info,32,32
|
||||
add target = 8,fptr
|
||||
;;
|
||||
|
||||
setf.sig ftmp = r_sym
|
||||
mov r8=EFI_BUFFER_TOO_SMALL
|
||||
;;
|
||||
cmp.geu Poom,p0 = fptr,fptr_limit
|
||||
|
||||
xma.lu ftmp = ftmp,syment,symtab
|
||||
(Poom) br.ret.sptk.few rp
|
||||
;;
|
||||
getf.sig addr = ftmp
|
||||
st8 [target] = gp
|
||||
;;
|
||||
add addr = ST_VALUE_OFF, addr
|
||||
;;
|
||||
ld8 val = [addr]
|
||||
;;
|
||||
add val = val,ldbase
|
||||
;;
|
||||
st8 [fptr] = val,16
|
||||
br.cond.sptk.few apply_relocs
|
||||
|
||||
.endp _relocate
|
||||
|
||||
.data
|
||||
.align 16
|
||||
fptr_mem_base:
|
||||
.space MAX_FUNCTION_DESCRIPTORS*16
|
||||
fptr_mem_limit:
|
115
gnu-efi/gnuefi/reloc_mips64el.c
Normal file
115
gnu-efi/gnuefi/reloc_mips64el.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* reloc_mips64el.c - position independent MIPS64 ELF shared object relocator
|
||||
Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
Copyright (C) 2017 Lemote Co.
|
||||
Contributed by Heiher <r@hev.cc>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn,
|
||||
EFI_HANDLE image EFI_UNUSED,
|
||||
EFI_SYSTEM_TABLE *systab EFI_UNUSED)
|
||||
{
|
||||
long relsz = 0, relent = 0, gotsz = 0;
|
||||
Elf64_Rel *rel = 0;
|
||||
unsigned long *addr = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_REL:
|
||||
rel = (Elf64_Rel*)
|
||||
((unsigned long)dyn[i].d_un.d_ptr
|
||||
+ ldbase);
|
||||
break;
|
||||
|
||||
case DT_RELSZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_PLTGOT:
|
||||
addr = (unsigned long *)
|
||||
((unsigned long)dyn[i].d_un.d_ptr
|
||||
+ ldbase);
|
||||
break;
|
||||
|
||||
case DT_MIPS_LOCAL_GOTNO:
|
||||
gotsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!rel && relent == 0) && (!addr && gotsz == 0))
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if ((!rel && relent != 0) || (!addr && gotsz != 0))
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (gotsz > 0) {
|
||||
*addr += ldbase;
|
||||
addr += 1;
|
||||
gotsz --;
|
||||
}
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF64_R_TYPE (swap_uint64 (rel->r_info))) {
|
||||
case R_MIPS_NONE:
|
||||
break;
|
||||
|
||||
case (R_MIPS_64 << 8) | R_MIPS_REL32:
|
||||
addr = (unsigned long *)
|
||||
(ldbase + rel->r_offset);
|
||||
*addr += ldbase;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf64_Rel*) ((char *) rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
98
gnu-efi/gnuefi/reloc_x86_64.c
Normal file
98
gnu-efi/gnuefi/reloc_x86_64.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/* reloc_x86_64.c - position independent x86_64 ELF shared object relocator
|
||||
Copyright (C) 1999 Hewlett-Packard Co.
|
||||
Contributed by David Mosberger <davidm@hpl.hp.com>.
|
||||
Copyright (C) 2005 Intel Co.
|
||||
Contributed by Fenghua Yu <fenghua.yu@intel.com>.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of Hewlett-Packard Co. nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn,
|
||||
EFI_HANDLE image EFI_UNUSED,
|
||||
EFI_SYSTEM_TABLE *systab EFI_UNUSED)
|
||||
{
|
||||
long relsz = 0, relent = 0;
|
||||
Elf64_Rel *rel = 0;
|
||||
unsigned long *addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
|
||||
switch (dyn[i].d_tag) {
|
||||
case DT_RELA:
|
||||
rel = (Elf64_Rel*)
|
||||
((unsigned long)dyn[i].d_un.d_ptr
|
||||
+ ldbase);
|
||||
break;
|
||||
|
||||
case DT_RELASZ:
|
||||
relsz = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
case DT_RELAENT:
|
||||
relent = dyn[i].d_un.d_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rel && relent == 0)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
if (!rel || relent == 0)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
while (relsz > 0) {
|
||||
/* apply the relocs */
|
||||
switch (ELF64_R_TYPE (rel->r_info)) {
|
||||
case R_X86_64_NONE:
|
||||
break;
|
||||
|
||||
case R_X86_64_RELATIVE:
|
||||
addr = (unsigned long *)
|
||||
(ldbase + rel->r_offset);
|
||||
*addr += ldbase;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rel = (Elf64_Rel*) ((char *) rel + relent);
|
||||
relsz -= relent;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
27
gnu-efi/inc/Makefile
Normal file
27
gnu-efi/inc/Makefile
Normal file
|
@ -0,0 +1,27 @@
|
|||
SRCDIR = .
|
||||
|
||||
VPATH = $(SRCDIR)
|
||||
|
||||
include $(SRCDIR)/../Make.defaults
|
||||
|
||||
TOPDIR = $(SRCDIR)/..
|
||||
|
||||
CDIR=$(TOPDIR)/..
|
||||
|
||||
all:
|
||||
|
||||
clean:
|
||||
|
||||
install:
|
||||
mkdir -p $(INSTALLROOT)$(PREFIX)/include/efi
|
||||
mkdir -p $(INSTALLROOT)$(PREFIX)/include/efi/protocol
|
||||
mkdir -p $(INSTALLROOT)$(PREFIX)/include/efi/$(ARCH)
|
||||
$(INSTALL) -m 644 $(SRCDIR)/*.h $(INSTALLROOT)$(PREFIX)/include/efi
|
||||
$(INSTALL) -m 644 $(SRCDIR)/protocol/*.h $(INSTALLROOT)$(PREFIX)/include/efi/protocol
|
||||
$(INSTALL) -m 644 $(SRCDIR)/$(ARCH)/*.h $(INSTALLROOT)$(PREFIX)/include/efi/$(ARCH)
|
||||
ifeq ($(ARCH),ia64)
|
||||
mkdir -p $(INSTALLROOT)$(PREFIX)/include/efi/protocol/ia64
|
||||
$(INSTALL) -m 644 $(SRCDIR)/protocol/ia64/*.h $(INSTALLROOT)$(PREFIX)/include/efi/protocol/ia64
|
||||
endif
|
||||
|
||||
include $(SRCDIR)/../Make.rules
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user