The Windows API has a Beep function, which is used to make a beep sound. This beep function has a long history, and the BIOS alarm sound comes from the motherboard beeper. Its principle is to call the Programmable Interval Timer (PIT) that almost every machine has. Unfortunately, starting from Windows Vista, the behavior of this function has become to call the speaker to make a sound, and it is no longer using the motherboard beeper to make a sound.

How to use the motherboard beeper to make a sound in systems above Windows Vista? Do you have to write a Windows driver? In fact, using the function of the WinDbg kernel debugger, it can be done with just one line of code. The following line of code makes the motherboard beeper sound at a frequency of 800 Hz for 1000 milliseconds.

1
n 10; r $t0=800; r $t1=1000; ob 0x43 0xb6; ob 0x42 (1193180/$t0)&0xff; ob 0x42 (1193180/$t0)>>8; ob 0x61 3; .sleep $t1; ob 0x61 0

How to use:

  1. Download and install WinDbg
  2. Open kernel debugging. Run with administrator privileges
    1
    bcdedit /debug on
    , and restart.
  3. Open WinDbg with administrator privileges, File->Kernel Debug, select the “Local” tab, and confirm. If everything goes well, you will enter the kernel debug session.
  4. Enter this code, if your motherboard beeper is normal, you should be able to hear the beep sound. (Unfortunately, there is no sound in the screenshot)

Principle:

1
2
3
4
5
6
7
8
9
n 10;          设置十进制,默认 WinDbg 是 16 进制
r $t0=800; 设置 WinDbg 内部寄存器 t0 为 800,表示发声频率
r $t1=1000; 设置 WinDbg 内部寄存器 t1 为 1000,表示发声时长(毫秒)
ob 0x43 0xb6; 设置 PIT 输出到主板蜂鸣器的 PWM 波周期(这里的 ob 和 Linux 的 outb 相同)
ob 0x42 (1193180/$t0)&0xff; PWM 波周期的低字节
ob 0x42 (1193180/$t0)>>8; PWM 波周期的高字节
ob 0x61 3; 开始发声
.sleep $t1; 持续发声 $t1 这么长时间(毫秒)
ob 0x61 0; 发声结束

Thanks to The Square Root of Negative One (zzh1996) for the question.

Reference: http://wiki.osdev.org/PC_Speaker

Comments

2016-12-24