深入理解Linux网络技术内幕——内核基础架构和组件初始化
引导期间的内核选项
注册关键字:
__setup(string, fn)
#ifndef MODULE
#define early_param(str, fn) \
__setup_param(str, fn, fn, 0)
#else /* MODULE */
#define early_param(str, fn)
#endif
//net/core/dev.c
_setup("netdev=", netdev_boot_setup);
//net/ethernet/eth.c
__setup("ether=", netdev_boot_setup);
#define __setup(str, fn) \
__setup_param(str, fn, fn, 0) #define early_param(str, fn) \
__setup_param(str, fn, fn, 1) #define __setup_param(str, unique_id, fn, early) \
static char __setup_str_##unique_id[] __initdata __aligned(1) = str; \
static struct obs_kernel_param __setup_##unique_id \
__used __section(.init.setup) \
__attribute__((aligned((sizeof(long))))) \
= { __setup_str_##unique_id, fn, early }
early_param和__setup唯一不同的就是传递给__setup_param的最后一个参数early。_setup_param定义了一个struct obs_kernel_param类型的结构,然后通过_section宏,使这个变量在链接的时候能够放置在段.init.setup。下文有.init.setup的介绍。
struct obs_kernel_param结构如下:
struct obs_kernel_param {
const char *str;
int (*setup_func)(char *);
int early;
};
两遍分析:
parse_args("early options", tmp_cmdline, NULL, 0, do_early_param);
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
&unknown_bootoption);

.init.setup 内存区
struct obs_kernel_param {
const char *str;
int (*setup_func)(char *);
int early;
};
模块初始化代码:
module_init(XXX);
module_exit(XXX);
static char version[] _ _devinitdata = DRV_NAME " ... ";
static struct vortex_chip_info {
...
} vortex_info_tbl[] _ _devinitdata = {
{"3c590 Vortex 10Mbps",
... ... ...
}
static int _ _init vortex_init (void)
{
...
}
static void _ _exit vortex_cleanup (void)
{
...
}
module_init(vortex_init);
module_exit(vortex_cleanup);
基于宏标签的优化:

深入理解Linux网络技术内幕——内核基础架构和组件初始化的更多相关文章
- 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口
Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...
- 深入理解linux网络技术内幕读书笔记(七)--组件初始化的内核基础架构
Table of Contents 1 引导期间的内核选项 2 注册关键字 3 模块初始化代码 引导期间的内核选项 linux运行用户把内核配置选项传给引导记录,然后引导记录再把选项传给内核. 在引导 ...
- 深入理解linux网络技术内幕读书笔记(十)--帧的接收
Table of Contents 1 概述 1.1 帧接收的中断处理 2 设备的开启与关闭 3 队列 4 通知内核帧已接收:NAPI和netif_rx 4.1 NAPI简介 4.1.1 NAPI优点 ...
- 深入理解linux网络技术内幕读书笔记(二)--关键数据结构
Table of Contents 1 套接字缓冲区: sk_buff结构 1.1 网络选项及内核结构 1.2 结构说明及操作函数 2 net_device结构 2.1 MTU 2.2 结构说明及操作 ...
- 深入理解linux网络技术内幕读书笔记(五)--网络设备初始化
Table of Contents 1 简介 2 系统初始化概论 2.1 引导期间选项 2.2 中断和定时器 2.3 初始化函数 3 设备注册和初始化 3.1 硬件初始化 3.2 软件初始化 3.3 ...
- 深入理解Linux网络技术内幕——设备的注册与初始化(二)
设备注册于设备除名 设备注册与设备除名一般有 register_netdev和unregister_netdev完成.这两个是包裹函数,负责上锁,真正起作用的是其调用的register_net ...
- 深入理解Linux网络技术内幕——用户空间与内核空间交互
概述: 内核空间与用户空间经常需要进行交互.举个例子:当用户空间使用一些配置命令如ifconfig或route时,内核处理程序就要响应这些处理请求. 用户空间与内核有多种交互方式,最常 ...
- 深入理解Linux网络技术内幕——Notification内核通知表链
为什么要有内核通知表链: Linux由多个相互依赖的子系统组成.其中一些子系统可能需要对其他子系统的一些事件感兴趣.这样子系统之间需要一些通信机制来实现这一功能. 在接触Notific ...
- 深入理解Linux网络技术内幕——中断与网络驱动程序
接收到帧时通知驱动程序 在网络环境中.设备(网卡)接收到一个数据帧时,须要通知驱动程序进行处理. 有一下几种通知机制: 轮询: 内核不断检查设备是否有话要说.(比較耗资源,但在一些情况 ...
随机推荐
- BZOJ2982: combination Lucas
Description LMZ有n个不同的基友,他每天晚上要选m个进行[河蟹],而且要求每天晚上的选择都不一样.那么LMZ能够持续多少个这样的夜晚呢?当然,LMZ的一年有10007天,所以他想知道答案 ...
- C#学习笔记(二):变量、数据类型和运算符
变量.数据类型 给变量赋值,如果想指定float,在数字后面加上F/f:如果想指定decimal,在数字后面加上m. 0-9:48-57 A-Z:65-90 a-z:97-122 ...
- CRLF line terminators导致shell脚本报错:command not found --转载
Linux和Windows文本文件的行结束标志不同.在Linux中,文本文件用"/n"表示回车换行,而Windows用"/r/n"表示回车换行.有时候在Wind ...
- axios post请求报错
问题描述: vue中使用axios提交post请求, 请求地址及参数都对, 但是一直报缺少参数的错误 探索:对比post请求数据, 提交数据的方式不对 (1)axios的post请求(返回响应缺少参数 ...
- Django本地开发,debug模式引用静态文件
debug为true ,不用设置static_root debug 为false ,设置static_root STATIC_ROOT = ( os.path.join(BASE_DIR, 'stat ...
- java 基本数据类型及自动类型提升
1.Java的8种基本数据类型及其所占空间大小: boolean 8bit/1byte byte 8bit/1byte char 16bit/2byte ...
- 算法笔记--数位dp
算法笔记 这个博客写的不错:http://blog.csdn.net/wust_zzwh/article/details/52100392 数位dp的精髓是不同情况下sta变量的设置. 模板: ]; ...
- 使用SFTP工具相关问题
1.使用SFTP工具,填写ip,端口都正确但是连接不上? 答:请统一使用 filezilla工具进行连接,环境搭建使用该工具进行测试和使用. 2.使用SFTP工具访 ...
- js如何创建JSON对象
js如何创建JSON对象 一.总结 一句话总结:直接创建js数组和js对象即可,然后JSON.stringify就可以获取json字符串,js中的一切都是对象,而且js中的对象都是json对象 js ...
- LeetCode--202--快乐数
问题描述: 编写一个算法来判断一个数是不是“快乐数”. 一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变 ...