Linux内核--基于Netfilter的内核级包过滤防火墙实现

测试内核版本:Linux Kernel 2.6.35----Linux Kernel 3.2.1

原创作品,转载请标明http://blog.csdn.net/yming0221/article/details/7572382

更多请查看专栏http://blog.csdn.net/column/details/linux-kernel-net.html

作者:闫明

知识基础:本防火墙的开发基于对Linux内核网络栈有个良好的概念,本人对网络栈的分析是基于早期版本(Linux 1.2.13),在明确了网络栈架构的前提下,上升一步分析高级版本内核中的Netfilter防火墙实现原理,然后进行模块或内核编程,开发一款基于包过滤的个人防火墙。

包过滤防火墙:包过滤防火墙是用一个软件查看所流经的数据包的包头(header),由此决定整个包的命运。它可能会决定丢弃(DROP)这个包,可能会接受(ACCEPT)这个包(让这个包通过),也可能执行其它更复杂的动作。工作于网络层,能对IP数据报进行首部检查。例如:IP源地址,目的地址,源端口和目的端口等。

本防火墙的包过滤功能如下:  

* 拒绝来自某主机或某网段的所有连接。
  * 允许来自某主机或某网段的所有连接。
  * 拒绝来自某主机或某网段的指定端口的连接。
  * 允许来自某主机或某网段的指定端口的连接。
  * 拒绝发去某主机或某网段的所有连接。
  * 允许发去某主机或某网段的所有连接。
  * 拒绝发去某主机或某网段的指定端口的连接。
  * 允许发去某主机或某网段的指定端口的连接。

Netfilter框架是Linux内核分析和过滤特定协议数据包处理框架,为其他模块动态参与网络层数据包处理提供了方便的途径。

该防火墙的总体结构如下:

本防火墙的简单功能就是检查数据包是否符合过滤的条件,如果不符合就舍弃(Drop),否则就接受(Accept),这里定义八个链表头结点

[cpp] view plain copy

  1. struct ip_node  ip_allowed_in_node_head;/*允许的远程主机或网络IP地址头节点*/
  2. struct ip_node  ip_denied_in_node_head;/*拒绝的远程主机或网络IP地址头节点*/
  3. struct ip_node  ip_allowed_out_node_head;/*允许的本地主机或网络IP地址头节点*/
  4. struct ip_node  ip_denied_out_node_head;/*拒绝的本地主机或网络IP地址头节点*/
  5. struct port_node port_allowed_in_node_head;/*允许的远程主机或网络传输层端口号头节点*/
  6. struct port_node port_denied_in_node_head;/*拒绝的远程主机或网络传输层端口号头节点*/
  7. struct port_node port_allowed_out_node_head;/*允许的本地主机或网络传输层端口号头节点*/
  8. struct port_node port_denied_out_node_head;/*拒绝的本地主机或网络传输层端口号头节点*/

用于保存配置文件中的地址或端口信息。

定义两个钩子函数hook_func_in和hook_func_out,分别将其挂载到INET协议族的入口NF_INET_LOCAL_IN和出口NF_INET_LOCAL_OUT:

[cpp] view plain copy

  1. static struct nf_hook_ops my_netfilter[] =
  2. {
  3. {
  4. .hook       =hook_func_in,
  5. .owner      =THIS_MODULE,
  6. .pf     =PF_INET,
  7. .hooknum    =NF_INET_LOCAL_IN,
  8. .priority   =100
  9. },
  10. {
  11. .hook       =hook_func_out,
  12. .owner      =THIS_MODULE,
  13. .pf     =PF_INET,
  14. .hooknum    =NF_INET_LOCAL_OUT,
  15. .priority   =100
  16. }
  17. };

说明一下自己定义的一些宏和引用的头文件:

[cpp] view plain copy

  1. #ifndef MODULE
  2. #define MODULE
  3. #endif
  4. #ifndef __KERNEL__
  5. #define __KERNEL__
  6. #endif
  7. //#define NET_DOWN
  8. #define MY_FIREWALL_DEBUG
  9. #include <asm/system.h>
  10. #include <linux/module.h>
  11. #include <linux/types.h>
  12. #include <linux/kernel.h>
  13. #include <linux/string.h>
  14. #include <linux/net.h>
  15. #include <linux/socket.h>
  16. #include <linux/sockios.h>
  17. #include <linux/in.h>
  18. #include <linux/inet.h>
  19. #include <net/ip.h>
  20. #include <net/protocol.h>
  21. #include <linux/skbuff.h>
  22. #include <net/sock.h>
  23. #include <net/icmp.h>
  24. #include <net/raw.h>
  25. #include <net/checksum.h>
  26. #include <linux/netfilter_ipv4.h>
  27. #include <linux/tcp.h>
  28. #include <linux/udp.h>
  29. #include <linux/igmp.h>
  30. #include <linux/fs.h>
  31. #include <linux/mm.h>
  32. #include <asm/uaccess.h>
  33. #define YES 1
  34. #define NO 0
  35. #define IP_MAX_LEN 20
  36. #define PORT_MAX_LEN 20
  37. #define ALLOWED_IP_IN 0
  38. #define DENIED_IP_IN 1
  39. #define ALLOWED_IP_OUT 2
  40. #define DENIED_IP_OUT 3
  41. #define ALLOWED_PORT_IN 0
  42. #define DENIED_PORT_IN 1
  43. #define ALLOWED_PORT_OUT 2
  44. #define DENIED_PORT_OUT 3
  45. #define ALLOWED_IN_IP_CONF_FILE_DIR "/etc/my_firewall/ip_allowed_in"
  46. #define DENIED_IN_IP_CONF_FILE_DIR "/etc/my_firewall/ip_denied_in"
  47. #define ALLOWED_IN_PORT_CONF_FILE_DIR "/etc/my_firewall/port_allowed_in"
  48. #define DENIED_IN_PORT_CONF_FILE_DIR "/etc/my_firewall/port_denied_in"
  49. #define ALLOWED_OUT_IP_CONF_FILE_DIR "/etc/my_firewall/ip_allowed_out"
  50. #define DENIED_OUT_IP_CONF_FILE_DIR "/etc/my_firewall/ip_denied_out"
  51. #define ALLOWED_OUT_PORT_CONF_FILE_DIR "/etc/my_firewall/port_allowed_out"
  52. #define DENIED_OUT_PORT_CONF_FILE_DIR "/etc/my_firewall/port_denied_out"
  53. //DEFINE FOR WORK_MODE
  54. /*不工作状态,默认*/
  55. #define MODE_FREE 0
  56. /*允许来自某主机或某网段的所有连接*/
  57. #define MODE_IP_ONLY_ALLOWED_IN 1
  58. /*拒绝来自某主机或某网段的所有连接*/
  59. #define MODE_IP_ONLY_DENIED_IN 2
  60. /*允许来自某主机或某网段指定端口的连接*/
  61. #define MODE_IP_PORT_ALLOWED_IN 3
  62. /*拒绝来自某主机或某网段的指定端口的连接*/
  63. #define MODE_IP_PORT_DENIED_IN 4
  64. /*允许本地主机或本地网络与其他主机或网络的所有连接*/
  65. #define MODE_IP_ONLY_ALLOWED_OUT 5
  66. /*拒绝本地主机或本地网络与其他主机或网络的所有连接*/
  67. #define MODE_IP_ONLY_DENIED_OUT 6
  68. /*允许本地主机或网络与其他主机或其他网络的指定端口的连接*/
  69. #define MODE_IP_PORT_ALLOWED_OUT 7
  70. /*拒绝本地主机或网络与其他主机或其他网络的指定端口的连接*/
  71. #define MODE_IP_PORT_DENIED_OUT 8

下面是防火墙模块的初始化函数:

[cpp] view plain copy

  1. int init_firewall()
  2. {
  3. (&ip_allowed_in_node_head)->next = NULL;
  4. (&ip_denied_in_node_head)->next = NULL;
  5. (&port_allowed_in_node_head)->next = NULL;
  6. (&port_denied_in_node_head)->next = NULL;
  7. (&ip_allowed_out_node_head)->next = NULL;
  8. (&ip_denied_out_node_head)->next = NULL;
  9. (&port_allowed_out_node_head)->next = NULL;
  10. (&port_denied_out_node_head)->next = NULL;
  11. switch(work_mode)
  12. {
  13. case MODE_IP_ONLY_ALLOWED_IN:
  14. open_ip_cfg_file(ALLOWED_IN_IP_CONF_FILE_DIR,ALLOWED_IP_IN);
  15. break;
  16. case MODE_IP_ONLY_DENIED_IN:
  17. open_ip_cfg_file(DENIED_IN_IP_CONF_FILE_DIR,DENIED_IP_IN);
  18. break;
  19. case MODE_IP_PORT_ALLOWED_IN:
  20. open_port_cfg_file(ALLOWED_IN_PORT_CONF_FILE_DIR,ALLOWED_PORT_IN);
  21. open_ip_cfg_file(ALLOWED_IN_IP_CONF_FILE_DIR,ALLOWED_IP_IN);
  22. break;
  23. case MODE_IP_PORT_DENIED_IN:
  24. open_port_cfg_file(DENIED_IN_PORT_CONF_FILE_DIR,DENIED_PORT_IN);
  25. open_ip_cfg_file(ALLOWED_IN_IP_CONF_FILE_DIR,ALLOWED_IP_IN);
  26. break;
  27. case MODE_IP_ONLY_ALLOWED_OUT:
  28. open_ip_cfg_file(ALLOWED_OUT_IP_CONF_FILE_DIR,ALLOWED_IP_OUT);
  29. break;
  30. case MODE_IP_ONLY_DENIED_OUT:
  31. open_ip_cfg_file(DENIED_OUT_IP_CONF_FILE_DIR,DENIED_IP_OUT);
  32. break;
  33. case MODE_IP_PORT_ALLOWED_OUT:
  34. open_port_cfg_file(ALLOWED_OUT_PORT_CONF_FILE_DIR,ALLOWED_PORT_OUT);
  35. open_ip_cfg_file(ALLOWED_OUT_IP_CONF_FILE_DIR,ALLOWED_IP_OUT);
  36. break;
  37. case MODE_IP_PORT_DENIED_OUT:
  38. open_port_cfg_file(DENIED_OUT_PORT_CONF_FILE_DIR,DENIED_PORT_OUT);
  39. open_ip_cfg_file(ALLOWED_OUT_IP_CONF_FILE_DIR,ALLOWED_IP_OUT);
  40. break;
  41. default:break;
  42. }
  43. //open_port_cfg_file(DENIED_PORT_CONF_FILE,DENIED_PORT);
  44. nf_register_hook(&my_netfilter[0]);
  45. nf_register_hook(&my_netfilter[1]);
  46. printk("INIT my firewall OK!\n");
  47. return 0;
  48. }

先从文件读取配置文件,加载到内核,然后注册钩子操作结构my_netfilter[0],my_netfilter[1]

下图是Netfilter的IPV4下的结构

上述的两个函数挂载位置NF_INET_LOCAL_IN和NF_INET_LOCAL_OUT,分别处理从本机发出和到达本机的数据包。

下面就是挂载到这两个挂载点的钩子函数,用于数据包的检查

[cpp] view plain copy

  1. static unsigned int hook_func_in(unsigned int hook,
  2. struct sk_buff *skb,
  3. const struct net_device *in,
  4. const struct net_device *out,
  5. int (*okfn)(struct sk_buff *))
  6. {
  7. #ifdef NET_DOWN
  8. return NF_DROP;
  9. #else
  10. struct iphdr *iph = ip_hdr(skb);
  11. __be32 saddr = ntohl(iph->saddr);
  12. __be16 sport = 0,dport = 0;
  13. if(trans_port(iph,skb,&sport,&dport) == NO && \
  14. work_mode == MODE_IP_PORT_ALLOWED_IN || \
  15. work_mode == MODE_IP_PORT_DENIED_IN)
  16. return NF_ACCEPT;
  17. #ifdef MY_FIREWALL_DEBUG
  18. __be32 daddr = ntohl(iph->daddr);
  19. printk("saddr= %u : %u  daddr= %u : %d\n",saddr,sport,daddr,dport);
  20. #endif
  21. switch(work_mode)
  22. {
  23. case MODE_FREE:
  24. return NF_ACCEPT;
  25. case MODE_IP_ONLY_ALLOWED_IN:
  26. if(ip_in_cfg_file(saddr,&ip_allowed_in_node_head))
  27. return NF_ACCEPT;
  28. else return NF_DROP;
  29. break;
  30. case MODE_IP_ONLY_DENIED_IN:
  31. if(ip_in_cfg_file(saddr,&ip_denied_in_node_head))
  32. return NF_DROP;
  33. else return NF_ACCEPT;
  34. break;
  35. case MODE_IP_PORT_ALLOWED_IN:
  36. if(ip_in_cfg_file(saddr,&ip_allowed_in_node_head) && \
  37. port_in_cfg_file(sport,&port_allowed_in_node_head))
  38. return NF_ACCEPT;
  39. else return NF_DROP;
  40. break;
  41. case MODE_IP_PORT_DENIED_IN:
  42. if(ip_in_cfg_file(saddr,&ip_allowed_in_node_head) && \
  43. !port_in_cfg_file(sport,&port_denied_in_node_head))
  44. return NF_ACCEPT;
  45. else return NF_DROP;
  46. break;
  47. default:
  48. return NF_DROP;
  49. break;
  50. }
  51. #endif
  52. }
  53. static unsigned int hook_func_out(unsigned int hook,
  54. struct sk_buff *skb,
  55. const struct net_device *in,
  56. const struct net_device *out,
  57. int (*okfn)(struct sk_buff *))
  58. {
  59. #ifdef NET_DOWN
  60. return NF_DROP;
  61. #else
  62. struct iphdr *iph = ip_hdr(skb);
  63. __be32 daddr = ntohl(iph->daddr);
  64. __be16 sport = 0,dport = 0;
  65. if(trans_port(iph,skb,&sport,&dport) == NO && \
  66. work_mode == MODE_IP_PORT_ALLOWED_OUT && \
  67. work_mode == MODE_IP_PORT_DENIED_OUT)
  68. return NF_ACCEPT;
  69. #ifdef MY_FIREWALL_DEBUG
  70. __be32 saddr = ntohl(iph->saddr);
  71. printk("saddr= %u : %u  daddr= %u : %d\n",saddr,sport,daddr,dport);
  72. #endif
  73. switch(work_mode)
  74. {
  75. case MODE_FREE:
  76. return NF_ACCEPT;
  77. case MODE_IP_ONLY_ALLOWED_OUT:
  78. if(ip_in_cfg_file(daddr,&ip_allowed_out_node_head))
  79. return NF_ACCEPT;
  80. else return NF_DROP;
  81. break;
  82. case MODE_IP_ONLY_DENIED_OUT:
  83. if(ip_in_cfg_file(daddr,&ip_denied_out_node_head))
  84. return NF_DROP;
  85. else return NF_ACCEPT;
  86. break;
  87. case MODE_IP_PORT_ALLOWED_OUT:
  88. if(ip_in_cfg_file(daddr,&ip_allowed_out_node_head) && \
  89. port_in_cfg_file(dport,&port_allowed_out_node_head))
  90. return NF_ACCEPT;
  91. else return NF_DROP;
  92. break;
  93. case MODE_IP_PORT_DENIED_OUT:
  94. if(ip_in_cfg_file(daddr,&ip_allowed_out_node_head) && \
  95. !port_in_cfg_file(dport,&port_denied_out_node_head))
  96. return NF_ACCEPT;
  97. else return NF_DROP;
  98. break;
  99. default:
  100. return NF_DROP;
  101. break;
  102. }
  103. #endif
  104. }

下面是打开文件并读取信息的函数,这里以打开IP地址的配置文件为例

[cpp] view plain copy

  1. static int open_ip_cfg_file(char * file_dir,int flag)
  2. {
  3. struct file * filp = NULL;
  4. char str[IP_MAX_LEN];
  5. int i = 0;
  6. if((filp = filp_open(file_dir,O_RDONLY,0)) < 0)
  7. return NO;
  8. mm_segment_t fs;
  9. fs = get_fs();
  10. set_fs(KERNEL_DS);
  11. struct ip_node * work = NULL;
  12. while((filp->f_op->read(filp,&str[i],1,&filp->f_pos)) == 1)
  13. {
  14. if(str[i] == ‘\n‘)//next line
  15. {
  16. str[i] = ‘\0‘;//the end of a string
  17. i = 0;
  18. #ifdef MY_FIREWALL_DEBUG
  19. printk("%s\n",str);
  20. #endif
  21. work = (struct ip_node *)kmalloc(sizeof(ip_allowed_in_node_head),GFP_ATOMIC);
  22. if( ip_to_unsigned(str,&(work->ip_start),&(work->ip_end)) == 0 )
  23. return NO;
  24. switch(flag)
  25. {
  26. case ALLOWED_IP_IN:
  27. work->next = (&ip_allowed_in_node_head)->next;
  28. (&ip_allowed_in_node_head)->next = work;//head insert
  29. break;
  30. case DENIED_IP_IN:
  31. work->next = (&ip_denied_in_node_head)->next;
  32. (&ip_denied_in_node_head)->next = work;//head insert
  33. break;
  34. case ALLOWED_IP_OUT:
  35. work->next = (&ip_allowed_out_node_head)->next;
  36. (&ip_allowed_out_node_head)->next = work;//head insert
  37. break;
  38. case DENIED_IP_OUT:
  39. work->next = (&ip_denied_out_node_head)->next;
  40. (&ip_denied_out_node_head)->next = work;//head insert
  41. break;
  42. default:break;
  43. }
  44. filp->f_op->read(filp,&str[0],1,&filp->f_pos);//eat the ‘\r‘
  45. }
  46. if(i > IP_MAX_LEN) return NO;
  47. i++;
  48. }
  49. return YES;
  50. }

这里配置文件中不仅支持具体的IP地址,还支持IP地址网段,例如

192.168.1.1

192.168.1.*

192.168.*.*

192.*.*.*

下面是处理函数

[cpp] view plain copy

  1. /************************************************
  2. str:The IP Address like 192.168.1.1
  3. start:The pointer to the start IP
  4. end:The pointer to the end IP
  5. ***********************************************/
  6. static int ip_to_unsigned(const char * str,unsigned int * start,unsigned int * end)
  7. {
  8. char cache[4][4];
  9. /*split the IP address*/
  10. int i;
  11. int k = 0;
  12. int j = 0;
  13. for(i = 0;str[i] != ‘\0‘;i++)
  14. {
  15. cache[j][k] = str[i];
  16. if(str[i] == ‘.‘)
  17. {
  18. cache[j][k] = ‘\0‘;
  19. k = 0;
  20. j++;
  21. }
  22. else k++;
  23. if(j > 3) return NO;
  24. }
  25. cache[3][k] = ‘\0‘;
  26. short int a[4];
  27. for(i = 0;i < 4;i++)
  28. {
  29. if(cache[i][0] != ‘*‘)
  30. {
  31. a[i] = (short)simple_strtol(cache[i],NULL,0);
  32. if(a[i] < 0 || a[i] > 255) return NO;
  33. }
  34. else
  35. {
  36. break;
  37. }
  38. }
  39. switch(i)
  40. {
  41. case 4:/*Specific IP Address eg.  192.168.1.1   */
  42. *start = *end = (a[0]<<24) + (a[1]<<16) + (a[2]<<8 )+a[3];
  43. break;
  44. case 3:/*  eg. 192.168.1.*   */
  45. *start = (a[0]<<24) + (a[1]<<16) + (a[2]<<8);
  46. *end = *start + (1<<8) - 1;
  47. break;
  48. case 2:/*  eg. 192.168.*.*   */
  49. *start = (a[0]<<24) + (a[1]<<16);
  50. *end = *start + (1<<16) - 1;
  51. break;
  52. case 1:/*  eg. 192.*.*.*    */
  53. *start = (a[0]<<24);
  54. *end = *start + (1<<24) - 1;
  55. break;
  56. default:
  57. *start = 0;
  58. *end = (1<<32) - 1;
  59. break;
  60. }
  61. return  YES;
  62. }

模块的移除函数

[cpp] view plain copy

  1. void remove_firewall()
  2. {
  3. free_ip_list(&ip_allowed_in_node_head);
  4. free_ip_list(&ip_denied_in_node_head);
  5. free_ip_list(&ip_allowed_out_node_head);
  6. free_ip_list(&ip_denied_out_node_head);
  7. free_port_list(&port_allowed_in_node_head);
  8. free_port_list(&port_denied_in_node_head);
  9. free_port_list(&port_allowed_out_node_head);
  10. free_port_list(&port_denied_out_node_head);
  11. nf_unregister_hook(&my_netfilter[0]);
  12. nf_unregister_hook(&my_netfilter[1]);
  13. printk("CLEAN up my firewall OK!\n");
  14. }

[cpp] view plain copy

  1. MODULE_LICENSE("Dual BSD/GPL");
  2. MODULE_AUTHOR("[email protected]");

该防火墙支持命令参数设置,根据参数设置防火墙的工作模式,只需定义和声明

[cpp] view plain copy

  1. static int work_mode = 0;//default mode
  2. module_param(work_mode,int,S_IRUGO);

目前测试,防火墙正常工作。

可以看到数据包能到达网络层,但由于防火墙启用的相应检查规则,浏览器等应用层软件无法联网,数据包被丢弃。

时间: 2024-10-21 12:15:09

Linux内核--基于Netfilter的内核级包过滤防火墙实现的相关文章

Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 【转】

原文地址:Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinaunix.net/uid-25909619-id-4938390.html 在构架相关的汇编代码运行完之后,程序跳入了构架无关的内核C语言代码:init/main.c中的start_kernel函数,在这个函数中Linux内核开始真正进入初始化阶段, 下面我就顺这代码逐个函数的解释,但是这里并不会过于深入

编译内核让netfilter支持过滤layer7应用层协议

netfilter/layer7 默认情况下,netfilter只能过滤二.三.四层的数据,但是对于应用层的数据(比如qq,迅雷视频等等)是无法过滤掉的.我们又知道netfilter是工作在内核当中的,因此要让netfilter支持过滤layer7应用层协议的数据必须要重新编译内核.由于iptables是规则编辑工具,因此也要重新编译iptables让其能够支持对layer7应用层协议的编写. 整体步骤如下: 一.需要使用的软件 内核源码:linux-2.6.28.10.tar.gz iptab

Linux与其它类Unix内核的比较

单块结构的内核:由几个逻辑上独立的成分构成,单块结构,大多数据商用Unix变体也是单块结构: 编译并静态连接的传统Unix内核:Linux能自动按需动态地装载和卸载部分内核代码(模块),而传统Unix内核仅支持静态连接: 内核线程:Linux以一种十分有限的方式使用内核线程来周期性地执行几个内核函数,而一些Unix内核则本身被组织成一组内核线程: 多线程应用程序支持:Linux定义了自己的轻量级进程版本,并以此来实现对多线程应用程序的支持,而商用Unix则都是基于内核线程来作为多线程应用程序的执

Linux内核@系统组成与内核配置编译

Linux系统由什么组成? 由用户空间(应用程序+GNU C标准库)和内核空间(系统调用接口+内核+内核架构代码)组成. Linux内核到底是什么?以及组成. ARM的七种操作级别? 内核网络协议栈(Network Stack)的作用? 为Linux提供了丰富的网络协议(TCP/IP.PPPOE)实现.将网络协议栈放在内核中为了提高网络性能,减少CPU开销. 虚拟文件系统的作用? 为了支持多种文件系统,并为它们提供统一的操作接口. Linux内核源代码结构 关于每个文件夹中的具体内容分析:参考h

linux、内核源码、内核编译与配置、内核模块开发、内核启动流程(转)

linux是如何组成的?答:linux是由用户空间和内核空间组成的为什么要划分用户空间和内核空间?答:有关CPU体系结构,各处理器可以有多种模式,而LInux这样的划分是考虑到系统的安全性,比如X86可以有4种模式RING0~RING3  RING0特权模式给LINUX内核空间RING3给用户空间linux内核是如何组成的?答:linux内核由SCI(System Call Interface)系统调用接口.PM(Process Management)进程管理.MM(Memory Managem

linux自学心得之--安装内核头文件

对于linux初学者来说有很多的问题需要去探索,不能完全按照书本上的章节顺序学习,有些知识和问题就像是安装软件一样有依赖关系.刚安装linux系统需要安装驱动,安装驱动就要提前安装内核头文件,不然会报各种错误,比如找不到目录,xxx不存在.安装内核头文件的时候可能又会遇到"未发现软件包......"     废话少说,下面就讲一下如何安装内核头文件,本文以kali linux为例,kali linux是基于Debian的Linux发行版,本文章适用于其他基于Debian的linux. 

Linux内核源码分析--内核启动之(1)zImage自解压过程(Linux-3.0 ARMv7) 【转】

转自:http://blog.chinaunix.net/uid-25909619-id-4938388.html 研究内核源码和内核运行原理的时候,很总要的一点是要了解内核的初始情况,也就是要了解内核启动过程.我在研究内核的内存管理的时候,想知道内核启动后的页表的放置,页表的初始化等信息,这促使我这次仔细地研究内核的启动代码. CPU在bootloader的帮助下将内核载入到了内存中,并开始执行.当然,bootloader必须为zImage做好必要的准备:  1. CPU 寄存器的设置: R0

linux系统用户态和内核态及其通信

究竟什么是用户态,什么是内核态,这两个基本概念以前一直理解得不是很清楚,根本原因个人觉得是在于因为大部分时候我们在写程序时关注的重点和着眼的角度放在了实现的功能和代码的逻辑性上,先看一个例子: 1)例子 C代码 1.     void testfork(){ 2.     if(0 = = fork()){ 3.     printf("create new process success!\n"); 4.     } 5.     printf("testfork ok\n

Linux进程管理 (篇外)内核线程简要介绍

关键词:kthread.irq.ksoftirqd.kworker.workqueues 在使用ps查看线程的时候,会有不少[...]名称的线程,这些有别于其它线程,都是内核线程. 其中多数内核线程从名称看,就知道其主要功能. 比如给中断线程化使用的irq内核线程,软中断使用的内核线程ksoftirqd,以及work使用的kworker内核线程. 本文首先概览一下Linux都有哪些内核线程,然后分析创建内核线程的API. 在介绍内核线程和普通线程都有哪些区别? 最后介绍主要内核线程(irq/ks