Добавление модуля "Мелодия"

Модуль воспроизводит мелодию при загрузке используя PC Speaker
This commit is contained in:
Aren Elchinyan 2023-10-23 09:16:16 +03:00
parent 8e59115c1e
commit 0eef3837f6
14 changed files with 155 additions and 96 deletions

2
.gitignore vendored
View File

@ -11,3 +11,5 @@ modules/helloworld/helloworld.elf
modules/com/com.elf modules/com/com.elf
modules/helloworld/hello.o modules/helloworld/hello.o
modules/helloworld/hello.so modules/helloworld/hello.so
*.so
*.o

View File

@ -11,6 +11,7 @@
"tool.h": "c", "tool.h": "c",
"sys.h": "c", "sys.h": "c",
"arch.h": "c", "arch.h": "c",
"fb.h": "c" "fb.h": "c",
"system.h": "c"
} }
} }

166
API.md
View File

@ -1,83 +1,83 @@
# Системные вызовы # Системные вызовы
## mem_alloc(size_t size) ## mem_alloc(size_t size)
Выделение блока памяти размером `size`. Выделение блока памяти размером `size`.
Вовзращает адрес на блок памяти или 0 в случае ошибки. Вовзращает адрес на блок памяти или 0 в случае ошибки.
Коды ошибок: Коды ошибок:
- `-1 не хватает ОЗУ`; - `-1 не хватает ОЗУ`;
- `-2 неправильный размер блока`. - `-2 неправильный размер блока`.
## mem_free(uintptr_t mem) ## mem_free(uintptr_t mem)
Освобождение блока памяти `mem`. Освобождение блока памяти `mem`.
Вовзращает 0 в случае успеха или -1 в случае ошибки. Вовзращает 0 в случае успеха или -1 в случае ошибки.
Коды ошибок: Коды ошибок:
- `-1 блок не найден`. - `-1 блок не найден`.
## sys_alloc_framebuffer() ## sys_alloc_framebuffer()
Выделяет память под буфер кадра для отображения графического интерфейса. Выделяет память под буфер кадра для отображения графического интерфейса.
Возвращает указатель на структуру `framebuffer_t` или 0, если произошла ошибка. Возвращает указатель на структуру `framebuffer_t` или 0, если произошла ошибка.
Коды ошибок: Коды ошибок:
- `-1 не удалось выделить память для буфера кадра`. - `-1 не удалось выделить память для буфера кадра`.
## sys_free_framebuffer(framebuffer_t *frame) ## sys_free_framebuffer(framebuffer_t *frame)
Освобождает ранее выделенную память `frame` для буфера кадра. Возвращает 0 в случае успеха или -1, если произошла ошибка. Освобождает ранее выделенную память `frame` для буфера кадра. Возвращает 0 в случае успеха или -1, если произошла ошибка.
Коды ошибок: Коды ошибок:
- `-1 ошибка при освобождении памяти для буфера кадра`. - `-1 ошибка при освобождении памяти для буфера кадра`.
## sys_exit(int code) ## sys_exit(int code)
Завершает выполнение текущего потока с кодом `code`. Завершает выполнение текущего потока с кодом `code`.
## sys_get_error() ## sys_get_error()
Получает код ошибки последней операции. Возвращает целочисленное значение, представляющее код ошибки. Получает код ошибки последней операции. Возвращает целочисленное значение, представляющее код ошибки.
## sys_get_info() ## sys_get_info()
Получает информацию о текущей системе. Возвращает структуру `sys_info_t` содержащую информацию о системе. Получает информацию о текущей системе. Возвращает структуру `sys_info_t` содержащую информацию о системе.
## sys_get_module(uid_t module_id) ## sys_get_module(uid_t module_id)
Получает информацию о модуле `module_id`. Возвращает структуру, содержащую информацию о модуле. Получает информацию о модуле `module_id`. Возвращает структуру, содержащую информацию о модуле.
## sys_new_thread(func_t func) ## sys_new_thread(func_t func)
Создает новый поток выполнения для функции `func`. Возвращает идентификатор созданного потока или 0 в случае ошибки. Создает новый поток выполнения для функции `func`. Возвращает идентификатор созданного потока или 0 в случае ошибки.
Коды ошибок: Коды ошибок:
- `-1 ошибка при создании потока`. - `-1 ошибка при создании потока`.
## sys_delete_thread(uid_t thread_id) ## sys_delete_thread(uid_t thread_id)
Удаляет указанный поток выполнения `thread_id`. Возвращает 0 в случае успеха или -1 в случае ошибки. Удаляет указанный поток выполнения `thread_id`. Возвращает 0 в случае успеха или -1 в случае ошибки.
Коды ошибок: Коды ошибок:
- `-1 поток не найден`. - `-1 поток не найден`.
<!-- <!--
## sys_get_time() ## sys_get_time()
Получает текущее время системы в формате timestamp. Возвращает целое число, представляющее количество секунд с начала эпохи. Получает текущее время системы в формате timestamp. Возвращает целое число, представляющее количество секунд с начала эпохи.
## sys_set_alarm(time_t time, func_t func) ## sys_set_alarm(time_t time, func_t func)
Устанавливает сигнал будильника на время time. При наступлении указанного времени будет вызвана функция func. Устанавливает сигнал будильника на время time. При наступлении указанного времени будет вызвана функция func.
Коды ошибок: Коды ошибок:
- `-1 ошибка при установке сигнала будильника`. - `-1 ошибка при установке сигнала будильника`.
--> -->

View File

@ -1,2 +1,6 @@
#!/bin/sh #!/bin/sh
cd modules/
cd helloworld/ && ./build.sh && cd ..
cd music/ && ./build.sh && cd ..
cd ..
python3 pbuild.py python3 pbuild.py

View File

@ -15,6 +15,9 @@ BACKGROUND_PATH=boot:///boot.tga
KASLR=no KASLR=no
KERNEL_PATH=boot:///kernel.elf KERNEL_PATH=boot:///kernel.elf
MODULE_PATH=boot:///mod/music.so
MODULE_CMDLINE=[MOD]music.so
MODULE_PATH=boot:///mod/hello.so MODULE_PATH=boot:///mod/hello.so
MODULE_CMDLINE=[MOD]hello.so MODULE_CMDLINE=[MOD]hello.so

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 1 #define VERSION_MINOR 1
#define VERSION_BUILD 254 #define VERSION_BUILD 279

View File

@ -83,13 +83,14 @@ void mod_init( ) {
} }
if (!tool_starts_with(module_ptr->cmdline, "[MOD]")) { continue; } if (!tool_starts_with(module_ptr->cmdline, "[MOD]")) { continue; }
modules_count++; modules_count++;
module_info_t *(*module_init)(env_t *env) = uint64_t (*module_init)(env_t * env) =
(module_info_t * (*)(env_t * env)) elf_entry(module_ptr->address, module_ptr->size); (module_info_t * (*)(env_t * env)) elf_entry(module_ptr->address, module_ptr->size);
fb_printf("\t->Точка входа: 0x%x\n", module_init); fb_printf("\t->Точка входа: 0x%x\n", module_init);
// module_info_t *ret = module_init(&main_env); uint64_t ret = module_init(&main_env);
fb_printf("Инициализированно с кодом: %u\n", ret);
// fb_printf("Инициализированно с кодом: %u\n", ret->err_code); // fb_printf("Инициализированно с кодом: %u\n", ret->err_code);
// fb_printf("Сообщение из модуля: %s\n\n", ret->message); // fb_printf("Сообщение из модуля: %s\n\n", ret->message);
} }

View File

@ -6,6 +6,8 @@
* *
*/ */
void task_init( ) {}
void task_new_thread( ) { void task_new_thread( ) {
return; return;
} }

View File

@ -2,5 +2,5 @@
echo "Название: Hello world" echo "Название: Hello world"
echo "Лицензия: Публичное достояние" echo "Лицензия: Публичное достояние"
gcc -I../../modlib -O0 -finput-charset=UTF-8 -fexec-charset=cp1251 -c -fPIC -nostdlib main.c -o hello.o gcc -I../../modlib -O0 -finput-charset=UTF-8 -fexec-charset=cp1251 -c -fPIC -nostdlib main.c -o hello.o
gcc -fPIC -shared -nostdlib hello.o -o hello.so -Wl,--entry=_start gcc -Wl,--entry=init -fPIC -shared -nostdlib hello.o -o hello.so
echo "Сборка завершена, файл: hello.so" echo "Сборка завершена, файл: hello.so"

View File

@ -5,8 +5,7 @@ const char message[] = "Привет из модуля!";
module_info_t info = { module_info_t info = {
.name = (char *)&name, .message = (char *)&message, .err_code = 2023, .func_count = 1 .name = (char *)&name, .message = (char *)&message, .err_code = 2023, .func_count = 1
}; };
env_t *env;
module_info_t *_start(env_t *env) { uint64_t init(env_t *env) {
return &info; return info.err_code;
} }

6
modules/music/build.sh Normal file
View File

@ -0,0 +1,6 @@
#/bin/sh
echo "Название: Мелодия из тетриса"
echo "Лицензия: Публичное достояние"
gcc -I../../modlib -O0 -finput-charset=UTF-8 -fexec-charset=cp1251 -c -fPIC -nostdlib main.c -o music.o
gcc -Wl,--entry=init -fPIC -shared -nostdlib music.o -o music.so
echo "Сборка завершена, файл: music.so"

42
modules/music/main.c Normal file
View File

@ -0,0 +1,42 @@
#include <system.h>
static inline void outb(uint16_t port, uint8_t val) {
asm volatile("outb %0, %1" : : "a"(val), "Nd"(port));
}
static inline uint8_t inb(uint16_t port) {
uint8_t ret;
asm volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
static inline void usleep(uint64_t ticks) {
for (uint64_t i = 0; i < ticks * 100; i++) { asm volatile("pause"); }
}
static inline void play_sound(unsigned int frequency) {
}
int init(env_t *env) {
// Массив с нотами
unsigned int tetris_notes[] = {0};
// Расчет количества нот в мелодии
int num_notes = sizeof(tetris_notes) / sizeof(tetris_notes[0]);
// Начальное значение для подсчета времени
int note_duration = 1000000; // 1 секунда
// Зацикленное воспроизведение мелодии в течение минуты
for (int i = 0; i < num_notes; i++) {
// Воспроизведение ноты с заданным временем
play_sound(tetris_notes[i]);
usleep(note_duration);
// Уменьшение времени для следующей ноты
note_duration -= note_duration / 24; // Уменьшение на 1/24 каждый раз
}
return 0;
}

View File

@ -135,7 +135,7 @@ def create_hdd(IMAGE_NAME):
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"kernel.elf", "configs/limine.cfg", "limine/limine-bios.sys", "::/"]) "kernel.elf", "configs/limine.cfg", "limine/limine-bios.sys", "::/"])
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"modules/com/com.elf", "modules/helloworld/hello.so", "::/mod"]) "modules/music/music.so", "modules/helloworld/hello.so", "::/mod"])
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
"limine/BOOTX64.EFI", "limine/BOOTIA32.EFI", "::/EFI/BOOT"]) "limine/BOOTX64.EFI", "limine/BOOTIA32.EFI", "::/EFI/BOOT"])
subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M", subprocess.run(["mcopy", "-i", IMAGE_NAME+".hdd@@1M",
@ -155,7 +155,7 @@ def create_iso(IMAGE_NAME):
subprocess.run(["mkdir", "-p", "iso_root/EFI/BOOT"]) subprocess.run(["mkdir", "-p", "iso_root/EFI/BOOT"])
subprocess.run(["mkdir", "-p", "iso_root/mod"]) subprocess.run(["mkdir", "-p", "iso_root/mod"])
subprocess.run(["cp", "-v", "modules/helloworld/hello.so", "iso_root/mod/"]) subprocess.run(["cp", "-v", "modules/helloworld/hello.so", "iso_root/mod/"])
subprocess.run(["cp", "-v", "modules/com/com.elf", "iso_root/mod/"]) subprocess.run(["cp", "-v", "modules/music/music.so", "iso_root/mod/"])
subprocess.run(["cp", "-v", "limine/BOOTX64.EFI", "iso_root/EFI/BOOT/"]) subprocess.run(["cp", "-v", "limine/BOOTX64.EFI", "iso_root/EFI/BOOT/"])
subprocess.run(["cp", "-v", "limine/BOOTIA32.EFI", "iso_root/EFI/BOOT/"]) subprocess.run(["cp", "-v", "limine/BOOTIA32.EFI", "iso_root/EFI/BOOT/"])
subprocess.run(["xorriso", "-as", "mkisofs", "-b", "limine-bios-cd.bin", subprocess.run(["xorriso", "-as", "mkisofs", "-b", "limine-bios-cd.bin",
@ -179,7 +179,6 @@ if __name__ == "__main__":
check_limine() check_limine()
check_tools() check_tools()
major, minor, build = version_build() major, minor, build = version_build()
os.system("cd modules/helloworld/ && ./build.sh")
compile_all() compile_all()
create_iso("bmosp") create_iso("bmosp")
create_hdd("bmosp") create_hdd("bmosp")

2
run.sh
View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd --no-reboot qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 -hda bmosp.hdd --no-reboot
#qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd -d int --no-reboot #qemu-system-x86_64 -name "БМПОС" -cpu max -m 1G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd -d int --no-reboot
#qemu-system-x86_64 -name "БМПОС" -cpu host -m 1G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd #qemu-system-x86_64 -name "БМПОС" -cpu host -m 1G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd
#qemu-system-x86_64 -name "БМПОС" -enable-kvm -cpu host -m 6G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd -d int --no-reboot #qemu-system-x86_64 -name "БМПОС" -enable-kvm -cpu host -m 6G -smp 1 -bios ovmf/OVMF.fd -hda bmosp.hdd -d int --no-reboot