SayoriOS  0.3.3
kernel.c
См. документацию.
1 
10 #include "kernel.h"
11 
12 #include <drv/fpu.h>
13 #include <lib/php/explode.h>
14 #include <sys/unwind.h>
15 
16 #include "mem/pmm.h"
17 #include "mem/vmm.h"
18 #include "drv/audio/ac97.h"
19 #include "sys/mtrr.h"
20 #include "net/ipv4.h"
21 
22 #include "fs/natfs.h"
23 #include "net/stack.h"
24 #include "drv/audio/hda.h"
25 #include "lib/ttf_font.h"
26 #include "sys/grub_modules.h"
27 #include "drv/disk/mbr.h"
28 #include "sys/file_descriptors.h"
29 #include "sys/lapic.h"
30 #include "drv/ps2.h"
31 #include "net/dhcp.h"
32 #include "gfx/intel.h"
33 #include "ports/eBat/eBat.h"
34 #include "ports/eBat/eBatRuntime.h"
35 
36 
37 #include <lib/pixel.h>
38 
39 #define INITRD_RW_SIZE (1474560)
40 
41 extern bool ps2_channel2_okay;
42 
43 uint32_t init_esp = 0;
44 bool test_pcs = true;
45 bool test_floppy = true;
46 bool test_network = true;
47 bool is_rsdp = true;
48 bool initRD = false;
49 size_t kernel_start_time = 0;
50 size_t ramdisk_size = INITRD_RW_SIZE;
51 
52 void jse_file_getBuff(char* buf);
53 void kHandlerCMD(char*);
54 
55 void autoexec(){
56 
57  variable_write("HOSTNAME", "SAYORISOUL");
58  variable_write("SYSTEMROOT", "R:\\Sayori\\");
59  variable_write("TEMP", "T:\\");
60  variable_write("USERNAME", "OEM");
61  variable_write("BUILDUSER", BUILDUSER);
62  variable_write("BUILDDATA", __TIMESTAMP__);
63  variable_write("VERSION_MAJOR", TOSTRING(VERSION_MAJOR));
64  variable_write("VERSION_MINOR", TOSTRING(VERSION_MINOR));
65  variable_write("VERSION_PATCH", TOSTRING(VERSION_PATCH));
66  variable_write("ARCH_TYPE", ARCH_TYPE);
67  variable_write("VERNAME", VERNAME);
68  variable_write("SUBVERSIONNAME", SUBVERSIONNAME);
69  variable_write("VERSION", VERSION_STRING);
70 
71 
72  char* f = "R:\\autoexec.bat";
73  FILE* cat_file = fopen(f, "r");
74  if (!cat_file){
75  tty_setcolor(COLOR_ERROR);
76  tty_printf("[AutoExec] Не удалось найти файл `%s`.\n",f);
77  return;
78  }
79 
80  size_t filesize = fsize(cat_file);
81 
82  uint8_t* buffer = kcalloc(1,filesize + 1);
83 
84  fread(cat_file, 1, filesize, buffer);
85 
86  qemu_log("'%s'", buffer);
87 
88  BAT_T* token = bat_parse_string(buffer);
89  token->Debug = 0;
90  token->Echo = 1;
91  int ret = bat_runtime_exec(token);
92  qemu_warn("RETURN CODE: %d\n",ret);
93  bat_destroy(token);
94 
95 
96  fclose(cat_file);
97 
98  kfree(buffer);
99 }
100 
101 void __createRamDisk(){
102  qemu_note("[INITRD] Create virtual read-write disk...");
103  void* disk_t = kmalloc(INITRD_RW_SIZE+1);
104  if (disk_t == NULL){
105  qemu_err("[INITRD] Fatal create virtual disk");
106  return;
107  }
108  qemu_log("[INITRD] Temp disk is (%d bytes) created to %x", ramdisk_size, disk_t);
109  dpm_reg('T',"TempDisk","TEMPFS", 2, ramdisk_size, 0, 0, 2, "TEMP-DISK", disk_t);
110  fs_tempfs_format('T');
111  qemu_ok("[INITRD] The virtual hard disk has been successfully created.");
112 }
113 
114 #ifndef RELEASE
115 void draw_raw_fb(multiboot_header_t* mboot, int x, int y, int w, int h, int color) {
116  for(uint32_t i = y; i < y + h; i++) {
117  for(uint32_t j = x; j < x + w; j++) {
118  uint8_t* a = (framebuffer_addr + (j * ((mboot->framebuffer_bpp) >> 3)) + i * (mboot->framebuffer_pitch));
119 
120  a[2] = (color >> 16) & 0xff;
121  a[1] = (color >> 8) & 0xff;
122  a[0] = (color) & 0xff;
123  }
124  }
125 }
126 #else
127 #define draw_raw_fb(a, b, c, d, e, f)
128 #endif
129 
136 void kHandlerCMD(char* cmd){
137  qemu_log("Kernel command line at address %x and contains: '%s'", (size_t)cmd, cmd);
138 
139  if(strlen(cmd) == 0)
140  return;
141 
142  uint32_t kCMDc = str_cdsp(cmd," ");
143  uint32_t kCMDc_c = 0;
144  char* out[128] = {0};
145  str_split(cmd,out," ");
146  for(int i = 0; kCMDc >= i; i++){
147  kCMDc_c = str_cdsp(out[i],"=");
148  char* out_data[128] = {0};
149  if (kCMDc_c != 1){
150  qemu_log("[kCMD] [%d] %s is ignore.",i,out[i]);
151  continue;
152  }
153  str_split(out[i],out_data,"=");
154  if (strcmpn(out_data[0],"bootscreen")){
155  // Config BOOTSCREEN
156  if (strcmpn(out_data[1],"minimal")){
158  } else if (strcmpn(out_data[1],"light")){
160  } else if (strcmpn(out_data[1],"dark")) {
162  } else {
163  qemu_log("\t Sorry, no support bootscreen mode!");
164  }
165  }
166 
167  if (strcmpn(out_data[0],"NatSuki-Login")){
168  __milla_setLogin(out_data[1]);
169  }
170  if (strcmpn(out_data[0],"NatSuki-Password")){
171  __milla_setPasswd(out_data[1]);
172  }
173  if (strcmpn(out_data[0],"ramdisk")){
174  ramdisk_size = atoi(out_data[1]);
175  }
176  if (strcmpn(out_data[0],"disable")){
177  if (strcmpn(out_data[1],"coms")){
178  // FIXME: If uncomment following line of code, it willn't boot
179  __com_setInit(1, 0);
180  __com_setInit(2, 0);
181  __com_setInit(3, 0);
182  __com_setInit(4, 0);
183  qemu_log("\t COM-OUT DISABLED");
184  } else if (strcmpn(out_data[1],"floppy")){
185  test_floppy = false;
186  qemu_log("\t FLOPPY DISABLED");
187  } else if (strcmpn(out_data[1],"network")){
188  test_network = false;
189  qemu_log("\t NETWORK DISABLED");
190  } else if (strcmpn(out_data[1],"pc-speaker")){
191  test_pcs = false;
192  qemu_log("\t PC-Speaker DISABLED");
193  } else if (strcmpn(out_data[1],"rdsp")){
194  is_rsdp = false;
195  qemu_log("\t RDSP DISABLED");
196  } else {
197  qemu_log("\t Sorry, no support!");
198  }
199  }
200  //qemu_log("[kCMD] [%d] %s >\n\tKey: %s\n\tValue:%s",i,out[i],out_data[0],out_data[1]);
201  }
202 }
203 
211 void initrd_sefs(size_t irdst, size_t irded){
212  if (initRD){
213  return;
214  }
215 
216  qemu_log("[InitRD] [SEFS] Initialization of the virtual disk. The SEFS virtual file system is used.");
217  qemu_log("[InitRD] [SEFS] The virtual disk space is located at address %x.", irdst);
218  qemu_log("[InitRD] [SEFS] The virtual disk space is ends at %x.", irded);
219 }
220 
228 extern size_t CODE_start;
229 extern size_t CODE_end;
230 extern size_t DATA_start;
231 extern size_t DATA_end;
232 extern size_t RODATA_start;
233 extern size_t RODATA_end;
234 extern size_t BSS_start;
235 extern size_t BSS_end;
236 
237 /*
238  Спаси да сохрани этот кусок кода
239  Да на все твое кодерская воля
240  Да прибудет с тобой, священный код
241  Я тебя благославляю
242 */
243 void __attribute__((noreturn)) kmain(multiboot_header_t* mboot, uint32_t initial_esp) {
244  __com_setInit(1, 1);
245  __com_init(PORT_COM1);
246 
247  __asm__ volatile("movl %%esp, %0" : "=r"(init_esp));
248 
249  framebuffer_addr = (uint8_t *) (mboot->framebuffer_addr);
250 
251  draw_raw_fb(mboot, 0, 0, 200, 16, 0x444444);
252 
253  drawASCIILogo(0);
254 
255  qemu_log("SayoriOS v%d.%d.%d\nBuilt: %s",
256  VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, // Версия ядра
257  __TIMESTAMP__ // Время окончания компиляции ядра
258  );
259 
260  qemu_log("Bootloader header at: %x", (size_t)mboot);
261 
262  qemu_log("SSE: %s", sse_check() ? "Supported" : "Not supported");
263 
264  if (sse_check()) {
265  fpu_save();
266  }
267 
268  qemu_log("Setting `Interrupt Descriptor Table`...");
269  init_descriptor_tables();
270  qemu_log("Setting `RIH`...");
271  isr_init();
272 
273  qemu_log("Initializing FPU...");
274  fpu_init();
275 
276  draw_raw_fb(mboot, 0, 0, 400, 16, 0x888888);
277 
278  init_timer(CLOCK_FREQ);
279 
280  __asm__ volatile("sti");
281 
282  draw_raw_fb(mboot, 0, 0, 800, 16, 0xffffff);
283 
284  qemu_log("Checking RAM...");
285  check_memory_map((memory_map_entry_t *) mboot->mmap_addr, mboot->mmap_length);
286  qemu_log("Memory summary:");
287  qemu_log(" Code: %x - %x", (size_t)&CODE_start, (size_t)&CODE_end);
288  qemu_log(" Data: %x - %x", (size_t)&DATA_start, (size_t)&DATA_end);
289  qemu_log(" Read-only data: %x - %x", (size_t)&RODATA_start, (size_t)&RODATA_end);
290  qemu_log(" BSS: %x - %x", (size_t)&BSS_start, (size_t)&BSS_end);
291  qemu_log("Memory manager initialization...");
292 
293  grub_modules_prescan(mboot);
294 
295  init_paging();
296 
297  mark_reserved_memory_as_used((memory_map_entry_t *) mboot->mmap_addr, mboot->mmap_length);
298 
299  qemu_ok("PMM Ok!");
300 
301  vmm_init();
302  qemu_ok("VMM OK!");
303 
304  switch_qemu_logging();
305 
306  kHandlerCMD((char *) mboot->cmdline);
307 
308  drv_vbe_init(mboot);
309 
310  qemu_log("Registration of file system drivers...");
311  fsm_reg("TARFS", 1, &fs_tarfs_read, &fs_tarfs_write, &fs_tarfs_info, &fs_tarfs_create, &fs_tarfs_delete,
312  &fs_tarfs_dir, &fs_tarfs_label, &fs_tarfs_detect);
313  fsm_reg("FAT32", 1, &fs_fat32_read, &fs_fat32_write, &fs_fat32_info, &fs_fat32_create, &fs_fat32_delete,
314  &fs_fat32_dir, &fs_fat32_label, &fs_fat32_detect);
315  fsm_reg("NatFS", 1, &fs_natfs_read, &fs_natfs_write, &fs_natfs_info, &fs_natfs_create, &fs_natfs_delete,
316  &fs_natfs_dir, &fs_natfs_label, &fs_natfs_detect);
317  fsm_reg("ISO9660", 1, &fs_iso9660_read, &fs_iso9660_write, &fs_iso9660_info, &fs_iso9660_create, &fs_iso9660_delete,
318  &fs_iso9660_dir, &fs_iso9660_label, &fs_iso9660_detect);
319  fsm_reg("TEMPFS", 1, &fs_tempfs_read, &fs_tempfs_write, &fs_tempfs_info, &fs_tempfs_create, &fs_tempfs_delete,
320  &fs_tempfs_dir, &fs_tempfs_label, &fs_tempfs_detect);
321  fs_natfs_init();
322 
323  grub_modules_init(mboot);
324 
325  kernel_start_time = getTicks();
326 
327  mtrr_init();
328  text_init("R:\\Sayori\\Fonts\\UniCyrX-ibm-8x16.psf");
329  // /Sayori/Fonts/UniCyrX-ibm-8x16.psf
330 
331  qemu_log("Initializing the virtual video memory manager...");
332  init_vbe(mboot);
333 
334  qemu_log("Initializing Task Manager...");
336 
337  clean_screen();
338 
339  qemu_log("Initalizing fonts...");
341 
342  draw_vga_str("Initializing devices...", 23, 0, 0, 0xffffff);
343  punch();
344 
345  bootScreenInit(15);
346  bootScreenLazy(true);
347 
348  bootScreenPaint("Настройка PS/2...");
349  ps2_init();
350  bootScreenPaint("Настройка PS/2 Клавиатуры...");
351  keyboardInit();
352 
353  if(ps2_channel2_okay) {
354  bootScreenPaint("Настройка PS/2 Мыши...");
355  mouse_install();
356  }
357 
358  bootScreenPaint("Пост-настройка PS/2...");
359  ps2_keyboard_install_irq();
360  ps2_mouse_install_irq();
361 
362  bootScreenPaint("PCI Setup...");
363  pci_scan_everything();
364 
365  bootScreenPaint("Инициализация ATA...");
366  ata_init();
367  ata_dma_init();
368 
369  bootScreenPaint("Калибровка датчика температуры процессора...");
370  cputemp_calibrate();
371 
372  bootScreenPaint("Настройка FDT...");
373  file_descriptors_init();
374 
375  char* btitle = 0;
376 
377  asprintf(&btitle, "Создание виртуального диска (%u kb.)...", ramdisk_size/1024);
378 
379  bootScreenPaint(btitle);
380  kfree(btitle);
381  __createRamDisk();
382 
383  bootScreenPaint("Настройка системных вызовов...");
384  qemu_log("Registering System Calls...");
385  init_syscalls();
386 
387  bootScreenPaint("Настройка ENV...");
388  qemu_log("Registering ENV...");
389  configure_env();
390 
391  bootScreenPaint("Определение процессора...");
392  detect_cpu(1);
393 
394  bootScreenPaint("Конфигурация триггеров...");
395  triggersConfig();
396 
397  bootScreenPaint("Инициализация списка сетевых карт...");
398  netcards_list_init();
399 
400  bootScreenPaint("Инициализация сетевого стека...");
401  netstack_init();
402  bootScreenPaint("Инициализация ARP...");
403  arp_init();
404  bootScreenPaint("Инициализация RTL8139...");
405  rtl8139_init();
406  bootScreenPaint("Инициализация DHCP...");
407  dhcp_init_all_cards();
408  bootScreenPaint("Готово...");
409  bootScreenClose(0x000000, 0xFFFFFF);
410  tty_set_bgcolor(COLOR_BG);
411 
412  tty_printf("SayoriOS v%d.%d.%d\nДата компиляции: %s\n",
413  VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, // Версия ядра
414  __TIMESTAMP__ // Время окончания компиляции ядра
415  );
416  tty_printf("\nВлюбиться можно в красоту, но полюбить - лишь только душу.\n(c) Уильям Шекспир\n");
417 
418  if (__milla_getCode() != 0) {
419  tty_error("[ОШИБКА] [NatSuki] Не удалось выполнить инициализацию. Код ошибки: %d", __milla_getCode());
420  }
421 
422  sayori_time_t time = get_time();
423  tty_printf("\nВремя: %d:%d:%d\n", time.hours, time.minutes, time.seconds);
424 
425  _tty_printf("Listing ATA disks:\n");
426  ata_list();
427 
428  tty_taskInit();
429 
430  if (is_rsdp){
431  RSDPDescriptor* rsdp = rsdp_find();
432  qemu_log("RSDP at: %x", rsdp);
433 
434  if(rsdp) {
435  acpi_scan_all_tables(rsdp->RSDTaddress);
436 
437  find_facp(rsdp->RSDTaddress);
438 
439  lapic_init(rsdp);
440  } else {
441  tty_printf("ACPI not supported! (Are you running in UEFI mode?)\n");
442  qemu_err("ACPI not supported! (Are you running in UEFI mode?)");
443  }
444  }
445 
446  tty_printf("Processors: %d\n", system_processors_found);
447 
448  // FIXME: WOW! We can write into 0!
449  // *((volatile int*)0) = 0x12345678;
450  // qemu_log("Data: %x", *((volatile int*)0));
451 
452  if (test_network) {
453  _tty_printf("Listing network cards:\n");
454 
455  uint8_t mac_buffer[6] = {0};
456 
457  for (int i = 0; i < netcards_get_count(); i++) {
458  netcard_entry_t *entry = netcard_get(i);
459 
460  _tty_printf("\tName: %s\n", entry->name);
461  entry->get_mac_addr(mac_buffer);
462 
463  _tty_printf("\tMAC address: %v:%v:%v:%v:%v:%v\n",
464  mac_buffer[0],
465  mac_buffer[1],
466  mac_buffer[2],
467  mac_buffer[3],
468  mac_buffer[4],
469  mac_buffer[5]
470  );
471  }
472  }
473 
474  // if (test_floppy){
475  // initFloppy();
476  // fatTest();
477  // _smfs_init();
478  // }
479 
480  ac97_init();
481 
483  // drawRoundedSquare(32,32, 128, 2, 0xFFFF0000, 0xFF0000FF);
484  // drawRoundedRectangle(32,32,128,16,4,0xFFFF0000, 0xFF0000FF);
485  // punch();
486  // while (1){}
488 
489  ahci_init();
490 
492  fsm_dpm_update(-1);
493 
494  // vio_ntw_init();
495 
496 // size_t hwstart = timestamp();
497 //
498 // for(int i = 0, sh = getScreenHeight(); i < sh; i+=20) {
499 // for(int j = 0, sw = getScreenWidth(); j < sw; j+=20) {
500 // draw_filled_rectangle(j, i, 20, 20, rand());
501 // }
502 // }
503 //
504 // qemu_note("Program finished generating rects in %d ms", hwstart);
505 //
506 // punch();
507 //
508 // while(1);
509 
510  igfx_init();
511 
512 // hda_init();
513  // void k();
514 
515 // create_process(k, "process", false, true);
516 // sleep_ms(500);
517 // create_process(k, "process2", false, true);
518 // sleep_ms(1500);
519 // create_process(k, "process3", false, true);
520 
521  autoexec();
522 
523  qemu_log("System initialized everything at: %f seconds.", (double) (getTicks() - kernel_start_time) / getFrequency());
524 
525  // char* args[] = {};
526  // spawn("R:\\hellors", 0, args);
527 
528  cli();
529 
530  while(1)
531  ;
532 }
533 
534 // void k() {
535 // for(int i = 0; i < 10; i++) {
536 // qemu_err("HELLO");
537 // sleep_ms(250);
538 // }
539 // }
void bootScreenPaint(char *title)
Обновить информацию для BootScreen.
Definition: bootscreen.c:149
void bootScreenInit(uint32_t count)
Инициализирует BootScreen.
Definition: bootscreen.c:195
void bootScreenChangeTheme(uint32_t th)
Сменить тему BootScreen.
Definition: bootscreen.c:40
void bootScreenClose(uint32_t bg, uint32_t tx)
Завершает работу BootScreen.
Definition: bootscreen.c:84
void bootScreenChangeMode(int m)
Смена режима отображения BootScreen.
Definition: bootscreen.c:97
void bootScreenLazy(bool l)
Включить ленивую загрузку для BootScreen.
Definition: bootscreen.c:31
sayori_time_t get_time()
Считывает время и передает в удобной структуре
Definition: cmos.c:144
int detect_cpu(bool silent)
Получение имени процессора (Инициализация)
Definition: cpuinfo.c:45
int dpm_reg(char Letter, char *Name, char *FS, int Status, size_t Size, size_t Sectors, size_t SectorSize, int AddrMode, char *Serial, void *Point)
[DPM] Регистрация дискового раздела
Definition: dpm.c:187
void fpu_init()
Инициализация FPU.
Definition: fpu.c:25
void initrd_sefs(size_t irdst, size_t irded)
Монтирует виртуальный диск с файловой системой Sayori Easy File System.
Definition: kernel.c:211
void kHandlerCMD(char *)
Обработка команд указаных ядру при загрузке
Definition: kernel.c:136
void __attribute__((noreturn))
Definition: kernel.c:243
#define INITRD_RW_SIZE
Размер виртуального диска 1.44mb floppy.
Definition: kernel.c:39
size_t CODE_start
Точка входа в ядро
void keyboardInit()
Выполняет инициализацию клавиатуры
Definition: keyboard.c:350
size_t filesize(const char *Path)
[FileIO] Возвращает размер указанного файла
Definition: fileio.c:67
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
uint32_t atoi(const char s[])
Превращает строку в число
Definition: string.c:565
bool strcmpn(const char *str1, const char *str2)
Сравнение строк
Definition: string.c:270
void mouse_install()
Установщик драйвера мыши
Definition: mouse.c:203
bool text_init(char *psf)
Инициализация шрифта PSF.
Definition: psf.c:32
void init_task_manager(void)
Инициализация менеджера задач
Definition: scheduler.c:33
uint32_t str_cdsp(const char *a_str, const char *del)
Функция отладки
Definition: split.c:22
void str_split(const char a_str[], char *out[], char *del)
Функция для деления строк
Definition: split.c:40
void fclose(FILE *stream)
Закончить работу с файлом
Definition: stdio.c:213
FILE * fopen(const char *filename, const char *_mode)
Открывает файл
Definition: stdio.c:166
int fsize(FILE *stream)
Получение размера файла в байтах
Definition: stdio.c:227
int fread(FILE *stream, size_t count, size_t size, void *buffer)
Чтение файла
Definition: stdio.c:250
Definition: eBat.h:91
Структура файла. Требуется для работы с VFS.
Definition: stdio.h:21
Definition: fat12.h:73
Definition: multiboot.h:102
Definition: cards.h:5
size_t getFrequency()
Получить частоту таймера
Definition: timer.c:43
size_t getTicks()
Получить количество тиков
Definition: timer.c:26
void init_timer(uint32_t f)
Инициализация модуля системного таймера
Definition: timer.c:93
void init_syscalls(void)
Инициализация системных вызовов
Definition: syscalls.c:140
void triggersConfig()
Инициализация триггеров
Definition: trigger.c:106
void tty_taskInit()
Инициализация потоков
Definition: tty.c:48
void tty_fontConfigurate()
Инициализация системы для печати через шрифты
Definition: tty.c:62
void tty_set_bgcolor(uint32_t color)
Изменение цвета заднего фона
Definition: tty.c:121
void tty_setcolor(uint32_t color)
Изменение цвета текста
Definition: tty.c:108
void drv_vbe_init(multiboot_header_t *mboot)
Definition: vbe.c:60