阅读:1501回复:4
请问如何在LINUX KERNEL 下运行(用户)程序?
各位大侠,我实在不知该怎样定标题,或许标题就很弱质,但意思如下:
我想写一个找到PCI总线上设备的小程序(输入VENDOR ID 和DEVICE ID, 终端上显示其BUS# DEV# FUNC#以及该设备的IoBaseAddr).其中要使用KERNEL下的对端口的输入输出操作.我写了一个很奇怪的程序: #define __KERNEL__ #include<linux/kernel.h> #include<asm/io.h> #define IC_SIGNATURE 0x244b8086 #define MAX_BUS_NUM 4 #define MAX_DEV_NUM 0x20 #define MAX_FUNC_NUM 8 #define USHORT unsigned short typedef struct { USHORT reg_num :8; USHORT fun_num :3; USHORT dev_num :5; USHORT bus_num :8; USHORT reserved:7; USHORT enable :1; }PCI_CFG_ADDR,*PPCI_CFG_ADDR; PCI_CFG_ADDR pci_cfg={0,}; unsigned long IoBaseAddr; unsigned long location; int find_adapter() { unsigned int bus,dev,func; unsigned long signature; unsigned long *lp; unsigned char ch0,ch1,ch2,ch3; int find_device=0; pci_cfg.enable=1; pci_cfg.reg_num=0; for(bus=0;bus<MAX_BUS_NUM;bus++) { for(dev=0;dev<MAX_DEV_NUM;dev++) { for(func=0;func<MAX_FUNC_NUM;func++){ pci_cfg.bus_num=bus; pci_cfg.dev_num=dev; pci_cfg.fun_num=func; lp=(unsigned long *)&pci_cfg; /* ch0=*((char *)lp+0); ch1=*((char *)lp+1); ch2=*((char *)lp+2); ch3=*((char *)lp+3);*/ outl_p(*lp,0xcf8); signature=inl_p(0xcfc); if(signature==IC_SIGNATURE) { find_device=1; break; } } if(find_device==1) break; } if(find_device==1) break; } if(find_device){ pci_cfg.reg_num=0x20; lp=(unsigned long *) &pci_cfg; location=*lp; outl_p(0xcf8,*lp); IoBaseAddr=inl(0xcfc); } return find_device; } int main(void) { if(find_adapter()) { printk("<5>FIND HARDDEVICE!\n"); printk("<5>location:%ld,IoBaseAddr:%ld\n",location,IoBaseAddr); return 1; }else{ printk("<5>FINDING DEVICE ERROR!\n"); return 0; } } 结果编译正常,运行时却说"段错误". 我知道有问题,但也说不出个所以然,另外,请问我该怎么办才能达到目的? 万分感激! |
|
沙发#
发布于:2004-02-22 18:18
本人刚发了一个附件,不知道管理员会不会接受,内容与你的要求类试,有源代码
解压后,./setup, showpci -l 显示大部分信息 -v num 表示vendor id -d num 表示device id -c num 表示class id 三个num都可以在pci_ids.h中指定的值中找到 如果你不知道任何一个id 可以执行showpci, 找到对应的id, showpci -l -v num -d num -c num 在X下,执行后察看sys log [编辑 - 2/22/04 by enLinux] |
|
|
板凳#
发布于:2004-02-20 09:48
别把kernel和user弄在一起啊,那岂不是很不稳定?
|
|
地板#
发布于:2004-02-19 13:54
kernel_1998:
一语惊醒梦中人! 非常感谢! 我现在正在测试初建安装并调用module的实验.但有个小问题,还望解答: 我写了个module (test.c),并编译成功,而且安装,并创立了设备文件.但是运行test_app.c时,却显示cannot open file!. 我查了下 /dev/test文件,大小为0.请问到底哪里有问题? 是module(test.c) 还是test_app.c? 源码如下: [root@terrace root]# cat test.c #include<linux/kernel.h> #include<linux/module.h> #include<linux/fs.h> #include<asm/uaccess.h> static char *pMessage="just for test!aaaaaaaaaaaaaaaaaaaaaaaaa"; /* static struct file_operations test_fops={ read:test_read, write:test_write, open:test_open, release:test_release, }; */ static unsigned int test_major =0; static int test_read(struct file *file,char *buf,size_t length,loff_t *offset) { int bytes_read=0; if(*pMessage==0) return 0; while(length&& *pMessage){ put_user(*(pMessage++),buf++); length--; bytes_read++; } printk("<1>Read %d bytes,%d left\n",bytes_read,length); return bytes_read; } static size_t test_write(struct file *file,const char *buf,size_t length,loff_t *offset) { return -EINVAL; } static int test_open(struct inode *inode,struct file *fle) { MOD_INC_USE_COUNT; return 0; } static void test_release(struct inode *inode,struct file *file) { MOD_DEC_USE_COUNT; } static struct file_operations test_fops={ read:test_read, write:test_write, open:test_open, release:test_release, }; int init_module(void) { int result=register_chrdev(0,"test",&test_fops); if(result<0){ printk("<1>test:can't get major number!\n"); return result; if (test_major==0) test_major=result; } return 0; } void clean_module(void) { unregister_chrdev(test_major,"test"); } [root@terrace root]# cat test_app.c #include<fcntl.h> #include<unistd.h> #include<stdio.h> int main() { int testdev; int i; char buf[20]; testdev=open("/dev/test",O_RDONLY); if(testdev =-1){ printf("cannot open file!\n"); exit(0); } read(testdev,buf,20); for(i=0;i<20;i++) printf("%c",buf); close(testdev); } [root@terrace root]# |
|
地下室#
发布于:2004-02-19 13:10
代码没什么问题,只不过用的方式错了。不过可以理解,任何人开始的时候都会犯这个错误。
solution: 你编译出来的程序是一个只能在用户态下运行的应用程序。它是不能访问IO地址空间的,这是你出错的主要原因; 我估计你读过一些PCI方面的资料,但对OS不是很了解,这里提供两个建议 (1)你要进行这样的操作,必须使用模块的方式,可以到网上找一些linux loadable module方面的资料,把你的program该成init_module和exit_module的形式。(记得操作的时候读一下就可以了,尽量不要写)《linux device driver》2nd是一个不错的开始。 (2)《Linux内核源代码情景分析》的下册设备驱动一章有对PCI操作的分析,可以一看。 |
|