More examples

merge-requests/1/head
bzt 3 years ago
parent 430c3baf70
commit 45d41bc1ca

@ -8,4 +8,4 @@ all: $(wildcard examples/*)
@test -f $@/Makefile && make -C $@ all 2>/dev/null
test:
qemu-system-x86_64 -bios $(OVMF) -m 64 -enable-kvm -hda fat:rw:examples
qemu-system-x86_64 -sdl -bios $(OVMF) -m 64 -enable-kvm -hda fat:rw:examples

@ -70,7 +70,7 @@ int main(int argc, char **argv)
efi_guid_t gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
efi_gop_t *gop = NULL;
efi_gop_mode_info_t *info = NULL;
uintn_t isiz = sizeof(efi_gop_mode_info_t), currentMode, i;
uintn_t isiz = sizeof(efi_gop_mode_info_t);
FILE *f;
long int size;

@ -28,7 +28,7 @@ int main(int argc, char **argv)
efi_guid_t gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
efi_gop_t *gop = NULL;
efi_gop_mode_info_t *info = NULL;
uintn_t isiz = sizeof(efi_gop_mode_info_t), currentMode, i;
uintn_t isiz = sizeof(efi_gop_mode_info_t);
FILE *f;
ssfn_font_t *font;
long int size;

@ -0,0 +1,4 @@
TARGET = png.efi
#USE_GCC=1
include uefi/Makefile

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

@ -0,0 +1,80 @@
#include <uefi.h>
/* public domain image loader - http://nothings.org/stb_image.h */
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
/**
* Display PNG image
*/
int main(int argc, char **argv)
{
efi_status_t status;
efi_guid_t gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
efi_gop_t *gop = NULL;
efi_gop_mode_info_t *info = NULL;
uintn_t isiz = sizeof(efi_gop_mode_info_t), currentMode, i;
FILE *f;
unsigned char *buff;
uint32_t *data;
int w, h, l;
long int size;
stbi__context s;
stbi__result_info ri;
/* load image */
if((f = fopen("\\0C_png\\image.png", "r"))) {
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
buff = (unsigned char*)malloc(size);
if(!buff) {
fprintf(stderr, "unable to allocate memory\n");
return 1;
}
fread(buff, size, 1, f);
fclose(f);
ri.bits_per_channel = 8;
s.read_from_callbacks = 0;
s.img_buffer = s.img_buffer_original = buff;
s.img_buffer_end = s.img_buffer_original_end = buff + size;
data = (uint32_t*)stbi__png_load(&s, &w, &h, &l, 0, &ri);
if(!data) {
fprintf(stderr, "Unable to decode png: %s\n", stbi__g_failure_reason);
return 0;
}
} else {
fprintf(stderr, "Unable to load image\n");
return 0;
}
/* set video mode */
status = BS->LocateProtocol(&gopGuid, NULL, (void**)&gop);
if(!EFI_ERROR(status) && gop) {
status = gop->SetMode(gop, 0);
ST->ConOut->Reset(ST->ConOut, 0);
ST->StdErr->Reset(ST->StdErr, 0);
if(EFI_ERROR(status)) {
fprintf(stderr, "unable to set video mode\n");
return 0;
}
} else {
fprintf(stderr, "unable to get graphics output protocol\n");
return 0;
}
/* display image */
if(gop->Mode->Information->PixelFormat == PixelBlueGreenRedReserved8BitPerColor ||
(gop->Mode->Information->PixelFormat == PixelBitMask && gop->Mode->Information->PixelInformation.BlueMask != 0xff0000)) {
/* png is RGBA, but UEFI needs BGRA */
for(l = 0; l < w * h; l++)
data[l] = ((data[l] & 0xff) << 16) | (data[l] & 0xff00) | ((data[l] >> 16) & 0xff);
}
gop->Blt(gop, data, EfiBltBufferToVideo, 0, 0, (gop->Mode->Information->HorizontalResolution - w) / 2,
(gop->Mode->Information->VerticalResolution - h) / 2, w, h, 0);
/* free resources exit */
free(data);
free(buff);
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load Diff

@ -0,0 +1 @@
../../uefi

@ -0,0 +1,4 @@
TARGET = memmap.efi
#USE_GCC=1
include uefi/Makefile

@ -0,0 +1,53 @@
#include <uefi.h>
/**
* List memory map
*/
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
efi_status_t status;
efi_memory_descriptor_t *memory_map = NULL, *mement;
uintn_t memory_map_size=0, map_key=0, desc_size=0, i;
const char *types[] = {
"EfiReservedMemoryType",
"EfiLoaderCode",
"EfiLoaderData",
"EfiBootServicesCode",
"EfiBootServicesData",
"EfiRuntimeServicesCode",
"EfiRuntimeServicesData",
"EfiConventionalMemory",
"EfiUnusableMemory",
"EfiACPIReclaimMemory",
"EfiACPIMemoryNVS",
"EfiMemoryMappedIO",
"EfiMemoryMappedIOPortSpace",
"EfiPalCode"
};
/* get the memory map */
status = BS->GetMemoryMap(&memory_map_size, NULL, &map_key, &desc_size, NULL);
if(status != EFI_BUFFER_TOO_SMALL || !memory_map_size) goto err;
memory_map_size += 2 * desc_size;
memory_map = (efi_memory_descriptor_t*)malloc(memory_map_size);
if(!memory_map) {
fprintf(stderr, "unable to allocate memory\n");
return 1;
}
status = BS->GetMemoryMap(&memory_map_size, memory_map, &map_key, &desc_size, NULL);
if(EFI_ERROR(status)) {
err: fprintf(stderr, "Unable to get memory map\n");
return 0;
}
printf("Address Size Type\n");
for(mement = memory_map; (uint8_t*)mement < (uint8_t*)memory_map + memory_map_size;
mement = NextMemoryDescriptor(mement, desc_size)) {
printf("%016x %8d %02x %s\n", mement->PhysicalStart, mement->NumberOfPages, mement->Type, types[mement->Type]);
}
free(memory_map);
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

@ -40,7 +40,7 @@ void __stdio_cleanup()
{
#if USE_UTF8
if(__argvutf8)
free(__argvutf8);
BS->FreePool(__argvutf8);
#endif
if(__blk_devs) {
free(__blk_devs);
@ -466,7 +466,7 @@ int vsnprintf(char_t *dst, size_t maxlen, const char_t *fmt, __builtin_va_list a
uint8_t *mem;
int64_t arg;
int len, sign, i, j;
char_t *p, *orig=dst, *end = dst + maxlen - 1, tmpstr[19], pad=CL(' '), n;
char_t *p, *orig=dst, *end = dst + maxlen - 1, tmpstr[19], pad, n;
char *c;
if(dst==NULL || fmt==NULL)
@ -477,7 +477,7 @@ int vsnprintf(char_t *dst, size_t maxlen, const char_t *fmt, __builtin_va_list a
if(*fmt==CL('%')) {
fmt++;
if(*fmt==CL('%')) goto put;
len=0;
len=0; pad=CL(' ');
if(*fmt==CL('0')) pad=CL('0');
while(*fmt>=CL('0') && *fmt<=CL('9')) {
len *= 10;

@ -33,6 +33,8 @@
int errno = 0;
static uint64_t __srand_seed = 6364136223846793005ULL;
extern void __stdio_cleanup();
static uintptr_t *__stdlib_allocs = NULL;
static uintn_t __stdlib_numallocs = 0;
int atoi(const char_t *s)
{
@ -76,8 +78,24 @@ int64_t strtol (const char_t *s, char_t **__endptr, int __base)
void *malloc (size_t __size)
{
void *ret = NULL;
efi_status_t status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
efi_status_t status;
uintn_t i;
/* this is so fucked up. UEFI firmware must keep track of allocated sizes internally, yet we must
* too, because realloc won't work otherwise... Why can't AllocatePool accept input addresses? */
for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != 0; i += 2);
if(i == __stdlib_numallocs) {
status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __stdlib_numallocs + 2, &ret);
if(EFI_ERROR(status) || !ret) { errno = ENOMEM; return NULL; }
if(__stdlib_allocs) memcpy(ret, __stdlib_allocs, __stdlib_numallocs * sizeof(uintptr_t));
__stdlib_allocs = (uintptr_t*)ret;
__stdlib_allocs[i] = __stdlib_allocs[i + 1] = 0;
__stdlib_numallocs += 2;
ret = NULL;
}
status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
if(EFI_ERROR(status) || !ret) { errno = ENOMEM; ret = NULL; }
__stdlib_allocs[i] = (uintptr_t)ret;
__stdlib_allocs[i + 1] = (uintptr_t)__size;
return ret;
}
@ -90,35 +108,52 @@ void *calloc (size_t __nmemb, size_t __size)
void *realloc (void *__ptr, size_t __size)
{
#if 1
void *ret = __ptr;
/* not sure if this works */
efi_status_t status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
void *ret = NULL;
efi_status_t status;
uintn_t i;
if(!__ptr) return malloc(__size);
for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != (uintptr_t)__ptr; i += 2);
if(i == __stdlib_numallocs) { errno = ENOMEM; return NULL; }
status = BS->AllocatePool(LIP ? LIP->ImageDataType : EfiLoaderData, __size, &ret);
if(EFI_ERROR(status) || !ret) { errno = ENOMEM; ret = NULL; }
if(ret) {
memcpy(ret, (void*)__stdlib_allocs[i], __stdlib_allocs[i + 1] < __size ? __stdlib_allocs[i + 1] : __size);
if(__size > __stdlib_allocs[i + 1]) memset(ret + __stdlib_allocs[i + 1], 0, __size - __stdlib_allocs[i + 1]);
}
BS->FreePool((void*)__stdlib_allocs[i]);
__stdlib_allocs[i] = (uintptr_t)ret;
__stdlib_allocs[i + 1] = (uintptr_t)__size;
return ret;
#else
void *ret = malloc(__size);
/* this isn't perfect, because we don't know the original size... */
if(ret && __ptr) memcpy(ret, __ptr, __size);
if(__ptr) free(__ptr);
return ret;
#endif
}
void free (void *__ptr)
{
efi_status_t status = BS->FreePool(__ptr);
efi_status_t status;
uintn_t i;
for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] != (uintptr_t)__ptr; i += 2);
if(i == __stdlib_numallocs) { errno = ENOMEM; return; }
__stdlib_allocs[i] = 0;
__stdlib_allocs[i + 1] = 0;
for(i = 0; i < __stdlib_numallocs && __stdlib_allocs[i] == 0; i += 2);
if(i == __stdlib_numallocs) { BS->FreePool(__stdlib_allocs); __stdlib_allocs = NULL; __stdlib_numallocs = 0; }
status = BS->FreePool(__ptr);
if(EFI_ERROR(status)) errno = ENOMEM;
}
void abort ()
{
if(__stdlib_allocs)
BS->FreePool(__stdlib_allocs);
__stdlib_numallocs = 0;
__stdio_cleanup();
BS->Exit(IM, EFI_ABORTED, 0, NULL);
}
void exit (int __status)
{
if(__stdlib_allocs)
BS->FreePool(__stdlib_allocs);
__stdlib_numallocs = 0;
__stdio_cleanup();
BS->Exit(IM, !__status ? 0 : (__status < 0 ? EFIERR(-__status) : EFIERR(__status)), 0, NULL);
}
@ -128,6 +163,9 @@ int exit_bs()
efi_status_t status;
efi_memory_descriptor_t *memory_map = NULL;
uintn_t cnt = 3, memory_map_size=0, map_key=0, desc_size=0, i;
if(__stdlib_allocs)
BS->FreePool(__stdlib_allocs);
__stdlib_numallocs = 0;
__stdio_cleanup();
while(cnt--) {
status = BS->GetMemoryMap(&memory_map_size, memory_map, &map_key, &desc_size, NULL);

Loading…
Cancel
Save