[funini.com] -> [kei@sodan] -> Kernel Reading

root/arch/x86/boot/tty.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. putchar
  2. puts
  3. gettime
  4. getchar
  5. kbd_pending
  6. kbd_flush
  7. getchar_timeout

/* -*- linux-c -*- ------------------------------------------------------- *
 *
 *   Copyright (C) 1991, 1992 Linus Torvalds
 *   Copyright 2007 rPath, Inc. - All Rights Reserved
 *
 *   This file is part of the Linux kernel, and is made available under
 *   the terms of the GNU General Public License version 2.
 *
 * ----------------------------------------------------------------------- */

/*
 * Very simple screen I/O
 * XXX: Probably should add very simple serial I/O?
 */

#include "boot.h"

/*
 * These functions are in .inittext so they can be used to signal
 * error during initialization.
 */

void __attribute__((section(".inittext"))) putchar(int ch)
{
        unsigned char c = ch;

        if (c == '\n')
                putchar('\r');  /* \n -> \r\n */

        /* int $0x10 is known to have bugs involving touching registers
           it shouldn't.  Be extra conservative... */
        asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal"
                     : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
}

void __attribute__((section(".inittext"))) puts(const char *str)
{
        int n = 0;
        while (*str) {
                putchar(*str++);
                n++;
        }
}

/*
 * Read the CMOS clock through the BIOS, and return the
 * seconds in BCD.
 */

static u8 gettime(void)
{
        u16 ax = 0x0200;
        u16 cx, dx;

        asm volatile("int $0x1a"
                     : "+a" (ax), "=c" (cx), "=d" (dx)
                     : : "ebx", "esi", "edi");

        return dx >> 8;
}

/*
 * Read from the keyboard
 */
int getchar(void)
{
        u16 ax = 0;
        asm volatile("int $0x16" : "+a" (ax));

        return ax & 0xff;
}

static int kbd_pending(void)
{
        u8 pending;
        asm volatile("int $0x16; setnz %0"
                     : "=rm" (pending)
                     : "a" (0x0100));
        return pending;
}

void kbd_flush(void)
{
        for (;;) {
                if (!kbd_pending())
                        break;
                getchar();
        }
}

int getchar_timeout(void)
{
        int cnt = 30;
        int t0, t1;

        t0 = gettime();

        while (cnt) {
                if (kbd_pending())
                        return getchar();

                t1 = gettime();
                if (t0 != t1) {
                        cnt--;
                        t0 = t1;
                }
        }

        return 0;               /* Timeout! */
}

/* [<][>][^][v][top][bottom][index][help] */

[funini.com] -> [kei@sodan] -> Kernel Reading