• I was talking with a friend the other day about questions we’ve used in interviews for programmers. One of my pet peeves is the obscenely specific questions which boil down to “how would you solve this particular problem we have right now?” If I were asked that kind of question in an interview, I would have to wonder if the company was at all interested in the long-term effectiveness of their employees, and whether they care to let them learn and grow into more productive programmers. Interviews need to establish a basic level of competence, but most importantly they need to determine whether the candidate knows what he doesn’t know and can learn on the job.

    On the other hand, I always tried to avoid asking questions that had nothing to do with programming, such as why are manhole covers round?. My friend told me of a great one he uses: “if I type ‘ping www.kqk4663.com‘ into a terminal at a UNIX box and hit return, what happens?” It’s been a while since I thought about the low-level hardware and software that makes ping possible, so as an exercise I wrote up the chain of events that occur on an 80×86 box running Linux:

    8059.pngA typical PS/2 keyboard has an onboard chip which detects keypresses and handles things like “debouncing” the switches. Different keyboards have different key mechanisms, so there is a variety of encoder chips (the Intel 8048 was popular early on), but the end result is a serial data signal sent through the keyboard cord to a controller chip on the motherboard. This data consists of (possibly multibyte) sequences called “scan codes.” For each key there are two unique scan codes: a “make code” which is sent when the key is pressed, and a “break code” which is sent when it is released.

    The controller chip is an Intel 8042-compatible device which handles decoding the serial stream from the keyboard, and telling the CPU about keypresses. It may also be integrated into the motherboard’s chipset. The CPU talks to it via I/O space addressing at locations 0×60 (data buffer) and 0×64 (status/commands).

    A typical PC contains two 8259 Programmable Interrupt Controller chips (which may be part of a chipset), or one of it’s more advanced descendants.
    8259.png
    The first one which controls the INT line of the CPU. It has eight interrupt inputs, IRQ0IRQ7, each of which can be hooked up to a peripheral device, one of which is the second “cascaded” 8259 on IRQ2. This allows for fifteen devices to interrupt the PC. The keyboard controller’s interrupt line is connected to IRQ1.

    When the INT line is raised, the processor immediately pushes the flags register and a return address onto the stack. It then fetches the interrupt vector (which IRQ line generated the interrupt) by lowering the INTA line to retrieve it from the 8259.

    Given the IRQ vector, it CPU must look up the address of the code which will handle the interrupt (a.k.a. the interrupt service routine, or ISR). On the original 8086, the CPU expects to find a table of 32-bit ISR pointers at address 0×0. But the 80286 and later processors have a register called idtr, which points to the system’s interrupt descriptor table in memory. Either way, the CPU uses the IRQ number as an index into these tables, retrieves a pointer to the ISR, pushes the flags register onto the stack, and jumps to that address. The ISR will return using the IRET instruction rather than RET to tell the processor to pop the flags register.

    Now, assuming that it set up the interrupt vector table properly at bootup, the kernel software is handling the interrupt. Next post, I’m going to dig into the Linux kernel and find out how it deals.

    Posted by jake on May 9, 2007 at 2:40 pm in Code.

    No Comments

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.