快速业务通道

在虚拟机下玩中断

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-03-30

记得以前学<<Linux Device Driver>>中断的章节,找了一块PCI转并口的卡,然后焊了一块小板,手动去触发中断.
最近看<<linux Kernel development>>中断的章节,已经是两年后了.找到了在虚拟机下调试内核的方法,也希望调试中断的实现可以在虚拟机下完成,而不是再去焊一块板子.

virtualbox里面的串口设置提供了这种功能,其中一个串口如前所述用于调试信息输出,可以另外再激活一个串口调试中断.

==============================================================
Port Number: COM2 IRQ: 3 I/O Port: 0x2F8
Port Mode: Host Pipe
Creat Pipe
Port/File_Path: /home/qianjiang/temp/test/myserial2
==============================================================

这样,启动虚拟机后,
# cat /proc/interrupts
CPU0
0: 133 XT-PIC-XT-PIC timer
1: 16 XT-PIC-XT-PIC i8042
2: 0 XT-PIC-XT-PIC cascade
3: 1 XT-PIC-XT-PIC
4: 926 XT-PIC-XT-PIC serial

其中第3个IRQ就是我们要用于调试的中断脚了.

写了一个内核模块来验证中断的生效,如下:

Makefile:
obj-m := uarttest.o

uarttest.c
其中8250控制器的寄存器描述参考:
http://www.doc88.com/p-95426735937.html for register description

==========================================================================
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/io.h>

MODULE_LICENSE("Dual BSD/GPL");

Empire CMS,phome.net

//typedef irqreturn_t (*irq_handler_t)(int, void *);
static irqreturn_t rtc_interrupt(int irq, void * dev_id)
{
u8 IIR;
u8 c;

do
{
IIR = inb(0x2fa); //中断状态寄存器
if((IIR & 0x01) == 0x01) break; //no interrupt

if((IIR & 0x06) == 0x06) //receive error
{
inb(0x2fd); //to clear error
printk(KERN_ALERT "receive error, clear it\n");
}
else if((IIR & 0x04) == 0x04) //receive data
{
c = inb(0x2f8);
printk(KERN_ALERT "got 0xx: %c\n", c, c);
}
else if((IIR & 0x02) == 0x02) //can send data
{
printk(KERN_ALERT "should not happen as we did not enable send data interrupt\n");
}
else
{
printk(KERN_ALERT "unkown interrupt 0xx\n", IIR);
}
}while(1);
return IRQ_HANDLED;
}

static int hello_init(void)
{
int ret;

printk(KERN_ALERT "Hello kernel\n");
ret = request_irq(3, rtc_interrupt, 0, "uart", NULL);
if(ret != 0)
{
printk("reqiest irq 3 failed\n");
}

//2fb 线路控制寄存器
outb(0xe3, 0x2fb);//DLAB=1 to set baudraut
outb(0x1, 0x2f8); outb(0x0, 0x2f9); //to set baudraut as 115200

outb(0x63, 0x2fb);//set DLAB=0 and set 8N1

//clear interrupt
inb(0x2fd); //read LSR(线路状态寄存器) to clear interrupt status if any error during receive
inb(0x2f8); //read

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号