Добавлена поддержка TGA

This commit is contained in:
Aren 2023-10-19 19:46:58 +03:00
parent 3825c1a1d8
commit 4a233e13ad
16 changed files with 236 additions and 8607 deletions

View File

@ -5,6 +5,7 @@
"bitset": "cpp",
"string_view": "cpp",
"initializer_list": "cpp",
"complex": "cpp"
"complex": "cpp",
"string": "cpp"
}
}

BIN
boot.tga Normal file

Binary file not shown.

View File

@ -3,13 +3,14 @@ TIMEOUT=5
DEFAULT_ENTRY=0
INTERFACE_BRANDING=By Aren Elchinyan
BACKGROUND_STYLE=stretched
BACKGROUND_PATH=boot:///boot.png
BACKGROUND_PATH=boot:///boot.tga
#TERM_FONT=boot:///CYRILL2.F16
#TERM_FONT_SIZE=8x16
:BMOSP (KASLR on)
#RESOLUTION=640x480
#RESOLUTION=1024x768
RESOLUTION=1280x720
PROTOCOL=limine
KASLR=no
KERNEL_PATH=boot:///kernel.elf
@ -17,5 +18,5 @@ BACKGROUND_PATH=boot:///boot.png
MODULE_PATH=boot:///mod/hello.so
MODULE_CMDLINE=[MOD]hello.so
MODULE_PATH=boot:///boot.png
MODULE_PATH=boot:///boot.tga
MODULE_CMDLINE=[BOOTIMG]

View File

@ -5,7 +5,7 @@
namespace fb {
void init( );
void print_buf(size_t x, size_t y, size_t h, size_t w, uint32_t *buf);
void printf(char *str, ...);
void printf_at(size_t x, size_t y, char *str, ...);

View File

@ -1,4 +1,5 @@
namespace mem {
void dump_memory( );
void init( );
void *alloc(size_t size);
void free(void *addr);

View File

@ -23,7 +23,7 @@
static inline void pause( ) {
for (uint64_t i = 0; i < 1024; i++) {
for (uint64_t j = 0; j < 1024; j++) {
for (uint64_t q = 0; q < 4; q++) { asm volatile("pause"); }
for (uint64_t q = 0; q < 8; q++) { asm volatile("pause"); }
}
}
}

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 1
#define VERSION_BUILD 135
#define VERSION_BUILD 198

View File

@ -3,6 +3,21 @@
#include <stdint.h>
#include <tool.h>
extern "C" {
void sse_init( ) {
uint64_t _cr0 = 0;
asm volatile("mov %0, %%cr0" : "=r"(_cr0) : : "memory");
_cr0 &= ~(1 << 2);
_cr0 |= (1 << 1);
asm volatile("mov %%cr0, %0" : : "r"(_cr0) : "memory");
uint64_t _cr4 = 0;
asm volatile("mov %0, %%cr4" : "=r"(_cr4) : : "memory");
_cr4 |= (3 << 9);
asm volatile("mov %%cr4, %0" : : "r"(_cr4) : "memory");
}
}
namespace cpu {
static bool acpi_msrs_support = false;
static bool mmx_support = false;
@ -102,28 +117,6 @@ void brandname( ) {
if (manufacturer[0] == 0x68747541) { do_amd( ); }
}
void sse_init( ) {
asm volatile("clts\n"
"mov %%cr0, %%rax\n"
"and $0xFFFD, %%ax\n"
"or $0x10, %%ax\n"
"mov %%rax, %%cr0\n"
"fninit\n"
"mov %%cr0, %%rax\n"
"and $0xfffb, %%ax\n"
"or $0x0002, %%ax\n"
"mov %%rax, %%cr0\n"
"mov %%cr4, %%rax\n"
"or $0x600, %%rax\n"
"mov %%rax, %%cr4\n"
"push $0x1F80\n"
"ldmxcsr (%%rsp)\n"
"addq $8, %%rsp\n"
:
:
: "rax");
}
void init( ) {
uint32_t eax, ebx, ecx, edx;
cpuid(1, &eax, &ebx, &ecx, &edx);
@ -132,8 +125,8 @@ void init( ) {
if ((edx >> 22) & 1) {
acpi_msrs_support = true;
fb::printf("Температура: %u\n", get_cpu_temperature( ));
fb::printf("Встроенный терморегулятор MSRS для ACPI\n");
fb::printf("Температура: %u\n", get_cpu_temperature( ));
}
if ((edx >> 23) & 1) {
@ -144,7 +137,7 @@ void init( ) {
if ((edx >> 25) & 1) {
sse2_support = true;
fb::printf("SSE2 подерживается!\n");
sse_init( );
// sse_init( );
}
cpuid(1, &eax, &ebx, &ecx, &edx);
@ -164,7 +157,12 @@ void init( ) {
fb::printf("RDRND подерживается!\n");
}
cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
if ((edx >> 11) & 1) { fb::printf("SYSCALL подерживается!\n"); }
if ((edx >> 29) & 1) { fb::printf("AMD64 подерживается!\n"); }
brandname( );
l2_cache( );
// l2_cache( );
}
} // namespace cpu

View File

@ -24,7 +24,7 @@ static volatile struct limine_framebuffer_request framebuffer_request = {
struct limine_framebuffer_response *framebuffer_response;
struct limine_framebuffer *boot_framebuffer;
uint32_t *fb_addr;
uint32_t text_color = GREEN;
uint32_t background = DARK_GREEN;
uint64_t width;
@ -46,12 +46,22 @@ void init( ) {
width = boot_framebuffer->width;
height = boot_framebuffer->height;
bpp = boot_framebuffer->bpp;
pitch = boot_framebuffer->pitch;
for (uint64_t i = 0; i < width * height; i++) { fb_addr[i] = background; }
fb::printf("0x%x %ux%u\n", fb_addr, width, height);
}
void print_buf(size_t x, size_t y, size_t h, size_t w, uint32_t *buf) {
for (size_t j = 0; j < h; j++) {
for (size_t i = 0; i < w; i++) {
uint64_t where = (i + x) + (j + y) * width;
SCREEN_BUFFER[where] = buf[i + j * w];
}
}
}
static inline void print_bits(size_t x, size_t y, uint8_t num) {
for (size_t i = 0; i <= 7; i++) {
if ((num >> i) & 1) {

View File

@ -5,76 +5,172 @@ extern void *bootpng_ptr;
extern uint64_t bootpng_size;
extern "C" {
void *realloc(void *pointer, int new_size) {
return mem::realloc(pointer, new_size);
}
typedef struct {
unsigned char magic1; // must be zero
unsigned char colormap; // must be zero
unsigned char encoding; // must be 2
unsigned short cmaporig, cmaplen; // must be zero
unsigned char cmapent; // must be zero
unsigned short x; // must be zero
unsigned short y; // image's height
unsigned short h; // image's height
unsigned short w; // image's width
unsigned char bpp; // must be 32
unsigned char pixeltype; // must be 40
} __attribute__((packed)) tga_header_t;
void free(void *pointer) {
free(pointer);
}
#define memcpy(x, y, z) tool::memcpy(x, y, z)
#define memset(x, y, z) tool::memset(x, y, z)
#define STB_IMAGE_IMPLEMENTATION
#define STBI_ASSERT(x) assert(x)
#define malloc(sz) \
mem::alloc(sz); \
fb::printf("malloc(%uКБ) %s, %s, %u\n", sz / 1024, __FILE__, __FUNCTION__, \
__LINE__);
#define STBI_MALLOC(sz) malloc(sz)
#define STBI_REALLOC(p, newsz) realloc(p, newsz)
#define STBI_FREE(p) free(p)
#define STBI_NO_STDIO
#define STBI_NO_LINEAR
#define STBI_NO_HDR
#define STBI_NO_SIMD
#define STBI_ONLYPNG
#include "stb_image.h"
unsigned int *tga_parse(unsigned char *ptr, int size) {
unsigned int *data;
int i, j, k, x, y, w = (ptr[13] << 8) + ptr[12],
h = (ptr[15] << 8) + ptr[14],
o = (ptr[11] << 8) + ptr[10];
int m = ((ptr[1] ? (ptr[7] >> 3) * ptr[5] : 0) + 18);
unsigned int *png_parse(unsigned char *ptr, int size) {
int i, w, h, f;
unsigned char *img, *p;
stbi__context s;
stbi__result_info ri;
s.read_from_callbacks = 0;
s.img_buffer = s.img_buffer_original = ptr;
s.img_buffer_end = s.img_buffer_original_end = ptr + size;
ri.bits_per_channel = 8;
img = p = (unsigned char *)stbi__png_load(&s, (int *)&w, (int *)&h,
(int *)&f, 1, &ri);
unsigned int *data =
(unsigned int *)malloc((w * h + 2) * sizeof(unsigned int));
fb::printf("Выделено %u\n", (w * h + 2) * sizeof(unsigned int));
pause( );
pause( );
pause( );
pause( );
if (w < 1 || h < 1) return NULL;
data = (unsigned int *)mem::alloc((w * h + 2) * sizeof(unsigned int));
if (!data) {
// free(img);
fb::printf("Err %u, %x, %u kb\n", __LINE__, data,
((w * h + 2) * sizeof(unsigned int)) / 1024);
return NULL;
}
for (i = 0; i < w * h; i++, p += f) switch (f) {
case 1:
data[2 + i] = 0xFF000000 | (p[0] << 16) | (p[0] << 8) | p[0];
break;
case 2:
data[2 + i] = (p[1] << 24) | (p[0] << 16) | (p[0] << 8) | p[0];
break;
case 3:
data[2 + i] = 0xFF000000 | (p[0] << 16) | (p[1] << 8) | p[2];
break;
case 4:
data[2 + i] = (p[3] << 24) | (p[0] << 16) | (p[1] << 8) | p[2];
break;
switch (ptr[2]) {
case 1:
if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 ||
(ptr[7] != 24 && ptr[7] != 32)) {
fb::printf("Err %u\n", __LINE__);
mem::free(data);
return NULL;
}
for (y = i = 0; y < h; y++) {
k = ((!o ? h - y - 1 : y) * w);
for (x = 0; x < w; x++) {
j = ptr[m + k++] * (ptr[7] >> 3) + 18;
data[2 + i++] = ((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) |
ptr[j];
}
}
break;
case 2:
if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 ||
(ptr[16] != 24 && ptr[16] != 32)) {
fb::printf("Err %u\n", __LINE__);
mem::free(data);
return NULL;
}
for (y = i = 0; y < h; y++) {
j = ((!o ? h - y - 1 : y) * w * (ptr[16] >> 3));
for (x = 0; x < w; x++) {
data[2 + i++] =
((ptr[16] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
j += ptr[16] >> 3;
}
}
break;
case 9:
if (ptr[6] != 0 || ptr[4] != 0 || ptr[3] != 0 ||
(ptr[7] != 24 && ptr[7] != 32)) {
fb::printf("Err %u\n", __LINE__);
mem::free(data);
return NULL;
}
y = i = 0;
for (x = 0; x < w * h && m < size;) {
k = ptr[m++];
if (k > 127) {
k -= 127;
x += k;
j = ptr[m++] * (ptr[7] >> 3) + 18;
while (k--) {
if (!(i % w)) {
i = ((!o ? h - y - 1 : y) * w);
y++;
}
data[2 + i++] =
((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
}
} else {
k++;
x += k;
while (k--) {
j = ptr[m++] * (ptr[7] >> 3) + 18;
if (!(i % w)) {
i = ((!o ? h - y - 1 : y) * w);
y++;
}
data[2 + i++] =
((ptr[7] == 32 ? ptr[j + 3] : 0xFF) << 24) |
(ptr[j + 2] << 16) | (ptr[j + 1] << 8) | ptr[j];
}
}
}
break;
case 10:
if (ptr[5] != 0 || ptr[6] != 0 || ptr[1] != 0 ||
(ptr[16] != 24 && ptr[16] != 32)) {
fb::printf("Err %u\n", __LINE__);
mem::free(data);
return NULL;
}
y = i = 0;
for (x = 0; x < w * h && m < size;) {
k = ptr[m++];
if (k > 127) {
k -= 127;
x += k;
while (k--) {
if (!(i % w)) {
i = ((!o ? h - y - 1 : y) * w);
y++;
}
data[2 + i++] =
((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) |
(ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m];
}
m += ptr[16] >> 3;
} else {
k++;
x += k;
while (k--) {
if (!(i % w)) {
i = ((!o ? h - y - 1 : y) * w);
y++;
}
data[2 + i++] =
((ptr[16] == 32 ? ptr[m + 3] : 0xFF) << 24) |
(ptr[m + 2] << 16) | (ptr[m + 1] << 8) | ptr[m];
m += ptr[16] >> 3;
}
}
}
break;
default: {
fb::printf("Err %u\n", __LINE__);
mem::free(data);
return NULL;
}
// free(img);
}
data[0] = w;
data[1] = h;
return data;
}
void main( ) {
fb::printf("Загрузка завершена! 1\n");
unsigned int *data = png_parse((unsigned char *)bootpng_ptr, bootpng_size);
fb::printf("Загрузка завершена! 2 %x\n", data);
unsigned int *res = tga_parse((uint8_t *)bootpng_ptr, bootpng_size);
fb::printf("Загрузка завершена! 2 %x\n", res);
tga_header_t *head = (tga_header_t *)bootpng_ptr;
if (res != NULL) {
fb::printf("Размер экрана загрузки: %ux%u \n", res[0], res[1]);
}
fb::printf("Размер экрана загрузки: %ux%u \n", head->h, head->w);
mem::dump_memory( );
fb::print_buf(0, 0, head->w, head->h, (uint32_t *)(res + 2));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,16 @@ static mem_entry_t *first_node;
namespace mem {
void dump_memory( ) {
mem_entry_t *curr = first_node;
while (curr) {
fb::printf("->0x%x | %u kb | %u | 0x%x\n", &curr->data,
curr->size / 1024, curr->free, curr->next);
curr = curr->next;
}
}
void frame_free(void *addr, uint64_t frames) {
// Проход по фреймам памяти и очистка битов в битовой карте
uint64_t frame = (uint64_t)addr / BLOCK_SIZE;
@ -92,6 +102,15 @@ void *frame_calloc(uint64_t frames) {
return addr;
}
void merge_blocks(mem_entry_t *start) {
if (!start->free) return;
mem_entry_t *block = start;
while (block->next && block->next->free) {
block->size += block->next->size + sizeof(mem_entry_t);
block->next = block->next->next;
}
}
void add_block(void *addr, size_t size) {
mem_entry_t *new_entry = (mem_entry_t *)addr;
@ -108,6 +127,7 @@ void add_block(void *addr, size_t size) {
curr->next = new_entry;
new_entry->next = NULL;
}
merge_blocks(first_node);
}
void alloc_init(void *address, size_t length) {
@ -118,15 +138,6 @@ void alloc_init(void *address, size_t length) {
first_node->next = NULL;
}
void merge_blocks(mem_entry_t *start) {
if (!start->free) return;
mem_entry_t *block = start;
while (block->next && block->next->free) {
block->size += block->next->size + sizeof(mem_entry_t);
block->next = block->next->next;
}
}
void *alloc_align(size_t size, size_t alignment) {
mem_entry_t *curr = first_node;
@ -158,7 +169,6 @@ void *alloc_align(size_t size, size_t alignment) {
curr = curr->next;
}
return NULL;
}
@ -257,16 +267,21 @@ void init( ) {
fb::printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit);
fb::printf("Размер битовой карты: %u\n", bitmap_size);
for (uint64_t i = 0; i < 256; i++) {
alloc_init(frame_alloc(100), 100 * BLOCK_SIZE);
alloc_init(frame_alloc(100), 1000 * BLOCK_SIZE);
for (uint64_t i = 0; i < 255; i++) {
add_block(frame_alloc(100), 1000 * BLOCK_SIZE);
}
mem::dump_memory( );
merge_blocks(first_node);
mem::dump_memory( );
fb::printf("%u мегабайт выделено в динамичную память\n",
(256 * 100 * BLOCK_SIZE) / 1024 / 1024);
(256 * 1000 * BLOCK_SIZE) / 1024 / 1024);
fb::printf("%u МБ объем доступной памяти, %u МБ объем виртуальной памяти\n",
(bitmap_available * BLOCK_SIZE) / 1024 / 1024,
available / 1024 / 1024);
fb::printf("%u / %u блоков доступно\n", bitmap_available, bitmap_limit);
fb::printf("Проверка менеджера памяти\n");
}
} // namespace mem

View File

@ -27,7 +27,9 @@ env_t main_env;
extern "C" {
void *bootpng_ptr;
uint64_t bootpng_size;
void main( );
}
void *elf_entry(void *module_bin, uint64_t size) {
// Приводим заголовок ELF файла к типу elf64_header_t
elf64_header_t *elf_header = (elf64_header_t *)module_bin;
@ -92,6 +94,7 @@ void init( ) {
fb::printf("\t\t[BOOTIMG]\n");
bootpng_ptr = module_ptr->address;
bootpng_size = module_ptr->size;
main( );
continue;
}
if (!tool::starts_with(module_ptr->cmdline, "[MOD]")) { continue; }

View File

@ -7,8 +7,6 @@
#include <tool.h>
#include <version.h>
extern "C" void main( );
// Точка входа
extern "C" void _start( ) {
asm volatile("cli");
@ -17,13 +15,11 @@ extern "C" void _start( ) {
arch::init( );
cpu::init( );
mem::init( );
mod::init( );
fb::printf("\t\t\t\t *** Базовая Модульная Платформа Операционных Систем "
"версии %u.%u.%u ***\n",
VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD);
fb::printf("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__);
mod::init( );
fb::printf("Пауза...\n");
pause( );
main( );
for (;;) { asm volatile("hlt"); }
}

View File

@ -119,7 +119,7 @@ def create_hdd(IMAGE_NAME):
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"limine/BOOTX64.EFI", "limine/BOOTIA32.EFI", "::/EFI/BOOT"])
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"boot.png", "::/"])
"boot.tga", "::/"])
subprocess.run(["./limine/limine", "bios-install", IMAGE_NAME+".hdd"])
@ -128,7 +128,7 @@ def create_iso(IMAGE_NAME):
subprocess.run(["rm", "-rf", "iso_root"])
subprocess.run(["mkdir", "-p", "iso_root"])
subprocess.run(["cp", "-v", "iso_root/"])
subprocess.run(["cp", "-v", "kernel.elf", "boot.png",
subprocess.run(["cp", "-v", "kernel.elf", "boot.tga",
"configs/limine.cfg", "limine/limine-bios.sys",
"limine/limine-bios-cd.bin", "limine/limine-uefi-cd.bin",
"iso_root/"])

4
run.sh
View File

@ -1,2 +1,4 @@
#!/bin/sh
qemu-system-x86_64 -cpu max -m 1G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd
#qemu-system-x86_64 -cpu max -m 1G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd -d int --no-reboot
#qemu-system-x86_64 -cpu host -m 1G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd
qemu-system-x86_64 -enable-kvm -cpu host -m 6G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd -d int --no-reboot