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
We use the channal 2
http://wiki.osdev.org/Programmable_Interval_Timer
No comments:
Post a Comment