自制bootloader之程序的編譯和鏈接
文本程序有4個:boot.s head.s main.c(led.c) image.s
boot.s:這個bootloader中真正屬于boot的程序,完成板子硬件初始化并將內(nèi)核程序(萬能的LED流水燈)搬至SDRAM。
head.s:內(nèi)核程序的前部,包括內(nèi)核異常向量表和內(nèi)核程序入口。
main.c:內(nèi)核主程序,只是一個簡單的LED流水燈~~~
inamge.s:整個bootloader的映像文件。包含boot.bin和kernel.bin,主要是將兩個bin文件重定向,確保兩個文件在正確的地址上。
Makefile文件如下:挺簡單的~~先貼出來:
CC = arm-elf-gcc AS = arm-elf-as LD = arm-elf-ld OBJCOPY = arm-elf-objcopy ADDRESS = 0x0c000000 .PHONY : all clean all : image.bin clean : rm -f *.bin rm -f *.elf rm -f *.o image.bin : image.asm boot.bin kernel.bin nasm -f bin -o $@ $ kernel.bin : kernel.elf $(OBJCOPY) -O binary -R .comment -R .note -S $ $@ chmod a-x $@ kernel.elf : head.o main.o $(LD) -Ttext $(ADDRESS) -nostdinc -o $@ $^ chmod a-x $@ main.o : main.c $(CC) -Wall -O2 -c -o $@ $ head.o : head.s $(AS) -o $@ $ boot.bin : boot.elf $(OBJCOPY) -O binary -R .comment -R .note -S $ $@ chmod a-x $@ boot.elf : boot.o $(LD) -Ttext 0 -nostdinc -o $@ $ chmod a-x $@ boot.o : boot.s $(AS) -o $@ $ 要注意的大概只有:image.bin : image.asm boot.bin kernel.bin nasm -f bin -o $@ $
用的是nasm程序,本人用的redhat9.0,當(dāng)然要另外安裝nasm 簡單看了一下中文手冊,還是能理解的
再帖一下image.s,有助于理解整個bootloader的安排:
image.s:
incbin "boot.bin"
times 0x100 - ($ - $$) db 0
incbin "kernel.bin"
因?yàn)閎oot.bin文件大小為232字節(jié)(不足0x100),kernel.bin文件起始地址安排的是放在0x00000100的,所以中間還空了一些空間,所以選用nasm程序?qū)蓚€bin文件拼接成一個image.bin,當(dāng)然中間空的得用0來填充。
這里還要補(bǔ)充的是:為什么要用nasm再編寫一個image.s文件。一般用過51單片機(jī)的,如at89s51的話,會認(rèn)為完全可以像燒寫51程序那樣,分別把boot.bin和kernel.bin文件燒寫到指定的地址(j-flash提供此功能)而不需要把兩個.bin文件事先拼接成一個文件。開始我也是這么想的,后來發(fā)現(xiàn)不行。因?yàn)閎oot.bin和kernel.bin兩個文件是在flash的一個扇區(qū)內(nèi),而sst39vf160芯片的編程是以扇區(qū)(統(tǒng)一規(guī)格為2K)為單位的。即使是在一個扇區(qū)內(nèi)只需修改一個字節(jié)的數(shù)據(jù),那么都需要對整個扇區(qū)做修改。所以,當(dāng)先把boot.bin燒寫到0地址后,再想把kernel.bin燒寫到0x100(2K)地址處時,會把boot.bin給覆蓋掉。所以只能把兩個文件拼接成一個文件一次性燒寫到0地址。
至些,在程序目錄中運(yùn)行make就行了,能得到一個image.bin文件是需要的,將其燒錄到板子的flash里,起始地址當(dāng)然是0。
斷電重啟板子,哈哈~~~ 燈還是跑起來了,~~~還是要強(qiáng)化一下理解,下一個目標(biāo)是要能用串口打印點(diǎn)什么吧~~
評論