Wednesday, August 28, 2013

Make Beep on x86 machines

http://hi.baidu.com/sfmewmddznjorye/item/afd09b5b867a9aadacc85757
http://jianggmulab.blogspot.com/search?q=beep

/*
 * IP port: 0x43
 Bits         Usage
 6 and 7      Select channel :
                 0 0 = Channel 0
                 0 1 = Channel 1
                 1 0 = Channel 2
                 1 1 = Read-back command (8254 only)
 4 and 5      Access mode :
                 0 0 = Latch count value command
                 0 1 = Access mode: lobyte only
                 1 0 = Access mode: hibyte only
                 1 1 = Access mode: lobyte/hibyte
 1 to 3       Operating mode :
                 0 0 0 = Mode 0 (interrupt on terminal count)
                 0 0 1 = Mode 1 (hardware re-triggerable one-shot)
                 0 1 0 = Mode 2 (rate generator)
                 0 1 1 = Mode 3 (square wave generator)
                 1 0 0 = Mode 4 (software triggered strobe)
                 1 0 1 = Mode 5 (hardware triggered strobe)
                 1 1 0 = Mode 2 (rate generator, same as 010b)
                 1 1 1 = Mode 3 (square wave generator, same as 011b)
 0            BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD
 *
 */
static void Beep(void)
{
    __asm__ volatile(
// configure Speaker IO controller
// set bit 0, 1 to 1
// IO port: 0x61
    "in $0x61, %al\n"
                "or $0x3, %al\n"
                "out %al, $0x61\n"

// set 8254 timer contol register
// IO port: 0x43
// 0xb6: 1011 0110
// channel2, access mode lo and hi, square wave
                "movb $0xb6, %al\n"
                "out %al, $0x43\n"

// set the high 8 bits of time2 counter
// IO port: 0x42
                "movb $0x0, %al\n"
                "out %al, $0x42\n"

// set the low 8 bits of timer2 counter
// IO port: 0x42
// use value $0x0f to firmware attack, high frequency
// use value $0xff to the configuration attack

                "movb $0x0f, %al\n"
                "out %al, $0x42\n"



   );
}


static void UnBeep(void)
{
    __asm__ volatile(
   // configure speaker IO contorller
   // set bit 0 and 1 to 0;
   // IO port: 0x61
   "in $0x61, %al\n"
   "and $0xFC, %al\n"
   "out %al, $0x61\n"
   );
}

the above code works on any x86 machines. It uses a timer counter existing on all x86 platforms. they all has Programmable interval timer Intel 8253
We use the channal 2

http://wiki.osdev.org/Programmable_Interval_Timer

No comments: