编译器: arm-linux-3.4.1
编译器目录结构,arm外面还包了usr/local两层目录,我觉得没必要写了。这个编译器是我的OK2440-III的开发板带的,可能东西会比网上直接下的会全一点(我还没研究过这个)。
arm |
3.4.1 |
arm-linux |
bin |
include |
info |
lib |
libexec |
man |
tmp |
arm |
3.4.1 |
arm-linux |
bin |
include |
info |
lib |
libexec |
man |
tmp |
内核版本:linux-2.6.12 (也是开发板自带的,应该有改动过很多地方)
主机端环境:vmware 下的Red Hat 9.0 (在安装时我选了工作站,并且用自定义软件的方式把所有的软件包都装了,防止日后有差什么工具就麻烦了)
开发板环境:OK2440-III (一整套950我觉得挺超值的)
1. 为了支持在bootloader下能用超级终端将新内核下载到内存中并运行,我把bootloader下的Downloader from Uart改了。支持用1K Xmodem协议(我写过所以用这种,简单)接收从主机端超级终端传过来的新内核。这个新bootloader我并没有烧到Flash中(我想尽量保留板上原来的状态),是用ads通过H-Jtag来debug的。
2. 重新配置内核,我试了很多次,发现当nfs(内核原本选中这项)和smbfs或cifs同时选中时,内核就无法启动。所以目前我只选中smbfs。
3. 用make zImage编译,会在arch/arm/boot下生成一个zImage的内核bin文件。
4. 用Red Hat 9.0下的smbfs文件系统,将zImage拷背到Windows下的共享文件夹(请看附1)。
5. 下载samba,通过smbfs文件系统,将samba源代码拷背到Red Hat 9.0下(请看附1)。
6. 进入samba的source目录,运行autogen.sh脚本来生成configure文件。
7. 运行./configure 脚本来生成相应makefile和config.h等等文件。这个命令要带很多参数如下:(为了注示我将它分行写)
./configure
--host=arm-linux 这个不知道有没有用,我觉得的主机端应该是自动检测的,不过网上说这样我就没去试了,不过能跑就行了
--target=arm-linux 这个设置目标板,我的一定得这么设了
--prefix=/usr/local/arm/3.4.1/arm-linux 这个设置我个人觉得很重要,因为在编译时所用到的lib和.h文件都是通过这个路径去查找的,就是编译器所在的目录
CC=arm-linux-gcc 设置编译器名称
LD=arm-linux-ld 设置链接器
AR=arm-linux-ar 这个也是编译时用到的,忘了是哪一步用的
--disable-cups
--disable-iprint
--disable-pie
--disable-fam
--enable-debug 因为再调试过程中会遇到很多问题,所以把回显打开了(帮了很多忙)
--with-ads=no --with-ldap=no 这两项会用到一些没有定义的类型指针,所以就关掉了(也没影响)
--with-cifsmount 使能这项在编译后会生成mount.cifs程序(不过如果只用smbfs,这项应该没用)
--with-smbmount 使能这项在编译后才会生成smbmount程序,就是我们的终极目标了
--with-ligfilebase=/var/log
--with-libdir=/usr/lib
--with-swatdir=/usr/local/swat
--with-rootsbindir=/sbin
--with-lockdir=/var/lock
--with-piddir=/var/lock
--with-privatedir=/etc/samba
--with-configdir=/etc/samba 这项指定的smb.conf文件所在目标板上的目录
--cache-file=arm-linux.cache 由于在运行这个configure命令时会出一些错误所以这里指定一个这样的文件,后面在修改configure时会用到
注:以上没有注示的选项都是由网上抄回来的还没有研究过,不过最好还是加上。运行
这个命令之前要先改configure文件的一些地方不然会提示
WARNING: cannot run when cross-compiling并退出。修改如下:
在(9497行)if test "${SMB_BUILD_CC_NEGATIVE_ENUM_VALUES+set}" = set; then前加一行
echo SMB_BUILD_CC_NEGATIVE_ENUM_VALUES=>arm-linux.cache
在32023行左右原来的代码
case "$host_os" in
*linux*)
# glibc <= 2.3.2 has a broken getgrouplist
if test "$cross_compiling" = yes; then
{ { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
See /`config.log' for more details." >&5
echo "$as_me: error: cannot run test program while cross compiling
See /`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
改成
case "$host_os" in
*linux*)
# glibc <= 2.3.2 has a broken getgrouplist
if test "$cross_compiling" = yes; then
{ { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
See /`config.log' for more details." >&5
echo "$as_me: error: cannot run test program while cross compiling
See /`config.log' for more details." >&2;}
}
其实是这个测试编译器的程序不能在主机端运行,所以我们就认为它可以正常在目标板上运行,忽略这个错误,去掉了最后的{ (exit 1); exit 1; };语句让configure继续运行下去
以上这样改完之后一般运行以上命令可以通过,如果不行再运行第二次就可以了。
8. 运行完上面命令后会生成一个config.h和proto.h文件在include下,首先config.h改动如下:(其实最后我发现这些宏也可以在configure命令行添加相应的开关来打开,具体自己研究吧)
/* Whether to use linux kernel oplocks */ 在这一行处添加以下定义
#define HAVE_KERNEL_OPLOCKS_LINUX 1
/* Whether iface ifconf is available */ 在这一行处添加以下定义
/* #undef HAVE_IFACE_IFCONF */
#define HAVE_IFACE_IFCONF 1
/* Whether to include Active Directory support */ 在这一行处添加以下两行语名,可能默认就是没有定义这两个宏,我只是确保一下。
/* #undef WITH_ADS */
#undef WITH_ADS
#undef WITH_LDAP
proto.h部分:
如果proto.h里面有用到LDAP声明指针就把这些注释掉,因为不会用到,按正常是不会生成的,可能是configure时可能哪里有一点错,就自动生成了这些函数声明,但最后一次我检查这个文件时尽然没有生成我原本注释掉的这段代码。
9. 运行make命令,幸运的话应该会在结束后在source/bin目录下看到smbmount,smbmnt等等文件。
10. 通过nfs文件系统将smbmount和smbmnt,smbumount拷背到开发板的/bin目录下(请看附1)。
11. 通过nfs文件系统将主机端的/etc/samba/smb.conf文件拷背到开发板的/etc/samba目录下,我们曾经在运行configure命令时有指定过这个文件夹。
12. 用ADS debug改好的bootloader程序,利用Download from uart接收从主机端的Windows下传输过来的新的内核zImage文件,并启动新内核。
13. 最后就可以用smbmount 命令挂载Windows下的共享文件夹了。例如:smbmount //192.168.12.100/LCN /windows –o username=SZ011//administrator,password=012345
附1:关于如何使用nfs文件系统在开发板与主机端传输文件以及如何使用smbfs文件系统在主机端的linux和windows之间传输文件请参考《LINUX和WINDOWS文件系统共享》一篇。
附2:提示的错误和解决方法
a) "ERROR: Could not determine network interfaces, you must use a interfaces config line"
在config.h文件中添加 #define HAVE_IFACE_IFCONF 1 解决。
b) "ERROR: smbfs filesystem not supported by the kernel"
用第2点解决。
c) "smbfs/init_mount: execv of smbmnt failed. "
用第10点解决,记得要拷背smbmnt。
d) 提示smb.conf找不到,原版英文提示忘了
用第11点解决。