forked from Aren/BMOSP
1
0
Fork 0

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

Модуль воспроизводит мелодию при загрузке используя 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/helloworld/hello.o
modules/helloworld/hello.so
*.so
*.o

View File

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

View File

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

View File

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

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0
#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; }
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);
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("Сообщение из модуля: %s\n\n", ret->message);
}

View File

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

View File

@ -2,5 +2,5 @@
echo "Название: Hello world"
echo "Лицензия: Публичное достояние"
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"

View File

@ -5,8 +5,7 @@ const char message[] = "Привет из модуля!";
module_info_t info = {
.name = (char *)&name, .message = (char *)&message, .err_code = 2023, .func_count = 1
};
env_t *env;
module_info_t *_start(env_t *env) {
return &info;
}
uint64_t init(env_t *env) {
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",
"kernel.elf", "configs/limine.cfg", "limine/limine-bios.sys", "::/"])
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",
"limine/BOOTX64.EFI", "limine/BOOTIA32.EFI", "::/EFI/BOOT"])
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/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/BOOTIA32.EFI", "iso_root/EFI/BOOT/"])
subprocess.run(["xorriso", "-as", "mkisofs", "-b", "limine-bios-cd.bin",
@ -179,7 +179,6 @@ if __name__ == "__main__":
check_limine()
check_tools()
major, minor, build = version_build()
os.system("cd modules/helloworld/ && ./build.sh")
compile_all()
create_iso("bmosp")
create_hdd("bmosp")

2
run.sh
View File

@ -1,5 +1,5 @@
#!/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 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