Skip to content

Commit 0c5f400

Browse files
committed
Installer.c +Syslibc implicit declaration fix
1 parent 27b6c64 commit 0c5f400

5 files changed

Lines changed: 185 additions & 7 deletions

File tree

src/syslibc/string.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,4 +234,14 @@ char *strpbrk(const char *s1, const char *s2) {
234234
s1++;
235235
}
236236
return NULL;
237+
}
238+
239+
char *strrchr(const char *s, int c) {
240+
char *last = NULL;
241+
do {
242+
if (*s == (char)c) {
243+
last = (char *)s;
244+
}
245+
} while (*s++);
246+
return last;
237247
}

src/syslibc/string.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ char *strtok(char *s, const char *delim);
2222
char *strpbrk(const char *s1, const char *s2);
2323
size_t strspn(const char *s1, const char *s2);
2424
size_t strcspn(const char *s1, const char *s2);
25+
char *strrchr(const char *s, int c);
2526

2627
// Конвертация чисел в строки (супер-важно для будущего printf!)
2728
void itoa(int64_t num, int base, char *buffer);

src/system/fs/ext2.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,6 @@ vfs_node_t* ext2_get_root_node() {
318318
return node;
319319
}
320320

321-
void ext2_read_block(uint32_t block, uint8_t *buffer) {
322-
// ВАЖНО: Сначала буфер, потом LBA, потом количество секторов
323-
read_sectors_ata_pio((uintptr_t)buffer, block * (block_size / 512),
324-
block_size / 512);
325-
}
326-
327321
void ext2_read_inode(uint32_t inode, ext2_inode_t* out_inode) {
328322
if (!sb || inode == 0) {
329323
memset(out_inode, 0, sizeof(ext2_inode_t));

src/system/fs/mkfs_ext2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#define BLOCK_BITMAP_BLOCK 2
1414
#define INODE_BITMAP_BLOCK 3
1515
#define INODE_TABLE_BLOCK 4
16-
16+
extern void term_print(const char* str);
1717
// Хелперы для работы с битмапами
1818
static void bitmap_set(uint8_t *bitmap, uint32_t index) {
1919
bitmap[index / 8] |= (1 << (index % 8));

src/system/misc/installer.c

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#include "../fs/vfs.h"
2+
#include "../fs/gpt.h"
3+
#include "../fs/ext2.h"
4+
#include "../fs/fat32.h"
5+
#include "../../syslibc/stdio.h"
6+
#include "../../syslibc/string.h"
7+
8+
extern void term_print(const char* str);
9+
extern void ext2_set_partition(uint64_t lba);
10+
extern int ext2_format(uint64_t start_lba, uint64_t sector_count);
11+
extern void fat32_init(void);
12+
13+
// Вспомогательная функция для создания родительских директорий по пути (например, /mnt/target/bin)
14+
static void ensure_directory(const char *path) {
15+
char temp[256];
16+
strncpy(temp, path, sizeof(temp) - 1);
17+
temp[sizeof(temp)-1] = '\0';
18+
19+
// Отрезаем имя файла, оставляем только путь к папке
20+
char *last_slash = strrchr(temp, '/');
21+
if (last_slash) {
22+
*last_slash = '\0';
23+
// Если такой папки еще нет в VFS, создаем её рекурсивно
24+
if (!vfs_dir_exists(temp)) {
25+
// Если нужно, можно сделать mkdir для каждого уровня, но у нас плоская структура
26+
vfs_mkdir(temp);
27+
}
28+
}
29+
}
30+
31+
// Функция копирования файла средствами VFS
32+
int copy_file(const char *src, const char *dst) {
33+
vfs_file_t *sf = vfs_open(src, VFS_O_RDONLY);
34+
if (!sf) return -1;
35+
36+
// Гарантируем, что папка назначения существует
37+
ensure_directory(dst);
38+
39+
vfs_file_t *df = vfs_open(dst, VFS_O_WRONLY | VFS_O_CREAT | VFS_O_TRUNC);
40+
if (!df) {
41+
vfs_close(sf);
42+
return -1;
43+
}
44+
45+
uint8_t buffer[4096];
46+
int bytes_read;
47+
while ((bytes_read = vfs_read(sf, buffer, sizeof(buffer))) > 0) {
48+
vfs_write(df, buffer, bytes_read);
49+
}
50+
51+
vfs_close(sf);
52+
vfs_close(df);
53+
return 0;
54+
}
55+
56+
void install_equinox_os(void) {
57+
term_print("\n=== EquinoxOS Universal Installer ===\n");
58+
59+
// 1. Парсим GPT
60+
gpt_partition_t parts[GPT_MAX_PARTITIONS];
61+
int part_count = gpt_parse(0, parts, GPT_MAX_PARTITIONS);
62+
if (part_count < 0) {
63+
term_print("Error: Could not parse GPT. Installation aborted.\n");
64+
return;
65+
}
66+
67+
// 2. Ищем ESP (FAT32)
68+
int esp_idx = gpt_find_esp(0, parts, part_count);
69+
if (esp_idx == -1) {
70+
term_print("Error: EFI System Partition (ESP) not found!\n");
71+
return;
72+
}
73+
gpt_partition_t *esp = &parts[esp_idx];
74+
75+
// 3. Выбираем раздел под Root
76+
int root_idx = -1;
77+
for (int i = 0; i < part_count; i++) {
78+
if (i != esp_idx && parts[i].size_sectors > 100000) {
79+
root_idx = i;
80+
break;
81+
}
82+
}
83+
if (root_idx == -1) {
84+
term_print("Error: Target partition for OS Root not found!\n");
85+
return;
86+
}
87+
gpt_partition_t *root_part = &parts[root_idx];
88+
89+
// 4. Форматируем Ext2 раздел под ОС
90+
ext2_format(root_part->first_lba, root_part->size_sectors);
91+
92+
// 5. Монтируем целевой раздел Ext2 в /mnt/target
93+
ext2_set_partition(root_part->first_lba);
94+
vfs_node_t *ext2_root = ext2_get_root_node();
95+
vfs_mount("/mnt/target", ext2_root);
96+
97+
// 6. Монтируем ESP (FAT32) в /mnt/esp
98+
fat32_init();
99+
vfs_node_t *fat_root = fat32_get_root_node();
100+
vfs_mount("/mnt/esp", fat_root);
101+
102+
// 7. Читаем манифест установки с загрузочной флешки
103+
vfs_file_t *manifest = vfs_open("/etc/install_manifest.txt", VFS_O_RDONLY);
104+
if (!manifest) {
105+
term_print("Error: /etc/install_manifest.txt not found! Installation aborted.\n");
106+
return;
107+
}
108+
109+
term_print("Copying system files based on manifest...\n");
110+
111+
char line_buf[256];
112+
int line_len = 0;
113+
char c;
114+
115+
// Построчно читаем манифест
116+
while (vfs_read(manifest, &c, 1) == 1) {
117+
if (c == '\n' || c == '\r') {
118+
if (line_len > 0) {
119+
line_buf[line_len] = '\0';
120+
121+
// Генерируем пути копирования
122+
// Источник: "/bin/sh.elf"
123+
// Назначение: "/mnt/target/bin/sh.elf"
124+
char dest_path[512];
125+
sprintf(dest_path, "/mnt/target%s", line_buf);
126+
127+
char log_msg[512];
128+
sprintf(log_msg, " -> Copying: %s\n", line_buf);
129+
term_print(log_msg);
130+
131+
if (copy_file(line_buf, dest_path) != 0) {
132+
char err_msg[512];
133+
sprintf(err_msg, " [!] Error copying %s\n", line_buf);
134+
term_print(err_msg);
135+
}
136+
line_len = 0;
137+
}
138+
} else if (line_len < 254) {
139+
line_buf[line_len++] = c;
140+
}
141+
}
142+
vfs_close(manifest);
143+
144+
// 8. Копируем файлы загрузчика Limine на ESP
145+
term_print("Installing Limine Bootloader to ESP...\n");
146+
147+
vfs_mkdir("/mnt/esp/EFI");
148+
vfs_mkdir("/mnt/esp/EFI/BOOT");
149+
vfs_mkdir("/mnt/esp/res");
150+
vfs_mkdir("/mnt/esp/sys");
151+
152+
copy_file("/boot/limine/BOOTX64.EFI", "/mnt/esp/EFI/BOOT/BOOTX64.EFI");
153+
copy_file("/sys/kernel.elf", "/mnt/esp/sys/kernel.elf");
154+
copy_file("/res/BG.BMP", "/mnt/esp/res/BG.BMP");
155+
156+
// Записываем новый limine.conf для жесткого диска
157+
const char *new_limine_conf =
158+
"timeout: 3\n"
159+
"backdrop: ff0b1220\n"
160+
"term_background: ff0b1220\n"
161+
"term_foreground: ffffff\n"
162+
"term_wallpaper: boot():/res/BG.BMP\n"
163+
"wallpaper: boot():/res/BG.BMP\n"
164+
"/EquinoxOS\n"
165+
" protocol: limine\n"
166+
" path: boot():/sys/kernel.elf\n"
167+
" resolution: 1920x1080x32\n"
168+
" module_path: boot():/res/font.psf\n";
169+
170+
vfs_write_file("/mnt/esp/EFI/BOOT/limine.conf", (const uint8_t*)new_limine_conf, strlen(new_limine_conf));
171+
172+
term_print("\nInstallation complete! Please reboot.\n");
173+
}

0 commit comments

Comments
 (0)