内联汇编控制PC蜂鸣器
本文,我们对控制PC蜂鸣器的操作改为使用内联汇编的方法,里面会使用到约束“a”和“dN”,其中前者对应eax,后者对应edx,并且N表示0-255之间的数,有了这些了解后,我们改造下“I/O映射之I/O端口”里的例子,改造后的代码如下:
#include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/timex.h> static int value = 0; module_param(value, int, 0644); MODULE_PARM_DESC(value, "the beep frequences(20,32767)"); static __init int ioport_beep_init(void) { unsigned int count = 0; u8 val; u16 port; if (value > 20 && value < 32767) count = PIT_TICK_RATE / value; if (count) { /* set command for counter 2, write 2 bytes */ val = 0xB6; port = 0x43; asm volatile("outb %0,%1" : : "a" (val), "dN" (port)); /* select desired HZ */ val = count & 0xff; port = 0x42; asm volatile("outb %0,%1" : : "a" (val), "dN" (port)); val = (count >> 8) & 0xff; asm volatile("outb %0,%1" : : "a" (val), "dN" (port)); /* enable counter 2 */ port = 0x61; asm volatile("inb %1,%0" : "=a" (val) : "dN" (port)); val = val | 3; asm volatile("outb %0,%1" : : "a" (val), "dN" (port)); } else { /* disable counter 2 */ port = 0x61; asm volatile("inb %1,%0" : "=a" (val) : "dN" (port)); val = val & 0xFC; asm volatile("outb %0,%1" : : "a" (val), "dN" (port)); } return 0; } static __exit void ioport_beep_exit(void) { u8 val; u16 port; /*disable counter 2 */ port = 0x61; asm volatile("inb %1,%0" : "=a" (val) : "dN" (port)); val = val & 0xFC; asm volatile("outb %0,%1" : : "a" (val), "dN" (port)); printk("Bye ioport_beep!\n"); } module_init(ioport_beep_init); module_exit(ioport_beep_exit); MODULE_LICENSE("GPL");
Makefile文件和源码文件名均未改变,从源码可以看出使用到了汇编的inb和outb指令,其用法也一目了然,这里也不多说了,有空再继续学习改造吧。
评论
发表评论