From 0c2fe1e32107a88122300be5c76f1948dd070ed1 Mon Sep 17 00:00:00 2001 From: portasynthinca3 Date: Sat, 15 Feb 2020 20:55:09 +0300 Subject: [PATCH] Update README; INITRD driver; window transparency --- README.md | 2 +- builder.py | 45 +++++++++++++++++++++++++++++++++++++++++--- initrd/hello.txt | 1 + initrd/hello2.txt | 1 + nbuild | 5 +---- src/drivers/gfx.c | 12 ++++++++---- src/drivers/initrd.c | 36 ++++++++++++++++++++++++++++++----- src/drivers/initrd.h | 10 ++++++++++ src/gui/controls.c | 12 ++++++------ src/gui/gui.c | 14 +++++++------- src/stdlib.h | 2 +- 11 files changed, 109 insertions(+), 31 deletions(-) create mode 100644 initrd/hello.txt create mode 100644 initrd/hello2.txt diff --git a/README.md b/README.md index d386e6b..b3b2842 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Neutron is the result of me trying to get into the low-level stuff. This project is **not** intended to do some crazy stuff like replacing the giants like Windows, Linux and macOS. That's just not possible. However, it doesn't mean i don't have an end goal. **The end goal is to write a simple 64-bit UEFI-powered OS that can run 3rd party applications and its GUI system, while requiring as little disk space, RAM and processor resources as possible.** Oh, and also, I just want to have fun :) # Who is involved? * Me, Andrey Antonenko, the creator, maintainer and programmer -* Sasha Kulichkov, booted this on his PC several times; created the logo +* Sasha Kulichkov, graphical designer and tester # Where does it work? In theory, it should work on any modern system. Here are the minimal requirements: * CPU: x86-64 architecture diff --git a/builder.py b/builder.py index 6ef4347..7eb96a0 100644 --- a/builder.py +++ b/builder.py @@ -1,4 +1,6 @@ import sys, os, time +from os import listdir +from os.path import isfile, join class bcolors: HEADER = '\033[95m' @@ -47,14 +49,12 @@ def execute(cmd): if not line.startswith('#'): if line.startswith('.'): config_section = line[1:] - if not config_section in ['c', 'fs']: + if not config_section in ['c']: print('Error: ' + config_file + ':' + str(line_no + 1) + ': invalid section "' + config_section + '"') sys.exit() else: if config_section == 'c': c_files.append(line) - elif config_section == 'fs': - fs_files.append(line) else: print('Error: ' + config_file + ':' + str(line_no + 1) + ': data in invalid section "' + config_section + '"') sys.exit() @@ -69,6 +69,43 @@ def execute(cmd): print_status('Linking') execute('x86_64-w64-mingw32-gcc -mcmodel=large -mno-red-zone -m64 -nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -o build/BOOTX64.EFI ' + ' '.join(c_obj)) + +print_status('Building INITRD') +initrd_img = bytearray() +initrd_files = [f for f in listdir('initrd') if isfile(join('initrd', f))] +initrd_size = 64 +for f in initrd_files: + initrd_size = initrd_size + 64 + os.path.getsize(join('initrd', f)) #64 bytes per file entry +print("INITRD size: " + str(initrd_size) + " bytes (" + str(initrd_size // 1024) + " kB, " + str(len(initrd_files)) + " files)") +initrd_img = bytearray(initrd_size) +initrd_file_pos = (len(initrd_files) + 1) * 64 +initrd_file_list_pos = 0 +for f in initrd_files: + with open(join('initrd', f), 'rb') as file: + f_data = file.read() + size_bytes = os.path.getsize(join('initrd', f)).to_bytes(4, byteorder="little") + pos_bytes = initrd_file_pos.to_bytes(4, byteorder="little") + initrd_img[initrd_file_list_pos + 0] = pos_bytes[0] + initrd_img[initrd_file_list_pos + 1] = pos_bytes[1] + initrd_img[initrd_file_list_pos + 2] = pos_bytes[2] + initrd_img[initrd_file_list_pos + 3] = pos_bytes[3] + initrd_file_list_pos = initrd_file_list_pos + 4 + initrd_img[initrd_file_list_pos + 0] = size_bytes[0] + initrd_img[initrd_file_list_pos + 1] = size_bytes[1] + initrd_img[initrd_file_list_pos + 2] = size_bytes[2] + initrd_img[initrd_file_list_pos + 3] = size_bytes[3] + initrd_file_list_pos = initrd_file_list_pos + 4 + for c in f: + initrd_img[initrd_file_list_pos] = ord(c) + initrd_file_list_pos = initrd_file_list_pos + 1 + initrd_img[initrd_file_list_pos] = 0 + initrd_file_list_pos = initrd_file_list_pos + 56 - len(f) + for b in f_data: + initrd_img[initrd_file_pos] = b + initrd_file_pos = initrd_file_pos + 1 +with open('build/initrd', 'wb') as initrd_file: + initrd_file.write(initrd_img) + print_status('Bulding system image') print(' Creating image file') execute('dd if=/dev/zero of=build/neutron.img count=' + str(image_size_sectors) + ' > /dev/null 2>&1') @@ -77,7 +114,9 @@ def execute(cmd): print(' Creating EFI executable') execute('mmd -i build/neutron.img ::/EFI') execute('mmd -i build/neutron.img ::/EFI/BOOT') +execute('mmd -i build/neutron.img ::/EFI/nOS') execute('mcopy -i build/neutron.img build/BOOTX64.EFI ::/EFI/BOOT') +execute('mcopy -i build/neutron.img build/initrd ::/EFI/nOS/initrd') print(' Making ISO') execute(f'dd if={image_file} of={iso_file} > /dev/null 2>&1') diff --git a/initrd/hello.txt b/initrd/hello.txt new file mode 100644 index 0000000..8ab686e --- /dev/null +++ b/initrd/hello.txt @@ -0,0 +1 @@ +Hello, World! diff --git a/initrd/hello2.txt b/initrd/hello2.txt new file mode 100644 index 0000000..a3036e5 --- /dev/null +++ b/initrd/hello2.txt @@ -0,0 +1 @@ +Hello, World!#2 diff --git a/nbuild b/nbuild index 94afd27..786f7e3 100644 --- a/nbuild +++ b/nbuild @@ -24,7 +24,4 @@ src/drivers/human_io/kbd.c src/drivers/human_io/mouse.c src/drivers/human_io/ps2.c src/drivers/human_io/ps2_kbd.c -src/drivers/human_io/ps2_mouse.c -.fs -build/krnl.bin>krnl -neutron.nbuild>nbuild \ No newline at end of file +src/drivers/human_io/ps2_mouse.c \ No newline at end of file diff --git a/src/drivers/gfx.c b/src/drivers/gfx.c index 365207b..95a4334 100644 --- a/src/drivers/gfx.c +++ b/src/drivers/gfx.c @@ -276,7 +276,7 @@ void gfx_draw_hor_line(p2d_t pos, uint64_t w, color32_t c){ uint64_t st = pos.y * res_x; //Draw each pixel in the line for(uint64_t x = pos.x; x < pos.x + w; x++) - buf[st + x] = c; + buf[st + x] = gfx_blend_colors(buf[st + x], c, c.a); } /* @@ -331,9 +331,13 @@ void gfx_draw_xbm(p2d_t position, uint8_t* xbm_ptr, p2d_t xbm_size, color32_t co * Blends from background to foreground colors using the alpha value */ color32_t gfx_blend_colors(color32_t b, color32_t f, uint8_t a){ - return COLOR32(255, ((((uint32_t)f.r - (uint32_t)b.r) * a) / 255) + (uint32_t)b.r, - ((((uint32_t)f.g - (uint32_t)b.g) * a) / 255) + (uint32_t)b.g, - ((((uint32_t)f.b - (uint32_t)b.b) * a) / 255) + (uint32_t)b.b); + if(a == 0) + return b; + if(a == 255) + return f; + return COLOR32(255, ((((int32_t)f.r - (int32_t)b.r) * a) / 255) + (int32_t)b.r, + ((((int32_t)f.g - (int32_t)b.g) * a) / 255) + (int32_t)b.g, + ((((int32_t)f.b - (int32_t)b.b) * a) / 255) + (int32_t)b.b); } /* diff --git a/src/drivers/initrd.c b/src/drivers/initrd.c index cc91396..63fd4bb 100644 --- a/src/drivers/initrd.c +++ b/src/drivers/initrd.c @@ -2,13 +2,13 @@ //Initrd driver // (initialization ramdisk) +#include "./initrd.h" +#include "../stdlib.h" + #include #include #include -#include "../stdlib.h" -#include "./initrd.h" - EFI_SYSTEM_TABLE* krnl_get_efi_systable(void); //Initrd image @@ -45,12 +45,12 @@ uint8_t initrd_init(void){ if(EFI_ERROR(status)) return 2; //Open the initrd file on it - status = root_file_prot->Open(root_file_prot, &initrd_file_prot, (WCHAR*)U"EFI\\nOS\\initrd", EFI_FILE_MODE_READ, 0); + status = root_file_prot->Open(root_file_prot, &initrd_file_prot, (CHAR16*)L"EFI\\nOS\\initrd", EFI_FILE_MODE_READ, 0); if(EFI_ERROR(status)) continue; //Skip this partition on error //Read its info EFI_FILE_INFO info; - uint64_t size = sizeof(EFI_FILE_INFO); + uint64_t size = sizeof(EFI_FILE_INFO) * 10; status = initrd_file_prot->GetInfo(initrd_file_prot, &((EFI_GUID)EFI_FILE_INFO_ID), &size, (void*)&info); if(EFI_ERROR(status)) return 4; @@ -68,4 +68,30 @@ uint8_t initrd_init(void){ } //No initrd file on all partitions return 3; +} + +/* + * Reads file info from INITRD + */ +initrd_file_t initrd_read(char* name){ + uint32_t i = 0; + initrd_file_t cur; + //Scan through the file list + //Location = 0 means the end of the list + while(cur.location != 0){ + //Load the dedscriptor + cur = ((initrd_file_t*)initrd_raw)[i]; + //Check the name + if(strcmp(name, cur.name) == 0) + break; + } + return cur; +} + +/* + * Returns pointer to file contents from INITRD + */ +uint8_t* initrd_contents(char* name){ + uint32_t location = initrd_read(name).location; + return (location == 0) ? NULL : (initrd_raw + location); } \ No newline at end of file diff --git a/src/drivers/initrd.h b/src/drivers/initrd.h index f2165bc..2fa0ffa 100644 --- a/src/drivers/initrd.h +++ b/src/drivers/initrd.h @@ -1,6 +1,16 @@ #ifndef INITRD_H #define INITRD_H +#include "../stdlib.h" + +typedef struct { + uint32_t location; + uint32_t size; + char name[56]; +} __attribute__((packed)) initrd_file_t; + uint8_t initrd_init(void); +initrd_file_t initrd_read(char* name); +uint8_t* initrd_contents(char* name); #endif \ No newline at end of file diff --git a/src/gui/controls.c b/src/gui/controls.c index fca9b8d..fa35eb6 100644 --- a/src/gui/controls.c +++ b/src/gui/controls.c @@ -134,13 +134,13 @@ void gui_render_control(window_t* win_ptr, control_t* ptr){ //Fetch the extended data control_ext_button_t* button = (control_ext_button_t*)ptr->extended; //Full transparency = we choose the color on our own - if(button->bg_color.a == 0) - button->bg_color = COLOR32(0, gui_get_color_scheme()->win_border.r, gui_get_color_scheme()->win_border.g, + //if(button->bg_color.a == 0) + button->bg_color = COLOR32(255, gui_get_color_scheme()->win_border.r, gui_get_color_scheme()->win_border.g, gui_get_color_scheme()->win_border.b); - if(button->border_color.a == 0) - button->border_color = COLOR32(0, button->bg_color.r, button->bg_color.g, button->bg_color.b); - if(button->pressed_bg_color.a == 0) - button->pressed_bg_color = COLOR32(0, button->bg_color.r >> 1, button->bg_color.g >> 1, button->bg_color.b >> 1); + //if(button->border_color.a == 0) + button->border_color = COLOR32(255, button->bg_color.r, button->bg_color.g, button->bg_color.b); + //if(button->pressed_bg_color.a == 0) + button->pressed_bg_color = COLOR32(255, button->bg_color.r >> 1, button->bg_color.g >> 1, button->bg_color.b >> 1); //Draw the rectangles color32_t bg_color = button->pressed_last_frame ? button->pressed_bg_color : button->bg_color; if(gui_mouse_btns().x && gfx_point_in_rect(gui_mouse_coords(), (p2d_t){.x = ptr->position.x + win_ptr->position.x + 1, diff --git a/src/gui/gui.c b/src/gui/gui.c index eee5c83..48ebc67 100644 --- a/src/gui/gui.c +++ b/src/gui/gui.c @@ -63,20 +63,20 @@ void gui_init(void){ my = gfx_res_y() / 2; gfx_verbose_println("Initializing color scheme"); //Set the default color scheme - color_scheme.desktop = COLOR32(255, 20, 20, 20); - color_scheme.top_bar = COLOR32(255, 71, 71, 71); - color_scheme.cursor = COLOR32(255, 255, 255, 255); - color_scheme.selection = COLOR32(255, 0, 128, 255); - color_scheme.time = COLOR32(255, 255, 255, 255); - color_scheme.win_bg = COLOR32(255, 32, 32, 32); + color_scheme.win_bg = COLOR32(240, 32, 32, 32); color_scheme.win_title = COLOR32(255, 255, 255, 255); color_scheme.win_title_inactive = COLOR32(255, 200, 200, 200); - color_scheme.win_border = COLOR32(255, 9, 9, 9); + color_scheme.win_border = COLOR32(255, 236, 78, 32); color_scheme.win_border_inactive = COLOR32(255, 39, 39, 39); color_scheme.win_exit_btn = COLOR32(255, 255, 0, 0); color_scheme.win_state_btn = COLOR32(255, 255, 255, 255); color_scheme.win_minimize_btn = COLOR32(255, 255, 255, 255); color_scheme.win_unavailable_btn = COLOR32(255, 128, 128, 128); + color_scheme.desktop = COLOR32(255, 20, 20, 20); + color_scheme.top_bar = COLOR32(255, 71, 71, 71); + color_scheme.cursor = COLOR32(255, 255, 255, 255); + color_scheme.selection = color_scheme.win_border; + color_scheme.time = COLOR32(255, 255, 255, 255); gui_trans = 0; gui_render = 0; diff --git a/src/stdlib.h b/src/stdlib.h index a51b198..8a4b0d2 100644 --- a/src/stdlib.h +++ b/src/stdlib.h @@ -6,7 +6,7 @@ #endif //The kernel version -#define KRNL_VERSION_STR "v0.4.8" +#define KRNL_VERSION_STR "v0.4.9" //Use WC for memcpy() transfers? #define STDLIB_MEMCPY_WC