/** * This function should initialise the server, * and it not invoked after a re-exec. * * @return Non-zero on error */ int initialise_server(void) { struct vt_mode mode; char* display_env; int primary_socket_fd; int stage = 0; const char* const message = "Command: intercept\n" "Message ID: 0\n" "Length: 38\n" "\n" "Command: get-vt\n" "Command: configure-vt\n"; const char* const secondary_message = "Command: intercept\n" "Message ID: 0\n" "Priority: -4611686018427387904\n" /* −2⁶² */ "Length: 22\n" "\n" "Command: switching-vt\n"; primary_socket_fd = socket_fd; fail_if (connect_to_display()); secondary_socket_fd = socket_fd; socket_fd = primary_socket_fd; display_env = getenv("MDS_DISPLAY"); display_env = display_env ? strchr(display_env, ':') : NULL; if ((display_env == NULL) || (strlen(display_env) < 2)) goto no_display; memset(vtfile_path, 0, sizeof(vtfile_path)); xsnprintf(vtfile_path, "%s/%s.vt", MDS_RUNTIME_ROOT_DIRECTORY, display_env + 1); stage = 1; if (is_respawn == 0) { display_vt = select_vt(); fail_if (display_vt < 0); display_tty_fd = vt_open(display_vt, &old_vt_stat); fail_if (write_vt_file() < 0); fail_if (vt_set_active(display_vt) < 0); } else { fail_if (read_vt_file() < 0); vt_is_active = (display_vt == vt_get_active()); fail_if (vt_is_active < 0); } fail_if (full_send(secondary_socket_fd, secondary_message, strlen(secondary_message))); fail_if (full_send(socket_fd, message, strlen(message))); fail_if (server_initialised() < 0); fail_if (mds_message_initialise(&received)); stage = 2; fail_if (xsigaction(SIGRTMIN + 2, received_switch_vt) < 0); fail_if (xsigaction(SIGRTMIN + 3, received_switch_vt) < 0); vt_construct_mode(1, SIGRTMIN + 2, SIGRTMIN + 3, &mode); fail_if (vt_get_set_mode(display_tty_fd, 1, &mode) < 0); if (vt_set_exclusive(display_tty_fd, 1) < 0) xperror(*argv); return 0; no_display: eprint("no display has been set, how did this happen."); return 1; fail: xperror(*argv); if (stage >= 1) unlink(vtfile_path); if (display_tty_fd >= 0) vt_close(display_tty_fd, &old_vt_stat); if (stage >= 2) mds_message_destroy(&received); return 1; }
// Real entry point of the OS : void init() { unsigned int freq; interrupt_init(); earlyterm_init(); earlyterm_clear(); kbd_init(); rtc_init(); time_init(); earlyterm_write("Kernel initialization...\n"); set_kernel_print(&earlyterm_write); printk(LOG_INFO, "cmd args: '%s'\n", &cmdargs_begin); cmdline_parse(&cmdargs_begin, 1024); mmu_init(); pm_init_pages(); stimer_init(); hwkbd_start_periodic_update(); DBG_WAIT; interrupt_inhibit_all(0); // console initialisation as soon as possible dev_init(); // add TTY device (on major 4) ttydev_device.init(); dev_register_device(&ttydev_device, 4); // add virtual terminal TTYs vt_init(); // USB initialisation usb_init(); // add usb-acm TTY acm_usb_init(); DBG_WAIT; // will be the last message displayed on early console printk(LOG_INFO, "Switching screen to tty1...\n The display will be cleared.\n"); console_make_active(); // in all cases, Virtual Terminals should be made active (tty1) DBG_WAIT; vt_set_active(0); // need to be changed for "overclocking" : //freq_change(FREQ_STC_4, FREQ_DIV_1, FREQ_DIV_4); freq_time_calibrate(); freq = freq_get_internal_hz(); printk(LOG_INFO, "CPU freq : %d.%dMHz\n", freq/1000000, (freq/100000)%10); freq = freq_get_peripheral_hz(); printk(LOG_INFO, "Peripheral freq : %d.%dMHz\n", freq/1000000, (freq/100000)%10); // initialize sysctl tables ctl_init(); //test_keyboard_int(); //test_virtual_mem(); //asm volatile ("trapa #50"); //DBG_WAIT; // Initializing VFS and device sub-sytems, mount platform filesystems, // register platform devices... vfs_init(); vfs_file_init(); vfs_register_fs(&smemfs_file_system, VFS_REGISTER_STATIC); vfs_register_fs(&protofs_file_system, VFS_REGISTER_STATIC); vfs_mount("protofs", NULL, VFS_MOUNT_ROOT); vfs_create("/", "dev", INODE_TYPE_PARENT, INODE_FLAG_READ | INODE_FLAG_EXEC, 0); vfs_create("/dev", "tty1", INODE_TYPE_DEV, INODE_FLAG_WRITE, 0x00040000); vfs_create("/dev", "tty2", INODE_TYPE_DEV, INODE_FLAG_WRITE, 0x00040001); vfs_create("/dev", "serial", INODE_TYPE_DEV, INODE_FLAG_WRITE, 0x00030000); vfs_create("/dev", "console", INODE_TYPE_DEV, INODE_FLAG_WRITE, console_get_device()); DBG_WAIT; // keyboard input for virtual terminals kbd_set_kstroke_handler(&vt_key_stroke); // mount additional filesystems vfs_create("/", "mnt", INODE_TYPE_PARENT, INODE_FLAG_WRITE, 0); vfs_create("/mnt", "smem", INODE_TYPE_PARENT, INODE_FLAG_WRITE, 0); vfs_mount("smemfs", "/mnt/smem", VFS_MOUNT_NORMAL); DBG_WAIT; // set /dev/display device _display_device.init(); dev_register_device(&_display_device, 0x20); vfs_create("/dev", "display", INODE_TYPE_DEV, INODE_FLAG_WRITE, 0x00200001); // direct keyboard device on major 0x21 fxkeyboard_device.init(); dev_register_device(&fxkeyboard_device, 0x21); vfs_create("/dev", "keyboard", INODE_TYPE_DEV, INODE_FLAG_WRITE, 0x00210000); DBG_WAIT; //test_keymatrix(); // test_keyboard(); /*while(1) { char c; if(vfs_read(console, &c, 1) == 1) { vfs_write(console, &c, 1); } }*/ DBG_WAIT; //test_vfs(); //test_sdcard(); //test_sleep_funcs(); // EEPROM-related code commented to avoid useless write cycles ;) //test_eeprom(); /*char mybuf[128]; int len; len = usb_receive(USB_EP_ADDR_EP1OUT, mybuf, 10, 0); printk(LOG_DEBUG, "usb_receive ret=%d\n", len); if(len > 0) { mybuf[len] = '\0'; printk(LOG_DEBUG, "content = '%s'\n", mybuf); } while(!_magic_lock); set_kernel_print(&print_usb_ep2); test_vfs(); */ // memory area subsystem mem_area_init(); process_init(); sched_init(); test_process(); printk(LOG_WARNING, "End of init job, sleeping...\n"); while(1) printk(LOG_WARNING, "IER: 0x%x 0x%x\n", USB.IFR0.BYTE, USB.IFR1.BYTE); }