1、 编译内核出问题 2、 核心数据:关于防火墙流量统计数据? 3、 请问解决unresolved symbol 问题的具体操作步骤 4、 linux网卡驱动程序的问题 5、 如何得到内核函数的使用手册
1、编译内核出问题,求救!!
我编译内核在make bzImage的时候老是出现错误, make[2]:***[ksyms.o] Error 1 make[2]:Leaving directory '/usr/src/linux-2.4.4/kernel' make[1]:***[first_rule]Error 2 make[1]:Leaving directory '/usr/src/linux-2.4.4/kernel' make:***[_dir_kernel] Error 2 这些表示什么意思?怎么看?
还有,编译的时候说有好些变量没declared(比如说,smp_num_cpus,在/usr/src/linux-2.4.4/include/linux/kernel_stat.h)中,可是我查了它是给定义了啊,这是怎么回事?多谢各位指点 #Try this simple way:
#make mrproper /* clean old config info */ #make clean /* clean old object file */ #make menuconfig /* do nothing,just exit and save config,all use default */ #make dep /* binding the configuration info */ #make bzImage /* it should work. */ #cp arch/i386/boot/bzImage /boot/bzImage_00 #vi /etc/lilo.conf /* add the new bzImage_00 to lilo */ #lilo #reboot
高,实在是高!真可以了.为什么会这样?前面两条命令起了什么作用?请高手指点.
你好,我第一次编译内核时,只注意了声卡支持,其他的按系统默认,编译顺利通过,重新引导也一切正常。在mount一个Fat16分区时,发现fs vfat can not be supported。我怀疑编译内核时MSDOS和VFAT是不是没有选上,就重新编译内核,特别的注意了这两个选项,其他照旧,结果make dep; make clean; make zImage都通过了,make modules时出了问题:
*** [dummy.o] error 1 *** [modsubdir_net] error 2 *** [mod_drivers] error 2
我该怎么办呢?如果说内核源码有问题,我第一次编译怎么没有出错呢。
我的内核版本:kernel-2.4.2-2 源码:kernel-source-2.4.2-2 kernel-headers-2.4.2-2 if u've configed modules,dunt forget to:
#make modules #make modules_install
and #make install will auto install the new kernel, but ... i'd rather install it by myself.
2、核心数据:关于防火墙流量统计数据?
在核心2.0时,有/proc/net/ip_acct文件用于存放防火墙流量统计数据;在核心2.2时,没有了此文件。只有/proc/net/ip_fwchains和 /proc/net/ip_fwnames 文件。请问,我如何访问以前的ip_acct文件中的数据呢?有相关的或是相对应的文件吗?它们的格式是什么?
你可以通过firewall library来访问每一条规则的流量统计信息。
3、请问解决unresolved symbol 问题的具体操作步骤
#以下是一个字符设备驱动程序例子的源代码: /* chardev.c * Copyright (C) 1998-1999 by Ori Pomerantz * * Create a character device (read only) */
/* The necessary header files */
/* Standard in kernel modules */ #include <linux/kernel.h> /* We're doing kernel work */ #include <linux/module.h> /* Specifically, a module */
/* Deal with CONFIG_MODVERSIONS */ #if CONFIG_MODVERSIONS==1 #define MODVERSIONS #include <linux/modversions.h> #endif
/* For character devices */ #include <linux/fs.h> /* The character device * definitions are here */ #include <linux/wrapper.h> /* A wrapper which does * next to nothing at * at present, but may * help for compatibility * with future versions * of Linux */
/* In 2.2.3 /usr/include/linux/version.h includes * a macro for this, but 2.0.35 doesn't - so I add * it here if necessary. */ #ifndef KERNEL_VERSION #define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c)) #endif
/* Conditional compilation. LINUX_VERSION_CODE is * the code (as per KERNEL_VERSION) of this version. */ #if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0) #include <asm/uaccess.h> /* for put_user */ #endif
#define SUCCESS 0
/* Device Declarations **************************** */
/* The name for our device, as it will appear * in /proc/devices */ #define DEVICE_NAME "char_dev"
/* The maximum length of the message from the device */ #define BUF_LEN 80
/* Is the device open right now? Used to prevent * concurent access into the same device */ static int Device_Open = 0;
/* The message the device will give when asked */ static char Message[BUF_LEN];
/* How far did the process reading the message * get? Useful if the message is larger than the size * of the buffer we get to fill in device_read. */ static char *Message_Ptr;
/* This function is called whenever a process * attempts to open the device file */ static int device_open(struct inode *inode, struct file *file) { static int counter = 0;
#ifdef DEBUG printk ("device_open(%p,%p) ", inode, file); #endif
/* This is how you get the minor device number in * case you have more than one physical device using * the driver. */ printk("Device: %d.%d ", inode->i_rdev >> 8, inode->i_rdev & 0xFF);
/* We don't want to talk to two processes at the * same time */ if (Device_Open) return -EBUSY;
/* If this was a process, we would have had to be * more careful here. * * In the case of processes, the danger would be * that one process might have check Device_Open * and then be replaced by the schedualer by another * process which runs this function. Then, when the * first process was back on the CPU, it would assume * the device is still not open. * * However, Linux guarantees that a process won't be * replaced while it is running in kernel context. * * In the case of SMP, one CPU might increment * Device_Open while another CPU is here, right after * the check. However, in version 2.0 of the * kernel this is not a problem because there's a lock * to guarantee only one CPU will be kernel module at * the same time. This is bad in terms of * performance, so version 2.2 changed it. * Unfortunately, I don't have access to an SMP box * to check how it works with SMP. */
Device_Open++;
/* Initialize the message. */ sprintf(Message, "If I told you once, I told you %d times - %s", counter++, "Hello, world "); /* The only reason we're allowed to do this sprintf * is because the maximum length of the message * (assuming 32 bit integers - up to 10 digits * with the minus sign) is less than BUF_LEN, which * is 80. BE CAREFUL NOT TO OVERFLOW BUFFERS, * ESPECIALLY IN THE KERNEL!!! */
Message_Ptr = Message;
/* Make sure that the module isn't removed while * the file is open by incrementing the usage count * (the number of opened references to the module, if * it's not zero rmmod will fail) */ MOD_INC_USE_COUNT;
return SUCCESS; }
/* This function is called when a process closes the * device file. It doesn't have a return value in * version 2.0.x because it can't fail (you must ALWAYS * be able to close a device). In version 2.2.x it is * allowed to fail - but we won't let it. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static int device_release(struct inode *inode, struct file *file) #else static void device_release(struct inode *inode, struct file *file) #endif { #ifdef DEBUG printk ("device_release(%p,%p) ", inode, file); #endif /* We're now ready for our next caller */ Device_Open --;
/* Decrement the usage count, otherwise once you * opened the file you'll never get rid of the module. */ MOD_DEC_USE_COUNT;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) return 0; #endif }
/* This function is called whenever a process which * have already opened the device file attempts to * read from it. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static ssize_t device_read(struct file *file, char *buffer, /* The buffer to fill with data */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */ #else static int device_read(struct inode *inode, struct file *file, char *buffer, /* The buffer to fill with * the data */ int length) /* The length of the buffer * (mustn't write beyond that!) */ #endif { /* Number of bytes actually written to the buffer */ int bytes_read = 0;
/* If we're at the end of the message, return 0 * (which signifies end of file) */ if (*Message_Ptr == 0) return 0;
/* Actually put the data into the buffer */ while (length && *Message_Ptr) {
/* Because the buffer is in the user data segment, * not the kernel data segment, assignment wouldn't * work. Instead, we have to use put_user which * copies data from the kernel data segment to the * user data segment. */ put_user(*(Message_Ptr++), buffer++);
length --; bytes_read ++; }
#ifdef DEBUG printk ("Read %d bytes, %d left ", bytes_read, length); #endif
/* Read functions are supposed to return the number * of bytes actually inserted into the buffer */ return bytes_read; }
/* This function is called when somebody tries to write * into our device file - unsupported in this example. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static ssize_t device_write(struct file *file, const char *buffer, /* The buffer */ size_t length, /* The length of the buffer */ loff_t *offset) /* Our offset in the file */ #else static int device_write(struct inode *inode, struct file *file, const char *buffer, int length) #endif { return -EINVAL; }
/* Module Declarations ***************************** */
/* The major device number for the device. This is * global (well, static, which in this context is global * within this file) because it has to be accessible * both for registration and for release. */ static int Major;
/* This structure will hold the functions to be * called when a process does something to the device * we created. Since a pointer to this structure is * kept in the devices table, it can't be local to * init_module. NULL is for unimplemented functions. */
struct file_operations Fops = { NULL, /* seek */ device_read, device_write, NULL, /* readdir */ NULL, /* select */ NULL, /* ioctl */ NULL, /* mmap */ device_open, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) NULL, /* flush */ #endif device_release /* a.k.a. close */ };
/* Initialize the module - Register the character device */ int init_module() { /* Register the character device (atleast try) */ Major = module_register_chrdev(0, DEVICE_NAME, &Fops);
/* Negative values signify an error */ if (Major < 0) { printk ("%s device failed with %d ", "Sorry, registering the character", Major); return Major; }
printk ("%s The major device number is %d. ", "Registeration is a success.", Major); printk ("If you want to talk to the device driver, "); printk ("you'll have to create a device file. "); printk ("We suggest you use: "); printk ("mknod <name> c %d <minor> ", Major); printk ("You can try different minor numbers %s", "and see what happens. ");
return 0; }
/* Cleanup - unregister the appropriate file from /proc */ void cleanup_module() { int ret;
/* Unregister the device */ ret = module_unregister_chrdev(Major, DEVICE_NAME); /* If there's an error, report it */ if (ret < 0) printk("Error in unregister_chrdev: %d ", ret); }
#Makefile是这样写的:
CC=gcc MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
chardev.o: chardev.c /usr/include/linux/version.h $(CC) $(MODCFLAGS) -c chardev.c
#insmod时出现错误:
unresolved symbol __put_user_X
请问大侠究竟是什么原因
是没有包含put_user函数所在的库吗? 还是内核版本问题?
#Makefile是这样写的: CC=gcc MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
chardev.o: chardev.c /usr/include/linux/version.h $(CC) $(MODCFLAGS) -c chardev.c 编译时加“O”参数 $(CC) -O $(MODCFLAGS) -c chardev.c 这是由于内核编程会用到很多内联函数(inline),需要此参数
为什么内联函数需要-O选项
内联函数需在编译期间被编译器整块拷贝到目标文件,就象处理宏一样
编译通过了, insmod也没有问题, 我测试了一下, 出了问题。 我的操作步骤(用的都是root): 1 mknod /dev/mychar c 254 0 /*insmod时主设备号为254*/ 2 test.c #include <stdio.h> #include <fcntl.h> #include <unistd.h>
int main() { int fd; char buf[80]; fd = open("mychar", O_RDONLY, 0); if(fd == -1) printf("error: open mychar"); else { if(read(fd, buf, 80) == -1) printf("read error!"); else printf("the read result is : %s", buf); }
}
3 gcc test.c -o test 4 ./test 提示: error: open mychar 请问斑竹, 这是为何?
文件路径错: 改为:mknod mychar c 254 0 或者: fd=open("/dev/mychar",O_RDWR);
4、linux网卡驱动程序的问题
我编了一个linux网卡驱动程序,我的网卡是NE2000的,其实我并没有使用NE2000的资料,因为我不知道,我只把网卡设为IRQ=3, I/O=OX300,编译通过,PING 自己可以,但PING 别人就不行了,甚至马上重启机器,问扎回事?
在用户模式下,进程访问到无效内存地枝是(一般是数组越界)一般是将进程的内存映射写成名为core 的文件,然后退出,而在内核模式下linux就无能为力啦,只好马上重起,linux 源带码中有ne2000的驱动源代码(/usr/src/linux/drivers/net/ne2k-pci.c),你可参考一下。
5、如何得到内核函数的使用手册
编驱动程序时,常回用到比如“printk,kfree,request_irq...."等等一系列内核函数,用man又不行,请问该怎么拌,谢谢!
/proc/kysms中既是
实在是对不起,我已看了kysms文件,里面只有函数名,后面跟一串以R开头的字符串,我还是不知道具体函数的用法,请赐教,谢谢。 在内核源码理查一下函数实现,不就知道用法了吗 。
责任编辑:axing(2001-06-06 17:24) | |