请教一个弱智的内核编程问题

内核编译和嵌入式产品的设计与开发
小左
帖子: 55
注册时间: 2008-05-09 22:00
联系:

请教一个弱智的内核编程问题

#1

帖子 小左 » 2008-06-01 21:11

小弟刚开始接触潜入式系统,写了一个程序,请大侠们指点一下:
/*hello.c*/
#include<linux/init.h>
#include<linux/module.h>
#include<linux/moduleparam.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "hello,world\n");
return 0;
}
static int hello_exit(void)
{
printk(KERN_ALERT "goodbye,world\n");
return 0;
}
module_init(hello_init);
module_exit(hello_exit);

之后写了一个makefile程序
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD :=$(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY:modules modules_install clean
else
obj-m:=hello.o
endif

在根目录下执行make,结果如下:
root@wuyi:/home/wuyi/hello# make
make -C /lib/modules/2.6.24-16-generic/build M=/home/wuyi/hello modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.24-16-generic'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory `/usr/src/linux-headers-2.6.24-16-generic'
在此目录下执行:insmod hello.ko,结果什么都看不到,恳请大侠指点,这是怎么回事阿,谢谢
这个问题看起来问的有点弱智,但小地我真的很想知道这是为什么
孤城吹雪
帖子: 1
注册时间: 2008-07-01 11:44

#2

帖子 孤城吹雪 » 2008-07-01 11:56

好像要把 代码放到一个内核的/drivers/char下面 再修改makefile,然后make modules
用insmod 把模块加入进去
elechi
帖子: 14
注册时间: 2006-03-30 21:26

#3

帖子 elechi » 2008-07-03 16:55

应该是printk的级别问题,你试着把KERN_ALERT改成其它不同的级别试试。
hanvy_xia
帖子: 11
注册时间: 2008-01-28 9:55

#4

帖子 hanvy_xia » 2008-07-10 9:52

有可能输出到 /var/log/messages cat看看有没有打印
hanvy_xia
帖子: 11
注册时间: 2008-01-28 9:55

#5

帖子 hanvy_xia » 2008-07-10 13:58

在/var/log/syslog

#cat /var/log/syslog
#kernel: [17306.492000] Hello, world
#kernel: [17572.404000] Goodbye, cruel world
#kernel: [17574.548000] Hello, world
hcd007
帖子: 29
注册时间: 2008-06-10 22:53
来自: 深圳

#6

帖子 hcd007 » 2008-07-13 12:09

在root用户下执行insmod ./hello.ko。没有错误提示的话,
这个程序就被执行了,可能是与系统的默认打印级别有关,
运行一下dmesg,最后一行是不是可以看到hello,world字样,
再执行rmmod hello
运行dmesg,最后一行又出现了goodbye,world。
裸奔时代
和月瑛泓
帖子: 2
注册时间: 2008-07-02 13:12

#7

帖子 和月瑛泓 » 2008-07-16 16:03

看不见就对了。 cat /var/log/messages 可看见。

printk 是内核的调用接口,它在系统init之前,把消息写往控制台,但是一旦系统init之后,便改写到系统的日志中。因为init之后用户所能够感受到的进程(拥有控制台)都是用户空间的进程,而用户空间的进程是无法反映内核数据的,除非通过一定的方式(如proc文件,netlink...)向内核申请相关的信息,并在用户空间反映出来.这样做的好处不言而喻的,如果内核在任何的时候都可以写信息到控制台,那控制台一定会被这样的信息淹没,而无法工作。

系统初始化进程(pid=0),工作在内核空间,它在启动init进程(pid=1)之前,把所有的信息通过printk内核方法写往控制台.printk把欲打印的日志消息,首先首先保存到内核的日志缓冲区之中.而后申请控制台的信号量,如果申请到,则调用控制台写方法,写控制台.而此时系统中并没有打开控制台,故而初始化进程,可以申请到控制台的信号量.当系统初始化到达一定阶段后,便会启动init进程(pid=1),并在此之前打开控制台,控制台的信号量增加,此后,printk便无法申请到信号量,而无法写数据到控制台.转而通过和用户空间的进程协作把内核的日志消息写到系统道的日志文件之中.-------前台进程通过sys_log系统调用读出,并根据配置文件sys_conf写向相应的日志文件或/var/log/messages文件中。

读printk原码可知流程。
上次由 和月瑛泓 在 2008-12-01 13:41,总共编辑 3 次。
王谋先
帖子: 4
注册时间: 2008-08-16 15:49

#8

帖子 王谋先 » 2008-08-17 9:21

你的程序和编译语句都没有错。

你在hello.ko下的目录,
你这里应该用编译命令:

insmod ./hello.ko

运行一下dmesg,最后一行可以看到hello,world字样,

再执行:
rmmod hello

运行dmesg,最后一行又出现了goodbye,world。
这样才可以。
xlongfeng
帖子: 9
注册时间: 2006-10-08 16:32

#9

帖子 xlongfeng » 2008-09-04 22:50

在终端模式下插入,不要在X下,就可以看到了。
singyea
帖子: 8
注册时间: 2008-09-01 17:08

#10

帖子 singyea » 2008-09-07 11:31

和月瑛泓 写了:看不见就对了。 cat /var/log/messages 可看见。

printk 是内核的调用接口,它在系统init之前,把消息写往控制台,但是一旦系统init之后,便改写到系统的日志中。

这样做的好处不言而喻的,如果内核在任何的时候都可以写信息到控制台,那控制台一定会被这样的信息淹没,而无法工作。printk的实现很简单,就是在有了日志消息后,首先申请控制台的信号量,如果申请到,则调用控制台写方法,写控制台。当linux初始化完成的时候,会在init之前打开控制台,此后,printk便无法申请到信号量,而把消息组织为skb发往特定的netlink缓冲区,由klogd读出,写向/var/log/messages文件中。

读printk原码可知流程。
正解~~。

printk的输出在内核空间,而控制台的输出在用户空间。
dysunset
帖子: 7
注册时间: 2009-03-17 19:01

Re: 请教一个弱智的内核编程问题

#11

帖子 dysunset » 2009-06-14 10:07

感谢5--10楼的强人们!
fin_mai
帖子: 9
注册时间: 2009-06-28 14:16

Re: 请教一个弱智的内核编程问题

#12

帖子 fin_mai » 2009-06-28 14:57

用dmesg看看吧
glance
帖子: 12
注册时间: 2009-06-10 3:16

Re: 请教一个弱智的内核编程问题

#13

帖子 glance » 2009-06-29 10:10

还显示messages最后10条:
cat /var/log/messages | tail -10
头像
infinite180
帖子: 207
注册时间: 2007-05-31 20:17
来自: DUT
联系:

Re:

#14

帖子 infinite180 » 2009-07-08 1:49

和月瑛泓 写了:看不见就对了。 cat /var/log/messages 可看见。

printk 是内核的调用接口,它在系统init之前,把消息写往控制台,但是一旦系统init之后,便改写到系统的日志中。因为init之后用户所能够感受到的进程(拥有控制台)都是用户空间的进程,而用户空间的进程是无法反映内核数据的,除非通过一定的方式(如proc文件,netlink...)向内核申请相关的信息,并在用户空间反映出来.这样做的好处不言而喻的,如果内核在任何的时候都可以写信息到控制台,那控制台一定会被这样的信息淹没,而无法工作。

系统初始化进程(pid=0),工作在内核空间,它在启动init进程(pid=1)之前,把所有的信息通过printk内核方法写往控制台.printk把欲打印的日志消息,首先首先保存到内核的日志缓冲区之中.而后申请控制台的信号量,如果申请到,则调用控制台写方法,写控制台.而此时系统中并没有打开控制台,故而初始化进程,可以申请到控制台的信号量.当系统初始化到达一定阶段后,便会启动init进程(pid=1),并在此之前打开控制台,控制台的信号量增加,此后,printk便无法申请到信号量,而无法写数据到控制台.转而通过和用户空间的进程协作把内核的日志消息写到系统道的日志文件之中.-------前台进程通过sys_log系统调用读出,并根据配置文件sys_conf写向相应的日志文件或/var/log/messages文件中。

读printk原码可知流程。
学习
I can do if I try!!!
iceke
帖子: 9
注册时间: 2009-08-02 20:55

Re: 请教一个弱智的内核编程问题

#15

帖子 iceke » 2009-08-05 17:01

7楼的答案是对的,但是你也可以直接在控制台(tty)运行,然后就可以看到信息了。
注意:不是图形界面的虚拟终端。
回复