在我們進入最佳男主角(爛豬腳)ㄉ主題之前,我希望先把makefile及三ㄍlds檔 memtest.bin.lds、memtest.lds、memtest_shared.lds稍加探討探討。若你還不知道什麼是makefile那先去溫習功課再來看這裡。makefile的寫法你去比較一下1.70版,稍有不同,但達成ㄉ效果是一樣的。一般我們很少會去寫lds檔,因為寫apㄉ人搞不好根本就不知道這是什麼東東,lds檔是給linux下gcc附的linker連結器LD所參考用的,若你不指定lds檔,LD還是會叫用預設lds檔,故名思義就是連結器專用的script(描述檔),畢竟memtest86+不是OS下ㄉapplication它等於是ㄍ小型的OS,因為從Boot到run實際應用都是要去和實際硬體溝通,因此lds檔當然要符合它自己ㄉ需求。先截取部分makefile內容:
memtest.bin: memtest_shared.bin bootsect.o setup.o memtest.bin.lds
$(LD) -T memtest.bin.lds bootsect.o setup.o -b binary \
memtest_shared.bin -o memtest.bin
以上敘述: bootsect.o setup.o連結時要參考memtest.bin.lds
以下是memtest.bin.ldsㄉ內容:
OUTPUT_FORMAT("binary")
OUTPUT_ARCH("i386")
ENTRY(_main);
SECTIONS {
. = 0;
.bootsect : { *(.bootsect) }
.setup : { *(.setup) }
.memtest : {
_start = . ;
*(.data)
_end = . ;
}
_syssize = (_end - _start + 15) >> 4;
}
若沒有全部看懂,先懂一半也行。
其他的makefile內容依此類推,應該難不倒大家。
爛豬腳:head.S
.code32
.globl startup_32
startup_32:
cld
cli
‧‧‧
看到沒,它是32位元的code,而且它沒有.section ㄉ宣告,因為它和Cㄉ部分是整合為同一區段,如下所示:
下面ㄉOBJS除了head.o是組合語言寫ㄉ,其餘都是C寫ㄉ,但這本來就無關緊要,重要ㄉ是這些物件檔被連結成memtest_shared(依照memtest_shared.ldsㄉ敘述)
OBJS= head.o reloc.o main.o test.o init.o lib.o patn.o screen_buffer.o \
config.o linuxbios.o memsize.o pci.o controller.o random.o extra.o \
spd.o error.o dmi.o
memtest_shared: $(OBJS) memtest_shared.lds Makefile
$(LD) --warn-constructors --warn-common -static -T memtest_shared.lds \
-o $@ $(OBJS) && \
$(LD) -shared -Bsymbolic -T memtest_shared.lds -o $@ $(OBJS)
我們還是看一下memtest_shared.lds:ㄌㄌ等(台語)
OUTPUT_FORMAT("elf32-i386");
OUTPUT_ARCH(i386);
ENTRY(startup_32);
SECTIONS {
. = 0;
.text : {
_start = .;
*(.text)
*(.text.*)
*(.plt)
_etext = . ;
} = 0x9090
.rodata : {
*(.rodata)
*(.rodata.*)
}
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.hash : { *(.hash) }
.dynamic : { *(.dynamic) }
.rel.text : { *(.rel.text .rel.text.*) }
.rel.rodata : { *(.rel.rodata .rel.rodata.*) }
.rel.data : { *(.rel.data .rel.data.*) }
.rel.got : { *(.rel.got .rel.got.*) }
.rel.plt : { *(.rel.plt .rel.plt.*) }
. = ALIGN(4);
.data : {
_data = .;
*(.data)
*(.data.*)
}
.got : {
*(.got.plt)
*(.got)
_edata = . ;
}
. = ALIGN(4);
.bss : {
_bss = .;
*(.dynbss)
*(.bss)
*(.bss.*)
*(COMMON)
/* _end must be at least 256 byte aligned */
. = ALIGN(256);
_end = .;
}
/DISCARD/ : { *(*) }
}
若是看ㄌ一頭霧水,至少你也看到startup_32,它就是head.Sㄉ頭,至於_start和 _end 請看:
memtest: memtest_shared.bin memtest.lds
$(LD) -s -T memtest.lds -b binary memtest_shared.bin -o $@
以下是 memtest.lds內容 0x10000=64k
OUTPUT_FORMAT("elf32-i386");
OUTPUT_ARCH(i386);
ENTRY(_start);
SECTIONS {
. = 0x10000;
_start = . ;
.data : {
*(.data)
}
}
所以startup_32=_start,you know!
沒有留言:
張貼留言