printf到printk的转变

转载 2012年03月30日 11:56:36

昨天下午stepbystep的为其他同学演示了内核模块编程hello,kernel!在陈老师的指导下,先为大家演示了最基本的C程序hello,world。然后又一步步的转换成内核模块程序。在这一步步的转变过程中,我也发现了自己在学习内核模块中的不足,下面将下午遇到的一些问题总结如下。

一个简单的hello,world程序如下:

#include <\stdio.h\>
int main()
{
	printf("hello,world\n");
	return 0;
}

对于上面的程序,我们通常一步到位进行编译:

gcc hello.c -o hello

这样的命令简单方便,不过通常会让我们忽略从.c文件到可执行文件的整个编译过程。通常在使用gcc编译程序时,编译过程通常会分为4个阶段,即预处理(pre-processing),编译(compiling),汇编(assembling),链接(linking)。

在预处理阶段,一般输入的是.c文件,而输出的是.i文件。在此阶段中通常会处理源文件中的预处理命令,比如#define,#include,#ifdef等命令。如果想要生成这种.i中间文件,那么可以使用下面命令:

gcc -E hello.c -o hello.i

在编译阶段,输入的是.i中间文件,输出的是.s汇编语言文件。可以使用下面的命令:

gcc -S hello.i -o test.s

在汇编阶段,输入的是上一步产生的.s文件,产生的是二进制机器代码.o文件。此阶段对应的命令如下:

gcc -c test.s -o test.o

在链接阶段,输入的是.o二进制机器代码文件,连同其他的(如果有的话)机器代码文件和库文件一起汇集成一个可执行的二进制代码文件。

gcc test.o -o test

以上是一个程序编译完整的四个阶段。一般来说我们会将前三个阶段一步搞定,那么整个编译过程可以用下面两条命令就完成:

gcc -c test.c -o test.o
gcc test.o -o test

也就是先生成目标文件,再将目标文件连接成可执行文件。当你熟悉了整个编译过程后,可以用一开始我们说的一条命令来完成。

了解普通文件的编译过程,我们现在就将hello.c中的代码转换成模块编程中的.c代码。首先我们要更改头文件:

#include <\linux/kernel.h\>
#include <\linux/module.h\>

这与我们一般的头文件不同。一般我们在用户态下编写C程序,头文件会放在:/usr/include/下,而我们模块编程时,它使用的是内核中的头文件,一般在:cd /usr/src/linux-headers-2.6.32-21/include/。特别的我们这里使用的是include/目录下linux/这个子目录中的头文件,因此模块编译的时候会自动在内核中的include/目录下找linux/kernel.h这样的头文件。

其次,printf到printk是一个典型的用户态下编程与内核模块编程的不同。可能我们一开始会比较奇怪,为什么我make成功,加载也成功,但是就是不能显示printk里面的语句呢?我们可以这么想printk就是专门为内核“服务”。它一般输出的语句都在内核的日志文件当中。


printk和printf的区别

大部分常用的C库函数在Linux内核中都已经得到了实现。在所有没有实现的函数中,最著名的就数printf()函数了。内核代码虽然无法调用 printf()函数,但它可以调用printk()函数。pri...
  • tianfengw
  • tianfengw
  • 2014年09月02日 11:13
  • 1113

printk(%p的各种方式)

https://www.kernel.org/doc/Documentation/printk-formats.txt If variable is of Type, use printk f...
  • wbd880419
  • wbd880419
  • 2017年06月21日 11:55
  • 693

用函数printk打印内核信息的方法

Linux内核用函数printk打印调试信息,该函数的用法与C库打印函数printf格式类似,但在内核使用。用户可在内核代码中的某位置加入函数printk,直接把所关心的信息打打印到屏幕上或日志文件中...
  • emalwb
  • emalwb
  • 2014年02月27日 13:30
  • 1071

printk打印到LCD

command_line="initrd=0x30800000,0x440000 root=/dev/ram init=/linuxrc console=tty0"; 这样就可以改变系统的控制台了....
  • Tommy_wxie
  • Tommy_wxie
  • 2013年11月27日 18:46
  • 2368

printk和printf的区别

内核使用printk()打印! 应用层使用printf()打印! &&& 大部分常用的C库函数在Linux内核中都已经得到了实现。在所有没有实现的函数中,最著名的就数printf(...
  • u011638528
  • u011638528
  • 2013年08月14日 09:08
  • 380

用printf打印uint64_t的符号

在32位平台 typedef unsigned long long int uint64_t; 在64位平台 typedef unsigned long int uint64_t; 不同的t...
  • shenyanxxxy
  • shenyanxxxy
  • 2013年08月06日 10:57
  • 9792

printk和printf的区别

内核使用printk()打印! 应用层使用printf()打印! &&& 大部分常用的C库函数在Linux内核中都已经得到了实现。在所有没有实现的函数中,最著名的就数printf(...
  • ywok526
  • ywok526
  • 2014年04月08日 12:24
  • 436

c语言中 printf及 占位符%

功能c语言中产生格式化输出的函数(定义在 stdio.h 中)。向终端输出(显示器等)编辑本段用法int printf(const char *format,[argument]);format 参数...
  • specialistt
  • specialistt
  • 2013年06月17日 14:50
  • 4632

printk打印不能显示到终端的问题

http://blog.chinaunix.net/uid-25811099-id-326899.html printk   对于做嵌入式或者熟悉linux内核的人来说,对printk这个函数一定...
  • oMingZi12345678
  • oMingZi12345678
  • 2015年08月06日 13:06
  • 1396

printk打印不能显示到终端的解决方法

printk与printf有个不同的地方,就是printk有打印级别 使用printk时,Linux内核根据日志级别,可能把消息打印到当前控制台上,这个控制台是一个字符设备。这些消息从终端输出的前提是...
  • qustDrJHJ
  • qustDrJHJ
  • 2016年05月12日 10:54
  • 3047
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:printf到printk的转变
举报原因:
原因补充:

(最多只允许输入30个字)