Username:
Password:
Remember Me?
Linux内核链接器学习
< 上一篇
|
下一篇 >
来源: ChinaUnix博客 作者: 发布时间:2008-04-25 02:50:48
通过对Linux内核的不断学习, 越来越发现其复杂性,需要研发人员掌控N多知识,操作系统的知识我想是最基本的了,其次包括汇编,C语言,Make file,bash script等等知识,最近又发现了,在编译连接Linux内核的时候,还涉及到了连接器(LD)的一些知识。
通常在编译C文档的时候,编译器会把文档转换成汇编语言,默认目标文档是包含text,data,bss三个段,然后链接器会把任何的目标程式连接成一个文档,链接过程包括多个文档不同段的整合,也就是不同文档的text段整合在一个text段里面,不同文档的data段整合在一个data段里面....
在Linux内核编译连接后,会生成很多段(不止上面默认的三个)。那个怎样定义新段呢?
[init.h]
#define __init __attribute__ ((__section__ (".text.init")))
[8139cp.c]
static int __init cp_init (void)
上面的cp_init的代码就被放置在一个新段".text.init"中,__attribute__ ((__section__ (".text.init")))就是通知编译器在编译时,把此函数体代码放在".text.init"中。其实Linux module方式加载驱动的init代码也都位于此段,把初始化代码都放在此段的原因主要是节约内存,当初始化这些模块后,这个".text.init"区域会被内核收回,linux内核程式员的确都珍惜内存。
假如单单只在内核代码中做上面的事情,还是不够的,上面只是解决了文档编译分块的问题,真正链接的问题还没有解决,那么怎样把任何目标文档同样的段集合在一起呢?段位置怎样确定呢?这就是链接器的事情了!
[Linux内核的Makefile]
vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \ --start-group \ $(CORE_FILES) \ $(DRIVERS) \ $(NETWORKS) \ $(LIBS) \ --end-group \ -o vmlinux
LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
vmlinux.lds
/* ld script to make i386 Linux kernel
* Written by Martin Mares ;
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0xC0000000 + 0x100000;
_text = .; /* Text and read-only data */
.text : {
*(.text)
*(.fixup)
*(.gnu.warning)
} = 0x9090
_etext = .; /* End of text section */
.rodata : { *(.rodata) *(.rodata.*) }
.kstrtab : { *(.kstrtab) }
. = ALIGN(16); /* Exception table */
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
__start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
.data : { /* Data */
*(.data)
CONSTRUCTORS
}
_edata = .; /* End of data section */
. = ALIGN(8192); /* init_task */
.data.init_task : { *(.data.init_task) }
. = ALIGN(4096); /* Init code and data */
__init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(16);
__setup_start = .;
.setup.init : { *(.setup.init) }
__setup_end = .;
__initcall_start = .;
.initcall.init : { *(.initcall.init) }
__initcall_end = .;
. = ALIGN(4096);
__init_end = .;
. = ALIGN(4096);
.data.page_aligned : { *(.data.idt) }
. = ALIGN(32);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
__bss_start = .; /* BSS */
.bss : {
*(.bss)
}
_end = . ;
/* Sections to be discarded */
/DISCARD/ : {
*(.text.exit)
*(.data.exit)
*(.exitcall.exit)
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
}
上面是Linux ld(链接器)所使用的脚本,也就是在链接linux内核时所参照的文档,ENTRY界定了程式的入口点,这里面时__start,也就是bootsect.S中的其实地址,执行copy内核到指定内存功能,然后用SECTION定义了生成内核文档的分块结构,__setup_start = .;这句话很有意思,在linux内核里面定义了__setup_start这个变量,但就是没有赋值过,嘿嘿,其实赋值在这里呢,"."代表输出文档(内核image)当前链接位置,之前我还疑惑,linux为何有时候定一变量,却没看到初始化,果不其然,原来在这里。通过链接文档的配合,一个符合研发者所规划的linux内核image就产生了。
喜欢本文,那就收藏到:
上一篇:
uname命令
下一篇:
Red Hat Enterprise Liunx 根文件系统
相关评论
我也要评论
还没有关于此文章的相关评论!
首页
上一页
下一页
尾页
昵称:
(为空则显示guest)
评论分数:
★
★ ★
★★★
★★★★
★★★★★
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
相关推荐
xml轻松学习手册(3)xml的术语_xml教程
xml轻松学习手册(4)xml语法_xml教程
xml轻松学习手册(5)xml实例解析_xml教程
了解web页面工具语言xml(一)产生背景_xml教程
了解web页面工具语言xml(二)定义_xml教程
了解web页面工具语言xml(三)支持工具_xml教程
了解web页面工具语言xml(四)应用分类_xml教程
了解web页面工具语言xml(五)好处_xml教程
了解web页面工具语言xml(六)展望_xml教程
xml技术上传文档_xml技巧
相关资讯
perl实例分析教程之十
perl实例分析教程之九
perl实例分析教程之八
perl实例分析教程之七
perl实例分析教程之六
perl实例分析教程之五
perl实例分析教程之四
perl实例分析教程之三
perl实例分析教程之二
perl实例分析教程之一
点击发布文章
导航
主页
设为首页
加入收藏
联系我们
赞助商
文章类别
行业资讯
域名资讯
虚拟主机
托管租用
VPS
CDN
网站运营
技术资讯
Mac OS
网络设备
路由技术
网络技术
HTML/DHTML
源码天堂
网络编程
Java
Perl
C/C++
Shell
数据库其他
DB2
Sybase
存储备份
硬件技术
网站建设
通信技术
虚拟化技术
安全其他
安全工具
加密和破解
数据库安全
程序安全
网络安全
系统安全
防火墙
VPN
网管技术其他
Informix
Oracle
PostgreSQL
Dreamweaver教程
windows操作系统
XML编程
NET编程
JSP编程
PHP编程
ASP编程
Mssql
Mysql
Access
Coreldraw
flash
web服务器
ftp服务器
mail服务器
邮件系统
IBM-AIX
HP-UX
Sco
Solaris
FreeBSD
Linux
Proxy
CSS教程
Javascript教程
Ajax
dns服务器
Photoshop教程
站长资讯
冲浪宝典
订阅
Rss Feed
主机赞助商连接:
华夏名网虚拟主机域名注册
关于我们 | 网站声明 | 联系我们 | 广告服务 IDC中文资讯站-客观公证的IDC产业权威媒体
Copyright
@
2007-2008 IDCNEWS.NET, All Rights Reserved
蜀ICP备07504800号