⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pm.c

📁 AT91RM9200的完整启动代码:包括loader, boot及U-boot三部分均已编译通过!欢迎下载使用!
💻 C
📖 第 1 页 / 共 4 页
字号:
            ioctl(_PM_console_fd, KDSKBMODE, mode.kb_mode);            ioctl(_PM_console_fd, KDSETLED, mode.leds);            tcsetattr(_PM_console_fd, TCSAFLUSH, &mode.termios);            fcntl(_PM_console_fd,F_SETFL,mode.flags);            }        fclose(kbmode);        unlink(path);        in_raw_mode = false;        }}/****************************************************************************REMARKS:Safely abort the event module upon catching a fatal error.****************************************************************************/void _PM_abort(    int signo){    char    buf[80];    sprintf(buf,"Terminating on signal %d",signo);    _PM_restore_kb_mode();    PM_fatalError(buf);}/****************************************************************************REMARKS:Put the keyboard into raw mode****************************************************************************/void _PM_keyboard_rawmode(void){    struct termios conf;    FILE            *kbmode;    keyboard_mode   mode;    char            path[PM_MAX_PATH];    int             i;    static int sig_list[] = {        SIGHUP,        SIGINT,        SIGQUIT,        SIGILL,        SIGTRAP,        SIGABRT,        SIGIOT,        SIGBUS,        SIGFPE,        SIGKILL,        SIGSEGV,        SIGTERM,        };    if ((kbmode = open_kb_mode("rb",path)) == NULL) {        if ((kbmode = open_kb_mode("wb",path)) == NULL)            PM_fatalError("Unable to open kbmode.dat file for writing!");        if (ioctl(_PM_console_fd, KDGKBMODE, &mode.kb_mode))            perror("KDGKBMODE");        ioctl(_PM_console_fd, KDGETLED, &mode.leds);        _PM_leds = mode.leds & 0xF;        _PM_modifiers = 0;        tcgetattr(_PM_console_fd, &mode.termios);        conf = mode.termios;        conf.c_lflag &= ~(ICANON | ECHO | ISIG);        conf.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | BRKINT | PARMRK | INPCK | IUCLC | IXON | IXOFF);        conf.c_iflag  |= (IGNBRK | IGNPAR);        conf.c_cc[VMIN] = 1;        conf.c_cc[VTIME] = 0;        conf.c_cc[VSUSP] = 0;        tcsetattr(_PM_console_fd, TCSAFLUSH, &conf);        mode.flags = fcntl(_PM_console_fd,F_GETFL);        if (ioctl(_PM_console_fd, KDSKBMODE, K_MEDIUMRAW))            perror("KDSKBMODE");        atexit(_PM_restore_kb_mode);        for (i = 0; i < sizeof(sig_list)/sizeof(sig_list[0]); i++)            signal(sig_list[i], _PM_abort);        mode.startup_vc = startup_vc;        if (fwrite(&mode,1,sizeof(mode),kbmode) != sizeof(mode))            PM_fatalError("Error writing kbmode.dat!");        fclose(kbmode);        in_raw_mode = true;        }}int PMAPI PM_kbhit(void){    fd_set s;    struct timeval tv = { 0, 0 };    if (console_count == 0)        PM_fatalError("You *must* open a console before using PM_kbhit!");    if (!in_raw_mode)        _PM_keyboard_rawmode();    FD_ZERO(&s);    FD_SET(_PM_console_fd, &s);    return select(_PM_console_fd+1, &s, NULL, NULL, &tv) > 0;}int PMAPI PM_getch(void){    static uchar    c;    int release;    static struct kbentry ke;    if (console_count == 0)        PM_fatalError("You *must* open a console before using PM_getch!");    if (!in_raw_mode)        _PM_keyboard_rawmode();    while (read(_PM_console_fd, &c, 1) > 0) {        release = c & 0x80;        c &= 0x7F;        if (release) {            switch(c){                case 42: case 54: // Shift                    _PM_modifiers &= ~KB_SHIFT;                    break;                case 29: case 97: // Control                    _PM_modifiers &= ~KB_CONTROL;                    break;                case 56: case 100: // Alt / AltGr                    _PM_modifiers &= ~KB_ALT;                    break;                }            continue;            }        switch (c) {            case 42: case 54: // Shift                _PM_modifiers |= KB_SHIFT;                 break;            case 29: case 97: // Control                _PM_modifiers |= KB_CONTROL;                break;            case 56: case 100: // Alt / AltGr                _PM_modifiers |= KB_ALT;                break;            case 58: // Caps Lock                _PM_modifiers ^= KB_CAPS;                ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);                break;            case 69: // Num Lock                _PM_modifiers ^= KB_NUMLOCK;                ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);                break;            case 70: // Scroll Lock                _PM_modifiers ^= KB_SCROLL;                ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);                break;            case 28:                return 0x1C;            default:                ke.kb_index = c;                ke.kb_table = 0;                if ((_PM_modifiers & KB_SHIFT) || (_PM_modifiers & KB_CAPS))                    ke.kb_table |= K_SHIFTTAB;                if (_PM_modifiers & KB_ALT)                    ke.kb_table |= K_ALTTAB;                ioctl(_PM_console_fd, KDGKBENT, (ulong)&ke);                c = ke.kb_value & 0xFF;                return c;            }        }    return 0;}/****************************************************************************REMARKS:Sleep until the virtual terminal is active****************************************************************************/static void wait_vt_active(    int _PM_console_fd){    while (ioctl(_PM_console_fd, VT_WAITACTIVE, tty_vc) < 0) {        if ((errno != EAGAIN) && (errno != EINTR)) {            perror("ioctl(VT_WAITACTIVE)");            exit(1);            }        usleep(150000);        }}/****************************************************************************REMARKS:Checks the owner of the specified virtual console.****************************************************************************/static int check_owner(    int vc){    struct stat sbuf;    char fname[30];    sprintf(fname, "/dev/tty%d", vc);    if ((stat(fname, &sbuf) >= 0) && (getuid() == sbuf.st_uid))        return 1;    printf("You must be the owner of the current console to use this program.\n");    return 0;}/****************************************************************************REMARKS:Checks if the console is currently in graphics mode, and if so we forciblyrestore it back to text mode again. This handles the case when a Nucleus orMGL program crashes and leaves the console in graphics mode. Running thetextmode utility (or any other Nucleus/MGL program) via a telnet sessioninto the machine will restore it back to normal.****************************************************************************/static void restore_text_console(    int console_id){    if (ioctl(console_id, KDSETMODE, KD_TEXT) < 0)        LOGWARN("ioctl(KDSETMODE) failed");    _PM_restore_kb_mode();}/****************************************************************************REMARKS:Opens up the console device for output by finding an appropriate virutalconsole that we can run on.****************************************************************************/PM_HWND PMAPI PM_openConsole(    PM_HWND hwndUser,    int device,    int xRes,    int yRes,    int bpp,    ibool fullScreen){    struct vt_mode  vtm;    struct vt_stat  vts;    struct stat     sbuf;    char            fname[30];    /* Check if we have already opened the console */    if (console_count++)        return _PM_console_fd;    /* Now, it would be great if we could use /dev/tty and see what it is     * connected to. Alas, we cannot find out reliably what VC /dev/tty is     * bound to. Thus we parse stdin through stderr for a reliable VC.     */    startup_vc = 0;    for (_PM_console_fd = 0; _PM_console_fd < 3; _PM_console_fd++) {        if (fstat(_PM_console_fd, &sbuf) < 0)            continue;        if (ioctl(_PM_console_fd, VT_GETMODE, &vtm) < 0)            continue;        if ((sbuf.st_rdev & 0xFF00) != 0x400)            continue;        if (!(sbuf.st_rdev & 0xFF))            continue;        tty_vc = sbuf.st_rdev & 0xFF;        restore_text_console(_PM_console_fd);        return _PM_console_fd;        }    if ((_PM_console_fd = open("/dev/console", O_RDWR)) < 0) {        printf("open_dev_console: can't open /dev/console \n");        exit(1);        }    if (ioctl(_PM_console_fd, VT_OPENQRY, &tty_vc) < 0)        goto Error;    if (tty_vc <= 0)        goto Error;    sprintf(fname, "/dev/tty%d", tty_vc);    close(_PM_console_fd);    /* Change our control terminal */    setsid();    /* We must use RDWR to allow for output... */    if (((_PM_console_fd = open(fname, O_RDWR)) >= 0) &&            (ioctl(_PM_console_fd, VT_GETSTATE, &vts) >= 0)) {        if (!check_owner(vts.v_active))            goto Error;        restore_text_console(_PM_console_fd);        /* Success, redirect all stdios */        fflush(stdin);        fflush(stdout);        fflush(stderr);        close(0);        close(1);        close(2);        dup(_PM_console_fd);        dup(_PM_console_fd);        dup(_PM_console_fd);        /* clear screen and switch to it */        fwrite("\e[H\e[J", 6, 1, stderr);        fflush(stderr);        if (tty_vc != vts.v_active) {            startup_vc = vts.v_active;            ioctl(_PM_console_fd, VT_ACTIVATE, tty_vc);            wait_vt_active(_PM_console_fd);            }        }    return _PM_console_fd;Error:    if (_PM_console_fd > 2)        close(_PM_console_fd);    console_count = 0;    PM_fatalError(        "Not running in a graphics capable console,\n"        "and unable to find one.\n");    return -1;}#define FONT_C  0x10000     /* 64KB for font data                       *//****************************************************************************REMARKS:Returns the size of the console state buffer.****************************************************************************/int PMAPI PM_getConsoleStateSize(void){    if (!inited)        PM_init();    return PM_getVGAStateSize() + FONT_C*2;}/****************************************************************************REMARKS:Save the state of the Linux console.****************************************************************************/void PMAPI PM_saveConsoleState(void *stateBuf,int console_id){    uchar   *regs = stateBuf;    /* Save the current console font */    if (ioctl(console_id,GIO_FONT,&regs[PM_getVGAStateSize()]) < 0)        perror("ioctl(GIO_FONT)");    /* Inform the Linux console that we are going into graphics mode */    if (ioctl(console_id, KDSETMODE, KD_GRAPHICS) < 0)        perror("ioctl(KDSETMODE)");    /* Save state of VGA registers */    PM_saveVGAState(stateBuf);}void PMAPI PM_setSuspendAppCallback(int (_ASMAPIP saveState)(int flags)){    /* TODO: Implement support for allowing console switching! */}/****************************************************************************REMARKS:Restore the state of the Linux console.****************************************************************************/void PMAPI PM_restoreConsoleState(const void *stateBuf,PM_HWND console_id){    const uchar *regs = stateBuf;    /* Restore the state of the VGA compatible registers */    PM_restoreVGAState(stateBuf);    /* Inform the Linux console that we are back from graphics modes */    if (ioctl(console_id, KDSETMODE, KD_TEXT) < 0)        LOGWARN("ioctl(KDSETMODE) failed");    /* Restore the old console font */    if (ioctl(console_id,PIO_FONT,&regs[PM_getVGAStateSize()]) < 0)        LOGWARN("ioctl(KDSETMODE) failed");    /* Coming back from graphics mode on Linux also restored the previous     * text mode console contents, so we need to clear the screen to get     * around this since the cursor does not get homed by our code.     */    fflush(stdout);    fflush(stderr);    printf("\033[H\033[J");    fflush(stdout);}/****************************************************************************REMARKS:Close the Linux console and put it back to normal.****************************************************************************/void PMAPI PM_closeConsole(PM_HWND _PM_console_fd){    /* Restore console to normal operation */    if (--console_count == 0) {        /* Re-activate the original virtual console */        if (startup_vc > 0)            ioctl(_PM_console_fd, VT_ACTIVATE, startup_vc);        /* Close the console file descriptor */        if (_PM_console_fd > 2)            close(_PM_console_fd);        _PM_console_fd = -1;        }}void PM_setOSCursorLocation(int x,int y){    /* Nothing to do in here */}/****************************************************************************REMARKS:Set the screen width and height for the Linux console.****************************************************************************/void PM_setOSScreenWidth(int width,int height){    struct winsize  ws;    struct vt_sizes vs;    // Resize the software terminal    ws.ws_col = width;    ws.ws_row = height;    ioctl(_PM_console_fd, TIOCSWINSZ, &ws);    // And the hardware    vs.v_rows = height;    vs.v_cols = width;    vs.v_scrollsize = 0;    ioctl(_PM_console_fd, VT_RESIZE, &vs);}ibool PMAPI PM_setRealTimeClockHandler(PM_intHandler ih, int frequency){    // TODO: Implement this for Linux    return false;}void PMAPI PM_setRealTimeClockFrequency(int frequency){    // TODO: Implement this for Linux}void PMAPI PM_restoreRealTimeClockHandler(void){    // TODO: Implement this for Linux}char * PMAPI PM_getCurrentPath(    char *path,    int maxLen){    return getcwd(path,maxLen);}char PMAPI PM_getBootDrive(void){ return '/'; }const char * PMAPI PM_getVBEAFPath(void){ return PM_getNucleusConfigPath(); }const char * PMAPI PM_getNucleusPath(void){    char *env = getenv("NUCLEUS_PATH");    return env ? env : "/usr/lib/nucleus";}const char * PMAPI PM_getNucleusConfigPath(void){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -