int openvt_main(int argc UNUSED_PARAM, char **argv) { char vtname[sizeof(VC_FORMAT) + sizeof(int)*3]; struct vt_stat vtstat; char *str_c; int vtno; int flags; enum { OPT_c = (1 << 0), OPT_w = (1 << 1), OPT_s = (1 << 2), OPT_l = (1 << 3), OPT_f = (1 << 4), OPT_v = (1 << 5), }; /* "+" - stop on first non-option */ flags = getopt32(argv, "+c:wslfv", &str_c); argv += optind; if (flags & OPT_c) { /* Check for illegal vt number: < 1 or > 63 */ vtno = xatou_range(str_c, 1, 63); } else { vtno = find_free_vtno(); } /* Grab new VT */ sprintf(vtname, VC_FORMAT, vtno); /* (Try to) clean up stray open fds above fd 2 */ bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS | DAEMON_ONLY_SANITIZE, NULL); close(STDIN_FILENO); /*setsid(); - BAD IDEA: after we exit, child is SIGHUPed... */ xopen(vtname, O_RDWR); xioctl(STDIN_FILENO, VT_GETSTATE, &vtstat); if (flags & OPT_s) { console_make_active(STDIN_FILENO, vtno); } if (!argv[0]) { argv--; argv[0] = getenv("SHELL"); if (!argv[0]) argv[0] = (char *) DEFAULT_SHELL; /*argv[1] = NULL; - already is */ } xdup2(STDIN_FILENO, STDOUT_FILENO); xdup2(STDIN_FILENO, STDERR_FILENO); #ifdef BLOAT { /* Handle -l (login shell) option */ const char *prog = argv[0]; if (flags & OPT_l) argv[0] = xasprintf("-%s", argv[0]); } #endif vfork_child(argv); if (flags & OPT_w) { /* We have only one child, wait for it */ safe_waitpid(-1, NULL, 0); /* loops on EINTR */ if (flags & OPT_s) { console_make_active(STDIN_FILENO, vtstat.v_active); // Compat: even with -c N (try to) disallocate: // # /usr/app/kbd-1.12/bin/openvt -f -c 9 -ws sleep 5 // openvt: could not deallocate console 9 xioctl(STDIN_FILENO, VT_DISALLOCATE, (void*)(ptrdiff_t)vtno); } } return EXIT_SUCCESS; }
// 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); }