以linux內(nèi)核啟動地址破解30008000由來之謎
出處:互聯(lián)網(wǎng) 發(fā)布于:2011-09-02 22:54:47
關(guān)于Linux
Linux是一類Unix計算機操作系統(tǒng)的統(tǒng)稱。Linux操作系統(tǒng)的內(nèi)核的名字也是“Linux”。Linux操作系統(tǒng)也是自由軟件和開放源代碼發(fā)展中著名的例子。嚴(yán)格來講,Linux這個詞本身只表示Linux內(nèi)核,但在實際上人們已經(jīng)習(xí)慣了用Linux來形容整個基于Linux內(nèi)核,并且使用GNU 工程各種工具和數(shù)據(jù)庫的操作系統(tǒng)。Linux得名于計算機業(yè)余愛好者Linus Torvalds。
內(nèi)核概念解說
在Linux的術(shù)語中被稱為“內(nèi)核”,也可以稱為“”。Linux內(nèi)核的主要模塊(或組件)分以下幾個部分:存儲管理、CPU和進(jìn)程管理、文件系統(tǒng)、設(shè)備管理和驅(qū)動、網(wǎng)絡(luò)通信,以及系統(tǒng)的初始化(引導(dǎo))、系統(tǒng)調(diào)用等。Linux 內(nèi)核實現(xiàn)了很多重要的體系結(jié)構(gòu)屬性。在或高或低的層次上,內(nèi)核被劃分為多個子系統(tǒng)。Linux 也可以看作是一個整體,因為它會將所有這些基本服務(wù)都集成到內(nèi)核中。這與微內(nèi)核的體系結(jié)構(gòu)不同,后者會提供一些基本的服務(wù),例如通信、I/O、內(nèi)存和進(jìn)程管理,更具體的服務(wù)都是插入到微內(nèi)核層中的。
內(nèi)核啟動地址的分析過程:
內(nèi)核編譯鏈接過程是依靠vmlinux.lds文件,以arm為例vmlinux.lds文件位于kernel/arch/arm/vmlinux.lds,
vmlinux-armv.lds的生成過程在kernel/arch/arm/Makefile中
ifeq ($(CONFIG_CPU_32),y)
PROCESSOR = armv
TEXTADDR = 0xC0008000
LDSCRIPT = arch/arm/vmlinux-armv.lds.in
endif
arch/arm/vmlinux.lds: $(LDSCRIPT) dummy
@sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@
查看arch/arm/vmlinux.lds 中
OUTPUT_ARCH(arm)
ENTRY(stext)
SECTIONS
{
. = 0xC0008000;
.init : { /* Init code and data */
_stext = .;
__init_begin = .;
*(。text.init)
__proc_info_begin = .;
*(。proc.info)
__proc_info_end = .;
__arch_info_begin = .;
*(。arch.info)
__arch_info_end = .;
__tagtable_begin = .;
*(。taglist)
__tagtable_end = .;
*(。data.init)
. = ALIGN(16);
__setup_start = .;
*(。setup.init)
__setup_end = .;
__initcall_start = .;
*(。initcall.init)
__initcall_end = .;
. = ALIGN(4096);
__init_end = .;
}
/DISCARD/ : { /* Exit code and data */
*(。text.exit)
*(。data.exit)
*(。exitcall.exit)
}
.text : { /* Real text segment */
_text = .; /* Text and read-only data */
*(。text)
*(。fixup)
*(。gnu.warning)
*(。rodata)
*(。rodata.*)
*(。glue_7)
*(。glue_7t)
*(。got) /* Global offset table */
_etext = .; /* End of text section */
}
.kstrtab : { *(。kstrtab) }
. = ALIGN(16);
__ex_table : { /* Exception table */
__start___ex_table = .;
*(__ex_table)
__stop___ex_table = .;
}
__ksymtab : { /* Kernel symbol table */
__start___ksymtab = .;
*(__ksymtab)
__stop___ksymtab = .;
}
. = ALIGN(8192);
.data : {
/*
* fIRst, the init task union, aligned
* to an 8192 byte boundary.
*/
*(。init.task)
/*
* then the cacheline aligned data
*/
. = ALIGN(32);
*(。data.cacheline_aligned)
/*
* and the usual data section
*/
*(。data)
CONSTRUCTORS
_edata = .;
}
.bss : {
__bss_start = .; /* BSS */
*(。bss)
*(COMMON)
_end = . ;
}
/* 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) }
}
arch/arm/Makefile中:
vmlinux: arch/arm/vmlinux.lds
arch/arm/vmlinux.lds: $(LDSCRIPT) dummy
@sed 's/TEXTADDR/$(TEXTADDR)/;s/DATAADDR/$(DATAADDR)/' $(LDSCRIPT) >$@
MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
bzImage zImage zinstall Image bootpImage install: vmlinux
@$(MAKEBOOT) $@
但在kernel/arch/arm/boot/Makefile
ifeq ($(CONFIG_ARCH_S3C2410),y)
ZTEXTADDR = 0x30008000
ZRELADDR = 0x30008000
endif
zImage: $(CONFIGURE) compressed/vmlinux
$(OBJCOPY) -O binary -R .note -R .comment -S compressed/vmlinux $@
compressed/vmlinux: $(TOPDIR)/vmlinux dep
@$(MAKE) -C compressed vmlinux
在compressed目錄下的Makefile中
ZLDFLAGS = -p -X -T vmlinux.lds
SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
all: vmlinux
vmlinux: $(HEAD) $(OBJS) piggy.o vmlinux.lds
$(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o $(LIBGCC) -o vmlinux
vmlinux.lds: vmlinux.lds.in Makefile $(TOPDIR)/arch/$(ARCH)/boot/Makefile $(TOPDIR)/.config
@sed "$(SEDFLAGS)" < vmlinux.lds.in > $@
vmlinux-armv.lds.in文件的內(nèi)容:
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = LOAD_ADDR;
_load_addr = .;
. = TEXT_START;
_text = .;
.text : {
_start = .;
*(。start)
*(。text)
*(。fixup)
*(。gnu.warning)
*(。rodata)
*(。rodata.*)
*(。glue_7)
*(。glue_7t)
input_data = .;
piggy.o
input_data_end = .;
. = ALIGN(4);
}
_etext = .;
_got_start = .;
.got : { *(。got) }
_got_end = .;
.got.plt : { *(。got.plt) }
.data : { *(。data) }
_edata = .;
. = BSS_START;
__bss_start = .;
.bss : { *(。bss) }
_end = .;
.stack (NOLOAD) : { *(。stack) }
.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) }
}
vmlinux.lds內(nèi)容為
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x30008000;
_load_addr = .;
. = 0;
_text = .;
.text : {
_start = .;
*(。start)
*(。text)
*(。fixup)
*(。gnu.warning)
*(。rodata)
*(。rodata.*)
*(。glue_7)
*(。glue_7t)
input_data = .;
piggy.o
input_data_end = .;
. = ALIGN(4);
}
_etext = .;
_got_start = .;
.got : { *(。got) }
_got_end = .;
.got.plt : { *(。got.plt) }
.data : { *(。data) }
_edata = .;
. = ALIGN(4);
__bss_start = .;
.bss : { *(。bss) }
_end = .;
.stack (NOLOAD) : { *(。stack) }
.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) }
}
一般情況下都在生成vmlinux后,再對內(nèi)核進(jìn)行壓縮成為zImage,壓縮的目錄是kernel/arch/arm/boot。
到flash中的是壓縮后的zImage文件,zImage是由壓縮后的vmlinux和解壓縮程序組成,如下圖所示:
|-----------------|\ |-----------------|
| | \ | |
| | \ | decompress code |
| vmlinux | \ |-----------------| zImage
| | \| |
| | | |
| | | |
| | | |
| | /|-----------------|
| | /
| | /
| | /
|-----------------|/
zImage鏈接腳本也叫做vmlinux.lds,位于kernel/arch/arm/boot/compressed。
是由同一目錄下的vmlinux.lds.in文件生成的
在kernel/arch/arm/boot/Makefile文件中定義了:
ifeq ($(CONFIG_ARCH_S3C2410),y)
ZTEXTADDR = 0x30008000
ZRELADDR = 0x30008000
endif
ZTEXTADDR就是解壓縮代碼的ram偏移地址,ZRELADDR是內(nèi)核ram啟動的偏移地址,這里看到指定ZTEXTADDR的地址為30008000,
總結(jié)內(nèi)核啟動地址的設(shè)置:
設(shè)置kernel/arch/arm/boot/Makefile文件中的
ifeq ($(CONFIG_ARCH_S3C2410),y)
ZTEXTADDR = 0x30008000
ZRELADDR = 0x30008000
endif
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
#
查看2410的datasheet ,發(fā)現(xiàn)內(nèi)存映射的基址是0x3000 0000 ,那么 0x30008000又是如何來的呢?
在內(nèi)核文檔kernel/Document/arm/Booting 文件中有:
Calling the kernel image
Existing boot loaders: MANDATORY
New boot loaders: MANDATORY
There are two options for calling the kernel zImage. If the zImage is stored in flash, and is linked correctly to be run from flash, then it is legal for the boot loader to call the zImage in flash directly.
The zImage may also be placed in system RAM (at any location) and called there. Note that the kernel uses 16K of RAM below the image to store page tables. The recommended placement is 32KiB into RAM.
看來在image下面用了32K(0x8000)的空間存放內(nèi)核頁表,
0x30008000就是2410的內(nèi)核在RAM中的啟動地址,這個地址就是這么來的。
版權(quán)與免責(zé)聲明
凡本網(wǎng)注明“出處:維庫電子市場網(wǎng)”的所有作品,版權(quán)均屬于維庫電子市場網(wǎng),轉(zhuǎn)載請必須注明維庫電子市場網(wǎng),http://m.58mhw.cn,違反者本網(wǎng)將追究相關(guān)法律責(zé)任。
本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點或證實其內(nèi)容的真實性,不承擔(dān)此類作品侵權(quán)行為的直接責(zé)任及連帶責(zé)任。其他媒體、網(wǎng)站或個人從本網(wǎng)轉(zhuǎn)載時,必須保留本網(wǎng)注明的作品出處,并自負(fù)版權(quán)等法律責(zé)任。
如涉及作品內(nèi)容、版權(quán)等問題,請在作品發(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。
- ARM技術(shù)架構(gòu)與應(yīng)用開發(fā)實踐指南2026/1/6 10:40:19
- 嵌入式實時操作系統(tǒng)(RTOS)選型與移植技術(shù)指南2025/12/31 10:42:31
- 工業(yè)嵌入式系統(tǒng):通信接口技術(shù)選型與抗干擾設(shè)計實踐2025/12/15 14:36:53
- 深入解析嵌入式 OPENAMP 框架:開啟異核通信新時代2025/7/22 16:27:29
- 一文快速了解OPENWRT基礎(chǔ)知識2025/7/14 16:59:04









