Compare commits

...

16 Commits

Author SHA1 Message Date
PoliEcho 92e474853b Update README.md 2025-08-19 19:33:50 +00:00
PoliEcho 24e7c443a1 fix aarch64 compilation 2025-08-19 21:13:02 +02:00
PoliEcho 37f63d51b9 README additions 2025-08-19 20:11:57 +02:00
PoliEcho 09ff9f8f19 some misc changes 2025-08-19 19:30:50 +02:00
PoliEcho 83df1a6048 Update README.md 2025-08-19 17:05:27 +02:00
PoliEcho 36a7c9066a misc changes 2025-08-19 16:38:32 +02:00
PoliEcho 9b768a4e9e README and build.sh changes 2025-08-19 16:35:16 +02:00
PoliEcho 868d27cecb update edk2 2025-08-18 23:16:58 +02:00
PoliEcho c72a80832b forgot to commit README 2025-08-18 21:05:24 +02:00
PoliEcho 54a54de423 enhance build script 2025-08-18 21:05:04 +02:00
PoliEcho 8af36091ba add input 2025-08-18 20:47:56 +02:00
PoliEcho fa35f79e34 addtions to test script 2025-08-17 15:14:07 +02:00
PoliEcho 83ef67ad28 fix rockets a bit 2025-08-17 14:37:30 +02:00
PoliEcho 91001e09ba add rockets 2025-08-16 16:29:37 +02:00
PoliEcho 8c53885621 update gitignore 2025-08-16 16:28:59 +02:00
PoliEcho 887e393d92 polishing a bit 2025-08-16 13:20:03 +02:00
21 changed files with 475 additions and 64 deletions
+1
View File
@@ -1,3 +1,4 @@
build/
.cache/
compile_commands.json
src/UEFI_fireworks/rocket.c
+86 -3
View File
@@ -1,5 +1,88 @@
Arch uefi_run fix: sudo ln -s /usr/share/edk2/x64/OVMF_CODE.4m.fd /usr/share/qemu/OVMF.fd
# UEFI Fireworks
### Retro fireworks you can run on your modern UEFI system
Simple automatic fireworks app that runs on your UEFI firmware with basic controls.
Primary purpose of this app is just to look at something nice.
cd edk2
> [!CAUTION]
> This app may cause epileptic seizures in people with epilepsy.
> $\color{red}{\text{!!!If you have a history of seizures, do not use this program!!!}}$
> I don't know if colorful expanding circles can cause seizures and i don't want for anyone to get hurt
## How to build
> [!IMPORTANT]
> You will need these programs to compile:
> - git
> - gcc
> - xxd
> - ImageMagick (if you changed the firework image)
```bash
git submodule update --init --recursive
cd edk2
source edksetup.sh
make -C BaseTools # if first run
make -C BaseTools
cd ..
./build.sh # to build for a different arch than X64 change TARGET_ARCH in build.sh
```
## How to use
### Download release
#### On real hardware
If you have an amd64 (x86_64) UEFI computer,
download the release and copy UEFI_fireworks.efi to /EFI/BOOT/bootx64.efi (case-insensitive).
#### On VM
You will need OVMF firmware; you can get it here: https://qemu.weilnetz.de/test/ovmf/usr/share/OVMF/OVMF_CODE_4M.fd
Run:
```bash
qemu-system-x86_64 -machine type=q35,accel=kvm -drive if=pflash,format=raw,readonly=on,file="$OVMF_CODE_PATH" -hda fat:rw:build -boot order=c -smp 4 -s -serial mon:stdio
```
### Build
#### On VM
You will need OVMF firmware; you can get it here: https://qemu.weilnetz.de/test/ovmf/usr/share/OVMF/OVMF_CODE_4M.fd
Run:
```bash
./test.sh $OVMF_CODE_PATH # only works on AMD64
```
to run in a VM using QEMU.
#### On real hardware
Copy:
```
edk2/Build/UEFI_fireworks/DEBUG_GCC5//UEFI_fireworks.efi
```
to a FAT32 or FAT16 USB at the following location:
| Architecture | Default Boot Path |
| --------------- | ------------------------ |
| x86_64 (AMD64) | `/EFI/BOOT/BOOTX64.EFI` |
| x86 (IA32) | `/EFI/BOOT/BOOTIA32.EFI` |
| ARM64 (AARCH64) | `/EFI/BOOT/BOOTAA64.EFI` |
| ARM (32-bit) | `/EFI/BOOT/BOOTARM.EFI` |
## Controlling
| Key | Action | Note |
| ---------- | ------------ | ---------------------------------- |
| ARROW_UP | speed up | delays under 1ms may be unreliable |
| ARROW_DOWN | slow down | max delay is about UINT32_MAX μs |
| PAGE_UP | speed up | 10× step |
| PAGE_DOWN | slow down | 10× step |
| Home | reset speed | reset frame delay to 10ms |
| Delete | clear screen | |
## Showcase
In QEMU/KVM
https://github.com/user-attachments/assets/275e28aa-eb2e-4348-ac08-95f909c46a1f
+3 -1
View File
@@ -4,7 +4,7 @@
PLATFORM_VERSION = 1.0
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/UEFI_fireworks
SUPPORTED_ARCHITECTURES = X64
SUPPORTED_ARCHITECTURES = X64|IA32|AARCH64
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
@@ -30,6 +30,8 @@ LocalApicLib|edk2/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
CpuLib|edk2/MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
UefiRuntimeServicesTableLib|edk2/MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
TimerLib|edk2/MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
BmpSupportLib|edk2/MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
SafeIntLib|edk2/MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
[Components]
src/UEFI_fireworks/UEFI_fireworks.inf
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
View File
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

+14 -4
View File
@@ -1,10 +1,20 @@
#!/bin/bash
export PACKAGES_PATH=$PWD:$PWD/edk2
export TARGET_ARCH=X64
# export GCC5_AARCH64_PREFIX=aarch64-linux-gnu- # uncomment for AARCH64 crosscompilation or you can use
# export GCC5_AARCH64_PREFIX=aarch64-none-elf-
magick assets/rocket_orig.bmp -type TrueColor -define bmp:format=bmp3 -compress None assets/rocket.bmp
xxd -i assets/rocket.bmp > src/UEFI_fireworks/rocket.c
if [ "$1" == "debug" ]; then
build -a X64 -t GCC5 -p UEFI_fireworks.dsc -b DEBUG
build -a $TARGET_ARCH -t GCC5 -p UEFI_fireworks.dsc -b DEBUG
else
build -a X64 -t GCC5 -p UEFI_fireworks.dsc
build -a $TARGET_ARCH -t GCC5 -p UEFI_fireworks.dsc -b RELEASE
fi
mkdir -p build/EFI/BOOT/
cp edk2/Build/UEFI_fireworks/DEBUG_GCC5/X64/UEFI_fireworks.efi build/
cp edk2/Build/UEFI_fireworks/DEBUG_GCC5/X64/UEFI_fireworks.efi build/EFI/BOOT/BOOTX64.EFI
if [ "$1" == "debug" ]; then
cp -v $(find edk2/Build/UEFI_fireworks/DEBUG_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/
cp -v $(find edk2/Build/UEFI_fireworks/DEBUG_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/EFI/BOOT/BOOTX64.EFI
else
cp -v $(find edk2/Build/UEFI_fireworks/RELEASE_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/
cp -v $(find edk2/Build/UEFI_fireworks/RELEASE_GCC5/ -name "UEFI_fireworks.efi" -type f | head -1) build/EFI/BOOT/BOOTX64.EFI
fi
+1 -1
Submodule edk2 updated: 808f1f1f87...d46aa46c83
+6 -1
View File
@@ -6,11 +6,15 @@
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain
[Sources]
[Sources.Common]
UefiMain.c
drawing.c
rng.c
time.c
rocket.c
[Sources.AARCH64]
memcpy.c
[Packages]
edk2/MdePkg/MdePkg.dec
@@ -30,6 +34,7 @@
RngLib
SerialPortLib
UefiRuntimeServicesTableLib
BmpSupportLib
[Protocols]
gEfiRngProtocolGuid
+91 -14
View File
@@ -1,5 +1,7 @@
#include "Library/UefiApplicationEntryPoint.h"
#include "ProcessorBind.h"
#include "Protocol/SimpleTextIn.h"
#include "Uefi/UefiBaseType.h"
#include "const.h"
#include "drawing.h"
#include "global.h"
#include "macros.h"
@@ -18,7 +20,9 @@
#include <Protocol/GraphicsOutput.h>
#include <Uefi.h>
#include <stdint.h>
EFI_GRAPHICS_OUTPUT_BLT_PIXEL night_sky =
COLOR_FROM_HEX(0x090531); // this cannot be const becose EDK2 said so
#define DEFAULT_SLEEP_TIME 10000
firework_instance create_firework();
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *framebuffer = NULL;
@@ -48,10 +52,11 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
return EFI_NOT_FOUND;
}
framebuffer =
(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)GraphicsOutput->Mode->FrameBufferBase;
framebuffer = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)(UINTN)
GraphicsOutput->Mode->FrameBufferBase;
init_rng();
init_rocket_blt();
if (SerialPortInitialize() == RETURN_SUCCESS) {
SERIAL_PRINT("Serial initialized\n");
@@ -67,14 +72,15 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
0); // make all pointers null
SERIAL_PRINT("DOES it work?\n");
Print(L"If you see this message timer does not work\n");
milisleep(100);
Print(L"If you see this message for long time, timer does not work\n");
microsleep(1);
clear_screen();
UINTN sleep_time = DEFAULT_SLEEP_TIME;
while (TRUE) {
UINT8 random;
fill_random_bytes(&random, sizeof(random));
if (random % 6 == 0) {
if (random % 30 == 0) {
// spawn new firework
firework_instance *new_firework_instence =
AllocateZeroPool(sizeof(firework_instance));
@@ -85,7 +91,8 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
*new_firework_instence = create_firework();
for (UINT8 i = 0; i < ARRAY_SIZE(firework_array); i++) {
if (firework_array[i] == NULL || firework_array[i]->active != TRUE) {
if (firework_array[i] == NULL ||
firework_array[i]->status == INACTIVE) {
if (firework_array[i] != NULL) {
FreePool(firework_array[i]); // free firework
firework_array[i] = NULL;
@@ -99,9 +106,13 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
assgned:
for (UINT8 i = 0; i < ARRAY_SIZE(firework_array); i++) {
if (firework_array[i] != NULL) {
if (firework_array[i]->active == TRUE) {
if (firework_array[i]->status == ACTIVE) {
if (!step_firework(firework_array[i])) {
firework_array[i]->active = FALSE;
firework_array[i]->status = INACTIVE;
}
} else if (firework_array[i]->status == LAUNCHING) {
if (!step_rocket(&firework_array[i]->rocket, firework_array[i]->y)) {
firework_array[i]->status = ACTIVE;
}
} else {
FreePool(firework_array[i]); // free firework
@@ -109,8 +120,71 @@ EFI_STATUS EFIAPI UefiMain(IN EFI_HANDLE imgHandle,
}
}
}
EFI_INPUT_KEY key;
EFI_STATUS status = gST->ConIn->ReadKeyStroke(gST->ConIn, &key);
gST->ConIn->Reset(gST->ConIn, FALSE);
if (status == EFI_SUCCESS) {
switch (key.ScanCode) {
case SCAN_UP: // increase simulation speed
milisleep(10);
if (sleep_time > 100) {
sleep_time = sleep_time - 100;
} else if (sleep_time > 10) {
sleep_time = sleep_time - 10;
} else if (sleep_time > 1) {
sleep_time = sleep_time - 1;
}
break;
case SCAN_DOWN:
if (sleep_time < UINT32_MAX - 100) {
sleep_time = sleep_time + 100;
} else if (sleep_time < UINT32_MAX - 10) {
sleep_time = sleep_time + 10;
} else if (sleep_time < UINT32_MAX - 1) {
sleep_time = sleep_time + 1;
}
break;
case SCAN_PAGE_UP:
if (sleep_time > 1000) {
sleep_time = sleep_time - 1000;
} else if (sleep_time > 100) {
sleep_time = sleep_time - 100;
} else if (sleep_time > 10) {
sleep_time = sleep_time - 10;
} else if (sleep_time > 1) {
sleep_time = sleep_time - 1;
}
break;
case SCAN_PAGE_DOWN:
if (sleep_time < UINT32_MAX - 1000) {
sleep_time = sleep_time + 1000;
} else if (sleep_time < UINT32_MAX - 100) {
sleep_time = sleep_time + 100;
} else if (sleep_time < UINT32_MAX - 10) {
sleep_time = sleep_time + 10;
} else if (sleep_time < UINT32_MAX - 1) {
sleep_time = sleep_time + 1;
}
break;
case SCAN_HOME:
sleep_time = DEFAULT_SLEEP_TIME;
break;
case SCAN_DELETE:
for (UINT8 i = 0; i < ARRAY_SIZE(firework_array); i++) {
if (firework_array[i] != NULL) {
FreePool(firework_array[i]);
firework_array[i] = NULL;
}
}
// clear_screen(); does not work on real hardware here for some unknown
// reason
for (UINTN i = 0; i < GraphicsOutput->Mode->FrameBufferSize; i++) {
framebuffer[i] = night_sky;
}
break;
}
}
microsleep(sleep_time);
}
return EFI_SUCCESS;
@@ -120,7 +194,7 @@ firework_instance create_firework() {
firework_instance firework;
UINT32 random;
fill_random_bytes(&random, sizeof(random));
firework.max_r = (random % 200) + 1; // 1 to 200, avoiding 0
firework.max_r = (random % 190) + 10; // 10 to 200,
for (UINT8 i = 0; i < ARRAY_SIZE(firework.color); i++) {
fill_random_bytes(&firework.color[i],
@@ -132,8 +206,11 @@ firework_instance create_firework() {
fill_random_bytes(&random, sizeof(random));
firework.x = random % GraphicsOutput->Mode->Info->HorizontalResolution;
fill_random_bytes(&random, sizeof(random));
firework.y = random % GraphicsOutput->Mode->Info->VerticalResolution;
firework.y = random % GraphicsOutput->Mode->Info->VerticalResolution /
2; // spawn only on upper half of the screen
firework.active = TRUE;
firework.rocket.x = firework.x + rocket_asset.width / 2;
firework.rocket.y = GraphicsOutput->Mode->Info->VerticalResolution;
firework.status = LAUNCHING;
return firework;
}
+3
View File
@@ -0,0 +1,3 @@
#pragma once
extern unsigned char assets_rocket_bmp[];
extern unsigned int assets_rocket_bmp_len;
+3 -2
View File
@@ -2,5 +2,6 @@
#include "macros.h"
#include <Protocol/GraphicsOutput.h>
EFI_GRAPHICS_OUTPUT_BLT_PIXEL night_sky =
COLOR_FROM_HEX(0x11095e); // this cannot be const becose EDK2 said so
extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL night_sky;
enum firework_status { INACTIVE, ACTIVE, LAUNCHING };
+70 -3
View File
@@ -1,17 +1,23 @@
#include "Base.h"
#include "Library/BaseMemoryLib.h"
#include "Library/MemoryAllocationLib.h"
#include "Library/UefiLib.h"
#include "ProcessorBind.h"
#include "bmp.h"
#include "const.h"
#include "global.h"
#include "time.h"
#include "types.h"
#include <../MdeModulePkg/Include/Library/BmpSupportLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Protocol/GraphicsOutput.h>
#include <alloca.h>
void draw_pixel(const UINT32 x, const UINT32 y,
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL pixel) {
if (x > GraphicsOutput->Mode->Info->HorizontalResolution ||
y > GraphicsOutput->Mode->Info
->VerticalResolution) { // ignore when out of bounds
if (x >= GraphicsOutput->Mode->Info->HorizontalResolution ||
y >= GraphicsOutput->Mode->Info
->VerticalResolution) { // ignore when out of bounds
return;
}
UINTN framebuffer_offset =
@@ -105,3 +111,64 @@ BOOLEAN step_firework(firework_instance *firework) {
}
return TRUE;
}
rocket_blt rocket_asset;
BOOLEAN **rocket_alfa_mask;
UINT32 *rocket_clean_up_mask;
void init_rocket_blt() {
EFI_STATUS Status = TranslateBmpToGopBlt(
assets_rocket_bmp, assets_rocket_bmp_len, &rocket_asset.blt,
&rocket_asset.blt_size, &rocket_asset.height, &rocket_asset.width);
if (EFI_ERROR(Status)) {
Print(L"Failed to load rocket asset: %r\n", Status);
Exit(Status);
}
rocket_clean_up_mask = AllocatePool(rocket_asset.width * sizeof(location));
rocket_alfa_mask = AllocateZeroPool(rocket_asset.height * sizeof(BOOLEAN *));
for (UINT32 i = 0; i < rocket_asset.height; i++) {
rocket_alfa_mask[i] = AllocatePool(rocket_asset.width * sizeof(BOOLEAN));
for (UINT32 j = 0; j < rocket_asset.width; j++) {
if (rocket_asset.blt[i * rocket_asset.width + j].Blue == 0 &&
rocket_asset.blt[i * rocket_asset.width + j].Green == 0 &&
rocket_asset.blt[i * rocket_asset.width + j].Red == 0) {
rocket_alfa_mask[i][j] = FALSE;
} else {
rocket_alfa_mask[i][j] = TRUE;
rocket_clean_up_mask[j] = i + 1; // build the cleanup mask
}
}
}
}
void draw_rocket(location *rocket) {
for (UINT32 i = 0; i < rocket_asset.width; i++) {
for (UINT32 j = 0; j < rocket_asset.height; j++) {
if (rocket_alfa_mask[j][i]) {
draw_pixel(i + rocket->x, j + rocket->y,
rocket_asset.blt[j * rocket_asset.width + i]);
}
}
}
}
BOOLEAN step_rocket(location *rocket, UINT32 max_y) {
draw_rocket(rocket);
for (UINT8 i = 0; i < rocket_asset.width; i++) {
draw_pixel(rocket->x + i, rocket->y + rocket_clean_up_mask[i], night_sky);
}
if (rocket->y <= max_y) {
// remove rocket
for (UINT32 i = 0; i < rocket_asset.width; i++) {
for (UINT32 j = 0; j < rocket_asset.height; j++) {
if (rocket_alfa_mask[j][i]) {
draw_pixel(i + rocket->x, j + rocket->y, night_sky);
}
}
}
return FALSE;
} else {
rocket->y--;
return TRUE;
}
}
+2
View File
@@ -5,3 +5,5 @@ void draw_circle(int xc, int yc, int r,
const EFI_GRAPHICS_OUTPUT_BLT_PIXEL color);
void clear_screen();
BOOLEAN step_firework(firework_instance *firework);
void init_rocket_blt();
BOOLEAN step_rocket(location *rocket, UINT32 max_y);
+2
View File
@@ -1,4 +1,6 @@
#pragma once
#include "types.h"
#include <Protocol/GraphicsOutput.h>
extern EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL *framebuffer;
extern rocket_blt rocket_asset;
+96
View File
@@ -0,0 +1,96 @@
#include <Library/BaseLib.h>
#include <Uefi.h>
VOID *memcpy(VOID *CONST Destination, CONST VOID *Source, UINTN Length) {
UINT8 *Dest = (UINT8 *)Destination;
CONST UINT8 *Src = (CONST UINT8 *)Source;
if (Length < 16) {
switch (Length) {
case 15:
*Dest++ = *Src++;
case 14:
*Dest++ = *Src++;
case 13:
*Dest++ = *Src++;
case 12:
*Dest++ = *Src++;
case 11:
*Dest++ = *Src++;
case 10:
*Dest++ = *Src++;
case 9:
*Dest++ = *Src++;
case 8:
*Dest++ = *Src++;
case 7:
*Dest++ = *Src++;
case 6:
*Dest++ = *Src++;
case 5:
*Dest++ = *Src++;
case 4:
*Dest++ = *Src++;
case 3:
*Dest++ = *Src++;
case 2:
*Dest++ = *Src++;
case 1:
*Dest++ = *Src++;
case 0:
break;
}
return Destination;
}
#ifdef MDE_CPU_X64
typedef UINT64 WORD_T;
#else
typedef UINT32 WORD_T;
#endif
while ((UINTN)Dest & (sizeof(WORD_T) - 1)) {
*Dest++ = *Src++;
Length--;
}
WORD_T *WordDest = (WORD_T *)Dest;
CONST WORD_T *WordSrc = (CONST WORD_T *)Src;
while (Length >= 8 * sizeof(WORD_T)) {
WordDest[0] = WordSrc[0];
WordDest[1] = WordSrc[1];
WordDest[2] = WordSrc[2];
WordDest[3] = WordSrc[3];
WordDest[4] = WordSrc[4];
WordDest[5] = WordSrc[5];
WordDest[6] = WordSrc[6];
WordDest[7] = WordSrc[7];
WordDest += 8;
WordSrc += 8;
Length -= 8 * sizeof(WORD_T);
}
while (Length >= 4 * sizeof(WORD_T)) {
WordDest[0] = WordSrc[0];
WordDest[1] = WordSrc[1];
WordDest[2] = WordSrc[2];
WordDest[3] = WordSrc[3];
WordDest += 4;
WordSrc += 4;
Length -= 4 * sizeof(WORD_T);
}
while (Length >= sizeof(WORD_T)) {
*WordDest++ = *WordSrc++;
Length -= sizeof(WORD_T);
}
Dest = (UINT8 *)WordDest;
Src = (CONST UINT8 *)WordSrc;
while (Length--) {
*Dest++ = *Src++;
}
return Destination;
}
+68 -21
View File
@@ -2,12 +2,14 @@
#include "Library/UefiBootServicesTableLib.h"
#include "Library/UefiLib.h"
#include "ProcessorBind.h"
#include "Uefi/UefiBaseType.h"
#include "time.h"
#include <Library/BaseLib.h>
#include <Library/RngLib.h>
#include <Library/TimerLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Uefi.h>
#include <stdint.h>
void (*fill_random_bytes)(void *dst, UINTN n);
UINT16 shift_LFSR(UINT16 LFSR) {
@@ -19,22 +21,6 @@ UINT16 shift_LFSR(UINT16 LFSR) {
return LFSR;
}
void fill_random_bytes_LFSR(void *dst, UINTN n) {
static UINT16 LFSR = 0xf5d7;
if (n % 2 != 0) {
LFSR = shift_LFSR(LFSR);
*(UINT8 *)dst = (UINT8)LFSR;
dst++;
n--;
}
while (n != 0) {
LFSR = shift_LFSR(LFSR);
*(UINT16 *)dst = LFSR;
dst += 2;
n -= 2;
}
}
void fill_random_bytes_TRUE(void *dst, UINTN n) {
UINT16 rand;
if (n % 2 != 0) {
@@ -50,6 +36,21 @@ void fill_random_bytes_TRUE(void *dst, UINTN n) {
n -= 2;
}
}
UINT16 LFSR;
void fill_random_bytes_LFSR(void *dst, UINTN n) {
if (n % 2 != 0) {
LFSR = shift_LFSR(LFSR);
*(UINT8 *)dst = (UINT8)LFSR;
dst++;
n--;
}
while (n != 0) {
LFSR = shift_LFSR(LFSR);
*(UINT16 *)dst = LFSR;
dst += 2;
n -= 2;
}
}
void init_rng() {
UINT16 test_var;
@@ -59,12 +60,58 @@ void init_rng() {
gST->ConOut->SetAttribute(gST->ConOut, EFI_YELLOW);
Print(L"[WARNING]");
gST->ConOut->SetAttribute(gST->ConOut, EFI_WHITE);
Print(L" RNG device not available falling back to LFSR\r\n");
Print(L" RNG device not available falling back to LFSR!\r\n");
Print(L"Continuing in ");
for (UINT8 i = 5; i > 0; i--) {
Print(L"\b%d", i);
milisleep(1000);
EFI_TIME Time;
EFI_STATUS Status;
UINT32 starting;
Status = gRT->GetTime(&Time, NULL);
if (EFI_ERROR(Status)) {
Print(L"failed to get time\r\n");
microsleep(2000000);
starting = 1;
} else {
starting = Time.Second;
}
Print(L"Press any key to seed the LFSR\r\n");
EFI_INPUT_KEY Key;
UINTN Index;
Status = gBS->WaitForEvent(1, &(gST->ConIn->WaitForKey), &Index);
if (EFI_ERROR(Status)) {
Print(L"failed to wait key\r\n");
Key.ScanCode = 1;
Key.UnicodeChar = 1;
} else {
Status = gST->ConIn->ReadKeyStroke(gST->ConIn, &Key);
if (EFI_ERROR(Status)) {
Print(L"failed to read key\r\n");
Key.ScanCode = 1;
Key.UnicodeChar = 1;
}
}
if (Key.ScanCode == 0) {
Key.ScanCode = 1;
}
Status = gRT->GetTime(&Time, NULL);
if (EFI_ERROR(Status)) {
Print(L"failed to get time\r\n");
Time.Second = 1;
}
UINT8 time_diff = (Time.Second - starting);
if (time_diff == 0) {
time_diff = 1;
}
LFSR = (typeof(LFSR))(((UINTN)Key.ScanCode * (UINTN)Key.UnicodeChar *
(UINTN)(time_diff)) %
UINT16_MAX);
if (LFSR <= 1) {
LFSR = 0xf5d7;
}
fill_random_bytes = fill_random_bytes_LFSR;
+2 -2
View File
@@ -1,7 +1,7 @@
#include "Library/UefiLib.h"
#include <Library/UefiBootServicesTableLib.h>
EFI_STATUS
milisleep(UINTN Milliseconds) {
microsleep(UINTN n) {
EFI_STATUS Status;
EFI_EVENT TimerEvent;
@@ -13,7 +13,7 @@ milisleep(UINTN Milliseconds) {
}
Status = gBS->SetTimer(TimerEvent, TimerRelative,
EFI_TIMER_PERIOD_MILLISECONDS(Milliseconds));
EFI_TIMER_PERIOD_MICROSECONDS(n));
if (!EFI_ERROR(Status)) {
gBS->WaitForEvent(1, &TimerEvent, NULL);
+1 -1
View File
@@ -1,2 +1,2 @@
#pragma once
void milisleep(UINTN Milliseconds);
void microsleep(UINTN n);
+16 -1
View File
@@ -1,13 +1,28 @@
#pragma once
#include "ProcessorBind.h"
#include "Protocol/GraphicsOutput.h"
#include "const.h"
#include <Library/BaseLib.h>
typedef struct {
BOOLEAN active; // IF FALSE can be overwriten
UINT32 x;
UINT32 y;
} location;
typedef struct {
enum firework_status status; // IF INACTIVE can be overwriten
UINT32 x;
UINT32 y;
UINT16 max_r;
UINT16 r[3];
EFI_GRAPHICS_OUTPUT_BLT_PIXEL color[3];
UINT16 cleanup_r;
location rocket;
} firework_instance;
typedef struct {
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *blt;
UINTN blt_size;
UINTN height;
UINTN width;
} rocket_blt;
+6 -6
View File
@@ -1,16 +1,16 @@
#!/bin/bash
cp /usr/share/edk2/x64/OVMF_VARS.4m.fd ./my_ovmf_vars.fd
if [ $# -ge 1 ]; then
OVMF_CODE_PATH=$1
else
OVMF_CODE_PATH=/usr/share/edk2/x64/OVMF_CODE.4m.fd
fi
qemu-system-x86_64 \
-machine type=q35,accel=kvm \
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \
-drive if=pflash,format=raw,file=./my_ovmf_vars.fd \
-drive if=pflash,format=raw,readonly=on,file="$OVMF_CODE_PATH" \
-hda fat:rw:build \
-boot order=c \
-smp 4 \
-s \
-serial mon:stdio
rm ./my_ovmf_vars.fd