分类: LINUX
2010-05-22 00:27:01
在make romfs过程中碰到了“permission denied”错误。错误信息如下:
make[2]: Entering directory `/home/ciuciu/uClinux-dist/user/net-tools'
romfs-inst.sh -e CONFIG_USER_NET_TOOLS_ARP //sbin/arp
romfs-inst.sh -e CONFIG_USER_NET_TOOLS_HOSTNAME //bin/hostname
romfs-inst.sh -e CONFIG_USER_NET_TOOLS_IFCONFIG //sbin/ifconfig
cp: cannot create regular file `/home/ciuciu/uClinux-dist/romfs//sbin/ifconfig': Permission denied
make[2]: *** [romfs] Error 1
make[2]: Leaving directory `/home/ciuciu/uClinux-dist/user/net-tools'
make[1]: *** [romfs] Error 2
make[1]: Leaving directory `/home/ciuciu/uClinux-dist/user'
make: *** [romfs] Error 1
根据错误信息来看,是在执行指令romfs-inst.sh -e CONFIG_USER_NET_TOOLS_IFCONFIG //sbin/ifconfig时发生错误。其中romfs-inst.sh脚本位于uClinux-dist/tools目录下,是用于构建ROMFS文件系统的重要工具。这条指令是准备将可执行文件ifconfig从当前目录/uClinux-dist/user/net-tools下拷贝到uClinux-dist/romfs/sbin中去。
在分析是什么导致了这个错误之前,可以先了解一下ROMFS文件系统的构建过程,或者说make romfs的执行过程。
1. 在顶层Makefile文件(uClinxu-dist/Makefile)中有如下代码:
.PHONY: romfs
romfs:
for dir in vendors $(DIRS) ; do [ ! -d $$dir ] || $(MAKEARCH) -C $$dir romfs || exit 1 ; done
-find $(ROMFSDIR)/. -name CVS | xargs -r rm –rf
其中DIRS变量和MAKEARCH变量在这个文件前面定义了:
DIRS = $(VENDOR_TOPDIRS) include lib include user
ifneq ($(SUBARCH),)
# Using UML, so make the kernel and non-kernel with different ARCHs
MAKEARCH = $(MAKE) ARCH=$(SUBARCH) CROSS_COMPILE=$(CROSS_COMPILE)
MAKEARCH_KERNEL = $(MAKE) ARCH=$(ARCH) SUBARCH=$(SUBARCH) CROSS_COMPILE=$(CROSS_COMPILE)
else
MAKEARCH = $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE)
MAKEARCH_KERNEL = $(MAKEARCH)
endif
-C选项的含义是:
-C dir, --directory=dir
Change to directory dir before reading the makefiles or doing anything else.
所以上面红色字体可以解释为:
for dir in vendors include lib include user ; do [ ! -d $dir ] || make ARCH=arm CROSS_COMPILE=arm-elf- -C $dir romfs
2. 首先,make romfs将进入vendors目录,读取该目录下的Makefile文件,并执行其中的romfs项。
romfs:
for i in $(dir_v) ; do \
[ ! -d $$i ] || make -C $$i romfs || exit $$? ; \
done
在该文件中,变量dir_v被定义为:
VEND=$(ROOTDIR)/vendors
dir_v = $(VEND)/$(CONFIG_VENDOR)/$(CONFIG_PRODUCT)/.
3. 按照上面的指令,接下来将进入vendors/GDB/ARMulator目录,读取该目录下的Makefile文件,并执行其中的romfs项。其中有一行:
$(ROMFSINST) -s /bin /sbin
这条指令将uClinux-dist/romfs/sbin 符号链接到 /bin。注意这个/bin是指当前主机下根目录下的/bin。
4. 按照红色字体部分,当make romfs从vendors目录退出后,将会接着进入其他目录,最后进入user目录。进入user目录后,读取该目录下的Makefile,执行romfs项。uClinux-dist/user/Makefile中romfs项被解释为如下:
for i in boa dhcpcd-new games gdbserver inetd init login net-tools ping ramimage sash telnetd /home/ciuciu/uClinux-dist/prop ; do [ ! -d $i ] || make -C $i romfs || exit $? ; done
5. 同理,会执行到make –C net-tools romfs. 由此,进入uClinux-dist/user/net-tools目录,读取其中的Makefile, 执行romfs项。
romfs:
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_ARP /$(SBINDIR)/arp
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_HOSTNAME /$(BINDIR)/hostname
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_IFCONFIG /$(SBINDIR)/ifconfig
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_NAMEIF /$(SBINDIR)/nameif
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_NETSTAT /$(BINDIR)/netstat
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_PLIPCONFIG /$(SBINDIR)/plipconfig
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_RARP /$(SBINDIR)/rarp
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_ROUTE /$(SBINDIR)/route
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_SLATTACH /$(SBINDIR)/slattach
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_IPMADDR /$(SBINDIR)/ipmaddr
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_IPTUNNEL /$(SBINDIR)/iptunnel
$(ROMFSINST) -e CONFIG_USER_NET_TOOLS_MII_TOOL /$(SBINDIR)/mii-tool
我们看到,错误正是出现在这个时候,这条命令将ifconfig由当前目录拷贝到romfs/sbin中。但是在此之前,uClinux-dist/romfs/sbin已经符号链接到/bin。因此,当试图拷贝到/romfs/sbin中,ifconfig也会被写入/bin。但是由于我们是在用户账户下构建uClinux,对于系统根目录的bin目录我们没有写入权限。所以“permission denied”错误产生了。