小赫曼不吃东西:uC5272 Makefile解析(转)

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 18:23:30
uc572 Makefile解析2011-03-21 10:30

以下为个人的学习理解,有错之处,还望指正,谢谢!(mac_zhong)

#
# Makefile -- Build instructions for Arcturus/uC5272
#
COMMON="$(ROOTDIR)/vendors/Arcturus/uC5272/"
DIRS =
ROMFSIMG = $(IMAGEDIR)/romfs.img /*romfs文件系统的image文件名*/
IMAGE = $(IMAGEDIR)/image.bin /*最终的image文件名*/
/*以下是romfs文件系统下需要的目录:
bin 可执行程序,要
dev 设备文件,要
etc 配置文件,要
home 用户目录,在这我们有/home/httpd,这是个web管理用户,要
lib 共享库(shared library)和模块(modules),uclinux在这我们没有
mnt floppy, CD-ROM,在这没有
Proc 内核工作信息文件,必须可写,要
usr 自己安装的第三方软件放在这,要
var 运行时的临时变量等,要可写,要
*/
ROMFS_DIRS = bin dev etc etc/rc.d home lib mnt proc \
usr var home/httpd home/httpd/cgi-bin
/*板子有的设备列表
tty 终端,有串口必须有
console 内核,输入输出的基本要求,用于启动init等,必须有
mem 物理内存,必须有
kmem kernel物理内存,必须有
null 垃圾站,必须有
zero,random,urandom 零(清零用),随机数 最好有
watchdog 看门狗,有则选,监控执行速度,我没选
ttys0,ttys1 串口一,二,这个得有
ptyp0(socket)和ttyp0(tty)是成对出现的,用于telnet远程登录等等,选上一对吧
ram0 ramdisk,在这我们没有,不用了
rom0 romdisk linux2.4这需要选上,linux2.6就不用了,用mtdblock吧
mtdblock 磁盘分区(经常用于将rom/flash分区),注意分区数不含mtdblock0本身,linux2.6选这个
loop 回路文件系统,可要可不要,我选了
qspi 有序列传输性能的串行外围设备接口,在这不需要
ipsec 虚拟专用网用,在这不要了
ppp dsl用,在这没有
hifn 是针对hifn设备公司的产品吧,咱们没有
usb usb设备,在这没有
*/
DEVICES = \
tty,c,5,0 console,c,5,1 cua0,c,5,64 cua1,c,5,65 \
mem,c,1,1 kmem,c,1,2 null,c,1,3 \
\
zero,c,1,5 random,c,1,8 urandom,c,1,9 watchdog,c,10,130 \
\
ptyp0,c,2,0 ptyp1,c,2,1 ptyp2,c,2,2 ptyp3,c,2,3 \
ptyp4,c,2,4 ptyp5,c,2,5 ptyp6,c,2,6 ptyp7,c,2,7 \
ptyp8,c,2,8 ptyp9,c,2,9 ptypa,c,2,10 ptypb,c,2,11 \
ptypc,c,2,12 ptypd,c,2,13 ptype,c,2,14 ptypf,c,2,15 \
\
ram0,b,1,0 ram1,b,1,1 ram2,b,1,2 ram3,b,1,3 \
\
mtdblock0,b,31,0 mtdblock1,b,31,1 mtdblock2,b,31,2 mtdblock3,b,31,3 \
mtdblock4,b,31,4 mtdblock5,b,31,5 mtdblock6,b,31,6 mtdblock7,b,31,7 \
rom0,b,31,0 rom1,b,31,1 rom2,b,31,2 rom3,b,31,3 \
rom4,b,31,4 rom5,b,31,5 rom6,b,31,6 rom7,b,31,7 \
rom8,b,31,8 rom9,b,31,9 \
\
tty0,c,4,0 tty1,c,4,1 tty2,c,4,2 tty3,c,4,3 \
ttyS0,c,4,64 ttyS1,c,4,65 \
\
ttyp0,c,3,0 ttyp1,c,3,1 ttyp2,c,3,2 ttyp3,c,3,3 \
ttyp4,c,3,4 ttyp5,c,3,5 ttyp6,c,3,6 ttyp7,c,3,7 \
ttyp8,c,3,8 ttyp9,c,3,9 ttypa,c,3,10 ttypb,c,3,11 \
ttypc,c,3,12 ttypd,c,3,13 ttype,c,3,14 ttypf,c,3,15 \
\
loop0,b,7,0 loop1,b,7,1 loop2,b,7,2 loop3,b,7,3 \
loop4,b,7,4 loop5,b,7,5 loop6,b,7,6 loop7,b,7,7 \
\
qspi0,c,126,0 qspi1,c,126,1 qspi2,c,126,2 qspi3,c,126,3 \
qspi4,c,126,4 qspi5,c,126,5 qspi6,c,126,6 qspi7,c,126,7 \
qspi8,c,126,8 qspi9,c,126,9 qspi10,c,126,10 qspi11,c,126,11 \
qspi12,c,126,12 qspi13,c,126,13 qspi14,c,126,14 qspi14,c,126,15 \
\
usb0,c,127,0 usb1,c,127,1 usb2,c,127,2 usb3,c,127,3 \
usb4,c,127,4 usb5,c,127,5 usb6,c,127,6 usb7,c,127,7 \
\
ipsec,c,36,10 \
ppp,c,108,0 pppox0,c,144,0 \
hifn0,c,28,0


all: /*如果有下级目录,进去make*/
dirs=$(DIRS) ; \
for i in $$dirs ; do make -C $$i || exit $? ; done


clean: /*make clean 要做的,清除临时文件*/
-dirs=$(DIRS) ; \/*"-"相当于“if”,判断一下,条件成立执行下面的,否则跳过*/
for i in $$dirs; do [ ! -d $$i ] || make -C $$i clean; done /*如果有下级目录,进去make clean*/
make -C $(ROOTDIR)/user/boottools/uCbootstrap-tools clean
make -C $(ROOTDIR)/user/cramfs/host_build clean


devices: device_dir /*建立(touch)设备文件,此处依赖于device_dir*/
for i in $(DEVICES); do touch $(ROMFSDIR)/dev/@$$i; done


device_dir: /*dev目录如果不存在则创建此目录*/
[ -d $(ROMFSDIR)/dev ] || mkdir -p $(ROMFSDIR)/dev


romfs: devices
/*检查romfs目录是否存在,不存在创建它,$$i在这没有用,没有值*/
[ -d $(ROMFSDIR)/$$i ] || mkdir -p $(ROMFSDIR)
for i in $(ROMFS_DIRS); do \
[ -d $(ROMFSDIR)/$$i ] || mkdir -p $(ROMFSDIR)/$$i; \ /*循环创建romfs目录下的子目录*/
done
/*如果有下级目录,进去相应子目录make romfs ,在这我们没有子目录*/
dirs=$(DIRS) ; for i in $$dirs; do make -C $$i romfs || exit $? ; done  
$(ROMFSINST) -s /var/tmp /tmp     /*创建"/var/tmp" symbol link 到 "/tmp"*/
$(ROMFSINST) -s /var/profile /etc/profile
$(ROMFSINST) -s /var/resolv.conf /etc/resolv.conf
$(ROMFSINST) -s /var/dhcpc /etc/dhcpc


/*在inetd.conf中加入ssh 的配置选项,以下两行是我自己加的*/
$(ROMFSINST) -a "ssh stream tcp nowait root /bin/discard" /etc/inetd.conf
/*在inetd.conf中加入http 的配置选项,顺便提一下同时要在inittab中启动这个服务*/
$(ROMFSINST) -a "http stream tcp nowait root /bin/httpd" /etc/inetd.conf


/*修改rc文件的权限为555并拷贝成/etc/rc,注:cp过程中会丧失”可执行”属性*/
$(ROMFSINST) -p 555 $(COMMON)rc /etc/rc
$(ROMFSINST) -p 555 $(COMMON)rc.d/rc.net /etc/rc.d/rc.net
$(ROMFSINST) -p 555 $(COMMON)rc.d/rc.dhcpc /etc/rc.d/rc.dhcpc
$(ROMFSINST) -p 555 $(COMMON)rc.d/rc.qspi /etc/rc.d/rc.qspi
$(ROMFSINST) $(COMMON)inittab /etc/inittab /*直接拷贝*/
$(ROMFSINST) $(COMMON)services /etc/services /*services用于翻译配置文件中的服务名到端口号*/
$(ROMFSINST) $(COMMON)issue /etc/issue
$(ROMFSINST) $(COMMON)passwd /etc/passwd /*登录密码文件*/
if [ $(CONFIG_BLK_DEV_INITRD) = "y" ]; then \
ln -sf bin/init $(ROMFSDIR)/linuxrc; \ /*创建symbol link*/
fi
$(ROMFSINST) $(COMMON)htdocs/index.html /home/httpd/index.html /*直接拷贝*/
$(ROMFSINST) $(COMMON)htdocs/info.html /home/httpd/info.html
$(ROMFSINST) $(COMMON)htdocs/arcturuslogo.gif /home/httpd/arcturuslogo.gif
$(ROMFSINST) $(COMMON)htdocs/miniuclinux2.gif /home/httpd/miniuclinux2.gif
$(ROMFSINST) $(COMMON)htdocs/5272pic.gif /home/httpd/5272pic.gif
$(ROMFSINST) -p 555 $(COMMON)htdocs/cgi-bin/benv.cgi /home/httpd/cgi-bin/benv.cgi
$(ROMFSINST) -p 555 $(COMMON)htdocs/cgi-bin/cpuinfo.cgi /home/httpd/cgi-bin/cpuinfo.cgi
$(ROMFSINST) -p 555 $(COMMON)htdocs/cgi-bin/ifconfig.cgi /home/httpd/cgi-bin/ifconfig.cgi
$(ROMFSINST) -p 555 $(COMMON)htdocs/cgi-bin/interrupts.cgi /home/httpd/cgi-bin/interrupts.cgi
$(ROMFSINST) -p 555 $(COMMON)htdocs/cgi-bin/mem_map.cgi /home/httpd/cgi-bin/mem_map.cgi
$(ROMFSINST) -p 555 $(COMMON)htdocs/cgi-bin/ps.cgi /home/httpd/cgi-bin/ps.cgi
$(ROMFSINST) -p 555 $(COMMON)htdocs/cgi-bin/kmsg.cgi /home/httpd/cgi-bin/kmsg.cgi
/*将版本和时间信息写入/etc/version文档*/
echo "$(VERSIONSTR) -- " `date` > $(ROMFSDIR)/etc/version


image-tools: /*产生需要的工具(tools)*/
touch $(ROOTDIR)/user/boottools/.sgbuilt_user && make -C $(ROOTDIR)/user/boottools uCbootstrap-too
ls
touch $(ROOTDIR)/user/cramfs/.sgbuilt_user && make -C $(ROOTDIR)/user/cramfs host_build


image: image-tools /*合成最终image的最重要部分在这,嘿嘿*/
[ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)  /*查看是否存在放image的目录,不存在则创建*/
rm -rf $(IMAGEDIR)/* /*删除images目录下旧的文件*/
/*以下是给elf格式的linux文件中的.romvec段增加alloc,load,readonly,data属性,
默认的.romvec段没有load属性,但objcopy只处理带load属性的段,所以需要此处理;
-O binary将elf格式的linux文件转化为binary格式的linux.bin*/
$(CROSS)objcopy --set-section-flags=.romvec=alloc,load,readonly,data \
-O binary $(ROOTDIR)/$(LINUXDIR)/linux \
$(ROMFSDIR)/linux.bin


/*修改命令ls的stack的size,如果执行命令时出现“非法指令”,经常是因为stack太小*/
(cd ${ROMFSDIR}/bin; if [ -f ls ] ; then $(CROSS)flthdr -r -s 12288 ls; fi )
(cd ${ROMFSDIR}/bin; if [ -f thttpd ] ; then $(CROSS)flthdr -r -s 20480 thttpd; fi )
(cd ${ROMFSDIR}/bin; if [ -f busybox ] ; then $(CROSS)flthdr -r -s 12288 busybox; fi )


ifdef FORCED_STACK_SIZE /*如果设置强制同意stack的大小,则用这设置全部命令的stack的size*/
(cd $(ROMFSDIR)/bin; for i in `find -type f` ; do J=`$(CROSS)flthdr -p $$i | grep "Stack" | sed -e
"s/Stack Size://g" | sed -e "s/ //g" | sed -e "s/0x//"` ; if [ "$$J" == "1000" ] ; then $(CROSS)flthdr -r
-s $$FORCED_STACK_SIZE $$i ; echo "Increased the stack of $$i to $$FORCED_STACK_SIZE" ; fi ; done)
endif


$(ROOTDIR)/user/cramfs/host_build/mkcramfs -r -n uClinux \
$(ROMFSDIR) $(IMAGEDIR)/image.cramfs /*将romfs目录创建成cramfs文件系统(压缩的romfs),注意linux.bin是放在了romfs目录下了,产生的image,这是cramfs的要求,而后面genromfs 是单独做romfs.img,然后是用cat把linux.bin and romfs 打包 ,有一点差别*/
$(ROOTDIR)/user/boottools/uCbootstrap-tools/uCmkimage \
-f $(IMAGEDIR)/image.cramfs -o $(IMAGEDIR)/image.ucb \
-t `date -I` -n "uC5272 cramfs image"
$(ROOTDIR)/user/boottools/uCbootstrap-tools/uCheader $(IMAGEDIR)/image.ucb


mv $(ROMFSDIR)/linux.bin $(IMAGEDIR)/ /*移动binary格式的linux.bin文件到images目录下*/
/*用genromfs工具命令将romfs目录打包成binary格式的romfs.img*/
genromfs -v -V "uC5272 ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)
/*用cat将linux.bin和romfs.img(binary格式)合并成image.bin(binary格式)*/
cat $(IMAGEDIR)/linux.bin $(ROMFSIMG) > $(IMAGE)


.PHONY:image-tools

-----------------------------------------------------------------------------------------------------------------------------------------------


注意一:如果elf格式的linux文件中的段不是连续的,或中间段的间隔太大,或不同段存在不同的地方(rom和RAM中),则要抽出各段,转成binary格式的文件后用cat合并,因为objcopy是以第一段的开始地址为开始和以最后一个段的结束地址为image结束,两个地址相减就是
image.bin文件的大小。
如:
image:
[ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)
genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)
/*此例来自为vendors/Arcturus/uCsimm/Makefile
.romvec, .text段存在rom中
.data, .init 段在ram中*/

/*在elf格式的linux文件中去掉.romvec和.text ,.bss段,只保留.data和.init段生成linux.data(binary格式)*/
$(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec \
--remove-section=.text --remove-section=.bss \
$(ROOTDIR)/$(LINUXDIR)/linux $(IMAGEDIR)/linux.data


/*在elf格式的linux文件中去掉.data和.init ,.bss段,同时给.romvec段增加load的属性,只保留.romvec和.text
段生成linux.text(binary格式)*/
$(CROSS_COMPILE)objcopy -O binary --remove-section=.bss \
--remove-section=.data \
--set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE \
$(ROOTDIR)/$(LINUXDIR)/linux $(IMAGEDIR)/linux.text


/*三个binary文件合并,产生image.bin*/
cat $(IMAGEDIR)/linux.text $(IMAGEDIR)/linux.data $(ROMFSIMG) > $(IMAGE)

不用remove  加-j只选想要的段 也可以     

$(CROSS_COMPILE)objcopy -O binary -j .data -j .init \
        $(ROOTDIR)/$(LINUXDIR)/linux         $(IMAGEDIR)/linux.data
       $(CROSS_COMPILE)objcopy -O binary -j .romvec -j .text \
        --set-section-flags=.romvec=CONTENTS,ALLOC,LOAD,READONLY,CODE \
        $(ROOTDIR)/$(LINUXDIR)/linux         $(IMAGEDIR)/linux.text

注意二:
> m68k-uclinux-objdump -h linux /*查看elf格式的文件linux的头信息(-h header info)*/

m68k-uclinux-objdump -i linux

注意三:
分开制作段的image时要注意对齐问题,比如在link文件中的.text段的最后加.=align(4)解决此问题。

 


注意四:如何创建elf格式的image(将romfs放在.bss段的位置)
/*
“.../vendor/Arnewsh/M5206/Makefile”
此系统loader 支持binary 和elf 格式的image
*/
image:
[ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)


/*产生binary格式的romfs文件系统的image 文件 “-f”输出文件名 ”-d”目录*/
genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)


/*将elf格式的linux转换成binary格式的linux.bin “-O”输出格式*/
$(CROSS)objcopy -O binary $(ROOTDIR)/$(LINUXDIR)/linux \
$(IMAGEDIR)/linux.bin


/*合并产生binary格式的最后image.bin,由于此板loader支持两种image格式*/
cat $(IMAGEDIR)/linux.bin $(ROMFSIMG) > $(IMAGE)


/*追加checksum的信息到image.bin “-b”应该是binary吧(猜的)*/
$(ROOTDIR)/tools/cksum -b -o 2 $(IMAGE) >> $(IMAGE)


/*复制image.bin到/tftpboot目录下*/
[ -n "$(NO_BUILD_INTO_TFTPBOOT)" ] || cp $(IMAGE) /tftpboot

 

---------以下是创建elf格式image部分--------------------------
/*抓取(grep)用objdump显示linux文件头信息中含“.bss”的行*/
BSS=`$(CROSS)objdump --headers $(ROOTDIR)/$(LINUXDIR)/linux | \
grep .bss` ; \


/*从含.bss的行中获取第4列的信息,即.bbs段的VMA地址*/
ADDR=`set -- $${BSS} ; echo 0x$${4}` ; \


/*增加.romfs段,它的vma地址就是.bbs的地址,因为.bss不占存储位置,同时添加.romfs段的lo
ad属性,生产$(ELFIMAGE)文件(elf格式)*/
$(CROSS)objcopy --add-section=.romfs=$(ROMFSIMG) \
--adjust-section-vma=.romfs=$${ADDR} --no-adjust-warnings \
--set-section-flags=.romfs=alloc,load,data \
$(ROOTDIR)/$(LINUXDIR)/linux $(ELFIMAGE) 2> /dev/null
/*

”2> /dev/null”代表”标准错误“扔到”垃圾站“,”1>“代表标准输出
--no-adjust-warnings 不产生adjust警告(因为两个段.bss 和.romfs 同一地址)

*/