Chinaunix首页 | 论坛 | 博客
  • 博客访问: 80660
  • 博文数量: 15
  • 博客积分: 15
  • 博客等级: 民兵
  • 技术积分: 204
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-30 11:18
个人简介

一个奋斗在北京的东北人,一直在打杂,从未被超越!

文章存档

2021年(1)

2013年(11)

2012年(3)

我的朋友

分类: LINUX

2013-05-09 14:42:37

工作平台:fedora 10虚拟机

硬件平台:tq2440

内核版本:2.6.30.4

下载地址

交叉编译器:Sourcery G++ Lite 2009q1-203

下载地址

内核存放位置:/opt/mypaper/ linux-2.6.30.4/

 

      下面做一些简要说明,交叉编译器版本的选择直接关系到对内核编译能否成功,交叉编译工具链主要由三部分组成,binutils,gcc和glibc,通过查阅内核目录下Documentation/Changes文件可以获得相关支持信息,从文件中得知,至少需要GNU C版本为3.2版本,因此,交叉编译器的相对应部分的版本应该该与此相符,高于这个版本可以获得更好的性能,但不一定会编译成功,因此最好选择相对应的版本。通过查阅所下载交叉编译器的版本信息可知,该交叉编译器gcc版本为4.3.3,可以使用。至于交叉编译器解压后,只是修改了一些环境变量以及相关参数,这里不再赘述。下面开始配置内核。

注:所有命令均在内核根目录下执行。

 

修改根目录下的Makefile文件

命令:vim Makefile

修改:

ARCH=arm

CROSS_COMPILE=arm-linux-

原因:指明体系结构为arm,采用的交叉编译器为arm-linux-,这一步一定要改完再执行make menuconfig,否则,用的是x86的make,打开的配置单不是arm的。

 

修改平台输入时钟

命令:vim arch/arm/mach-s3c2440/mach-smdk2440.c

修改:smdk2440_map_io()中的s3c24xx_init_clock(12000000)

原因:tq2440使用12MHz外部时钟输入

 

修改机器码

命令:vim arch/arm/tools/mach-types

修改:s3c2440一行最后的数字改为168

原因:在内核文件arch/arm/mach-s3c2440/mach-smdk2440.c中的 MACHINE_START(S3C2440,”SMDK2440”)中要使用该机器码,同时它还应该与uboot中的机器码一致

 

制作配置单

命令:make menuconfig

原因:一开始内核不存在.config文件,无法进行编译,只有用户按自己需求配置好内核并保存配置单为.config后,才可编译。

下面分别描述内核加入的配置。

       首先加载内核提供的默认配置单,以减少内核配置的工作量。在弹出的配置界面中,选择Load an Alternate Configuration File,加载默认配置arch/arm/configs/s3c2410_defconfig

       该配置单按照arm体系结构添加了一些配置,但有一些是我们不需要的或者是需要修改的,在此基础上进行进一步的配置。

 

General setup,该配置单下包括了内核的一些基本设置,配置时加入的功能有

System V IPC:支持system V的进程间通信对象;

Classic RCU:经典RCU(read-copy-update)支持,这是一种高级互斥机制;

(17) Kernel log buffer size (16 => 64KB, 17 => 128KB):内核日志缓冲区大小为128kb;

Optimize for size:内核大小优化,在编译时采用-O2;

Choose SLAB allocator (SLUB (Unqueued Allocator)):采用高速缓存管理(slab分配器)的高级版本SLUB;

 

Enable loadable module support,该配置单设置是否使用模块加载,在本配置单下选择:

Module unloading:模块可卸载,使得模块可以随时卸载和添加,当然一些不允许卸载的模块除外。

 

Enable the block layer,这个选项不选,因为设备中没有块设备,不需要使用块设备层,NAND flash直接通过IO口和几个控制引脚控制,也不需要块设备层。

 

System Type:该项是一些与平台相关的选项,选择以下几项:

ARM system type (Samsung S3C2410, S3C2412, S3C2413, S3C2440,S3C2443):选择所支持的ARM类型,这里针对开发板选择支持三星S3C2410, S3C2412, S3C2413, S3C2440,S3C2443。

ADC common driver support:与ADC与触摸屏驱动有关,选上;

Force UART FIFO on during boot process:在内核解压时保持串口打开,可用于检测内核解压的情况;

(0) S3C UART to use for low-level messages:选择输出底层信息的串口,根据开发板情况,选择0号串口;

(0) Space between gpio banks:设置GPIO bank之间的空间,用于防止访问越界,选择后会占用一部分存储空间,这个设置为0,注意编写程序,一般不会越界,可以节省存储空间;

S3C2440 Machines

       SMDK2440

       SMDK2440 with S3C2440 CPU module

选择S3C2440 Machines下的这两项,使得内核支持SMDK2440,SMDK2440是三星公司的官方设计参考,一般都采用这种参考。

 

Bus support:该选项选择总线类型,这个不选,没有合适的。

 

Kernel Features:该选项设置内和特性,选择以下几项:

Memory split (3G/1G user/kernel split):内存分配,一般保持该默认配置,即1G给内核空间,3G给用户空间;

Use the ARM EABI to compile the kernel:采用EABI技术编译内核,由于我们的交叉编译器支持EABI,选择该项;

(4096) Low address space to protect from user allocation:设置低端内存大小,按默认。

 

Boot options:引导时的相关选项,保持默认。

 

CPU Power Management:CPU电源管理,保持默认。

 

Floating point emulation:浮点仿真,保持默认。

 

Userspace binary formats:用户空间二进制模式,这里选择

Kernel support for ELF binaries,即采用ELF格式,ELF是可执行连接格式,是UNIX系统实验室作为应用程序二进制接口而开发和发布的。

 

Power management options:电源管理选项,这里不选,我们的设备要保持长时间工作,无需睡眠。

 

Networking support:网络设置,选择配置如下:

Networking options->

       Unix domain sockets:使用UNIX套接字;

       TCP/IP networking:TCP/IP网络;

       IP: kernel level autoconfiguration:内核自动配置IP;

IP: DHCP support :允许本机根文件系统通过NFS(网络文件系统)挂载到其他计算机上,实现远端访问。

Wireless:无线设置,暂时保持默认,以后修改。

 

Device Drivers:设备驱动,保持默认,做驱动时会进行修改。

 

File systems:文件系统配置,选择内容如下:

DOS/FAT/NT Filesystems->

       VFAT (Windows-95) fs suppor:支持挂载windows的文件系统;

       (437) Default codepage for FAT:设置FAT文件系统允许代码页大小;

       (iso8859-1) Default iocharset for FAT:设置FAT文件系统采用的字符类型。

Pseudo filesystems->

Virtual memory file system support (former shm fs):采用虚拟内存文件系统(Tmpfs);

Userspace-driven configuration filesystem:使用configfs,该文件系统与sysfs功能相反。

Miscellaneous filesystems:这个先不做选择,制作yaffs2文件系统后再处理。

Network File Systems->

       NFS client support->

              NFS client support for NFS version 3:使用第三版NFS;

              Root file system on NFS:允许通过NFS挂载根文件系统。

Partition Types:划分类型,这里不选择。

Native language support->

       (iso8859-1) Default NLS Option;

       Codepage 437 (United States, Canada)

       Simplified Chinese charset (CP936, GB2312)

       NLS ISO 8859-1  (Latin 1; Western European Languages)

       NLS UTF-8

给出了支持的语言及字符集类型

 

Kernel hacking:该项大部分是便于内核开发使用的,选择以下几项:

(1024)Warn for stack frames larger than (needs gcc 4.4):设置堆栈报警极限大小;

S3C UART to use for low-level debug:底层是用的UART端口号。

 

Security options:不做配置。

 

Cryptographic API:一些加密和校验码的设置,选择如下:

Cryptographic algorithm manager:启用加密技术必须选择这项;

ECB support:ECB支持;

CRC32c CRC algorithm:启用CRC32c算法;

AES cipher algorithms:启用AES加密算法;

ARC4 cipher algorithm:启用ARC4加密算法;

Hardware crypto devices:启用硬件加密设备;

 

Library routines:一些库函数选择,选择如下:

CRC ITU-T V.41 functions

CRC32 functions

CRC7 functions

        这样,整个配置过程结束,选择Save an Alternate Configuration File,保存为.config即可。现在在根目录下使用make zImage即可编译出内核镜像,但为了方便,作些改动。在根目录下使用命令vim arch/arm/boot/Makefile,进入该目录下的Makefile文件,修改如下

$(obj)/zImage:  $(obj)/compressed/vmlinux FORCE

        $(call if_changed,objcopy)

        @cp -f arch/arm/boot/zImage zImage.bin

        @echo '  Kernel: $@ is ready'

        这个指令就是将arch/arm/boot/目录下的zImage文件复制到根目录下,并重命名为zImage.bin,因为直接使用make zImage命令后zImage默认在arch/arm/boot/目录下,为了方便操作,加入该命令可将镜像复制到根目录下。 

        然后,修改根目录下的Makefile文件,如下:

distclean: mrproper

        @find $(srctree) $(RCS_FIND_IGNORE) \

                \( -name '*.orig' -o -name '*.rej' -o -name '*~' \

                -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \

                -o -name '.*.rej' -o -size 0 \

                -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \

                -type f -print | xargs rm –f rm -f zImage.bin

该命令是为执行make distclean清除文件时添加了一条清除任务,即将复制到根目录下的zImage.bin也清除掉。

        最后,执行make zImage,编译出内核镜像。由于此时未驱动NAND flash,也没有加载文件系统,烧写进开发板以后会显示未挂载文件系统,这进一步说明是正确的。

        下面对NAND flash进行分区和进行相应的配置。

        首先为内核支持NAND flash添加新的配置选项:

Device Drivers->

Memory Technology Device (MTD) support->启用MTD支持,这是使用NAND flash的前提,也是使用JAFFS2文件系统的前提

       MTD partitioning support:我们要对NAND flash进行分区,选中这一项;

       Direct char device access to MTD devices:允许字符设备访问MTD设备;

Common interface to block layer for MTD 'translation layers':块设备层向MTD传输层接口,该项默认必须选上。

Caching block device access to MTD devices:允许缓存块设备访问MTD设备,JAFFS2为文件系统服务。

NAND Device Support->

NAND Flash support for S3C2410/S3C2440 SoC  使内核支持S3C2440 NAND flash

S3C2410 NAND Hardware ECC   采用S3C2410的硬件ECC

设置完毕,退出保存配置单。

 

命令:vim arch/arm/plat-s3c24xx/common-smdk.c

修改内容如下:

static struct mtd_partition smdk_default_nand_part[] = {

      [0] = {

           .name     = "uboot",

           .offset = 0x00000000,

           .size     = 0x00040000,

      },

      [1] = {

           .name     = "kernel",

           .offset = 0x00200000,

           .size     = 0x00300000,

      },

      [2] = {

           .name     = "yaffs2",

           .offset = 0x00500000,

           .size     = MTDPART_SIZ_FULL

      }

};

即将NAND flash分为3个分区,名称分别为uboot,kernel和yaffs2,偏移量分别为0,2M和5M,大小分别为256kb,3M和251M,注意:大小必须为128KB的整数倍。至于为什么这样分区,是和uboot相关的,在我的博客中有一篇原创的文章详细说明这个问题。

 

       然后,修改同文件的下面的代码

static struct s3c2410_platform_nand smdk_nand_info = {

      .tacls         = 10,

      .twrph0        = 25,

      .twrph1        = 10,

      .nr_sets = ARRAY_SIZE(smdk_nand_sets),

      .sets      = smdk_nand_sets,

};

其中修改的值的确定,由NAND flash芯片手册查询相关数据,经计算得到,如下(其中HCLK=100Hz):

tacls>CLE或ALE建立时间最小值*HCLK

twrph0>nWE或nRE的持续时间最小值*HCLK-1

twrph1>写数据起作用时间*HCLK-1

 

       最后,修改drivers/mtd/nand/s3c2410.c中s3c2410_nand_init_chip函数的语句

chip->ecc.mode  = NAND_ECC_NONE;

这里不采用NAND flash的软件ECC校验码,因为在初始化的时候,uboot中有校验码,然后在后面yaffs2文件系统移植的时候,要选上采用S3C2440硬件校验码。

 

yaffs2文件系统移植

添加内核对yaffs2的支持

       YAFFS(Yet Another Flash File System)是专门为NAND Flash存储器设计的嵌入式文件系统,遵循 GPL(General Public License)协议。

 

       在移植前,首先要为内核添加yaffs2文件系统支持,首先下载yaffs2文件系统的补丁,可到下面官方下载页下载。下载后,解压缩,进入yaffs2目录,输入下面命令:

./patch-ker.sh c /opt/mypaper/linux-2.6.30.4/

为内核打上补丁。进入内核目录下的fs目录,这时可以看到出现了一个yaffs2目录,说明已经为内核打上了支持yaffs2的补丁。以后的操作都将再次回到内核源码目录。

命令:make menuconfig

原因:对内核添加yaffs相关配置

        进入配置单,添加之前文件系统中未做的关于yaffs2的配置

File system->

       Miscellaneous filesystems->

              YAFFS2 file system support  添加内核对yaffs2的支持;

              512 byte / page devices  支持512字节/页的设备;

              2048 byte (or larger) / page devices  支持2048字节(2KB)/页的设备;

              Autoselect yaffs2 format  自动选择yaffs2的形式,照应上面两个不同页大小设备的情况。

配置好之后,保存配置单,重新编译内核镜像,此时,内核已经支持yaffs2文件系统了。

利用BusyBox建立根文件系统

       下载并解压busybox源码,这里不再赘述,采用1.13.0版本,最新为1.19.3,下载地址为

 

进入busybox目录,修改Makefile:

命令:vim Makefile

操作:修改CROSS_COMPILE = arm-linux-,指定交叉编译器;

         修改ARCH = arm,指定CPU类型。

 

对busybox进行配置,输入make menuconfig,打开配置单,大部分保持默认即可,这里只写出作了修改的地方。

Busybox Settings  --->

       Build Options  --->

Build BusyBox as a static binary (no shared libs) 这里选择为静态编译,默认为动态链接C程序库,这就需要将庞大的C程序库一同存储,但对于小系统,静态编译更好,这样不需要将整个C程序库放在文件系统中。

Installation Options  ---> 

(../myroot-2.6.30.4) BusyBox installation prefix  修改安装路径为上一级目录的myroot-2.6.30.4目录。

       Busybox Library Tuning  --->

              vi-style line editing commands vi命令编辑风格

              Fancy shell prompts 这一项一定要选上,不然无法识别/etc/profile中的PS1变量。

Linux Module Utilities  ---> 

首先取消Simplified modutils,然后在新出现的菜单中选中insmod,rmmod,lsmod,modprobe,这几项是对模块操作的命令

保存配置单,退出。

 

然后先使用make进行编译,然后再用make install进行安装。

 

注意:编译时出现错误

In file included from /opt/EmbedSky/4.3.3/bin/../arm-none-linux-gnueabi/libc/usr/include/linux/if_tunnel.h:5,

                 from networking/libiproute/iptunnel.c:24:

/opt/EmbedSky/4.3.3/bin/../arm-none-linux-gnueabi/libc/usr/include/linux/ip.h:85: error: redefinition of 'struct iphdr'

很显然是包含头文件ip.h所导致的问题,解决办法,将busybox中的networking/libiproute/iptunnel.c:24的头文件引用#include 注释掉即可,分析原因应该是重复引用造成的。

       这样,在busybox上一级目录下,就出现了myroot-2.6.30.4的目录,其中已经有了bin,sbin,usr三个目录和linuxrc,但这还不是Linux的全部目录结构,因此需要自己再添加其它的目录。

先在myroot-2.6.30.4目录下再建立dev、etc、home、lib、mnt、opt、proc、root、sys、tmp、var目录,如有需要将来可以修改。

命令:mkdir –p dev etc home lib mnt opt proc root sys tmp var

下面填充个目录下的相关内容,并说明个目录的作用。

bin:用户和管理员必备的用户命令。

利用busybox生成的该目录已经包含了大部分常用的命令,这里不需要改动。

 

etc:系统的配置文件和启动脚本存放目录,该目录比较重要。添加内容如下:

(1) /etc/passwd

root:$1$f9ya6yUT$8/8m5URmSjPaR2FKlAf8q.:0:0:root:/:/bin/sh

bin:*:1:1:bin:/bin:

daemon:*:2:2:daemon:/sbin:

yjp:$1$prv02BFs$PezsV1oqmP64KHid2og6C.:502:502:Linux User:home/yjp:/bin/sh

这里注意,刚一开始乱码部分保持空白即可,然后将制好的文件系统烧入开发板,以root登陆,这是不需要密码即可登录成功,然后用命令passwd root和passwd yjp,设置密码即可。如希望出场就有默认密码,则可从设置密码后的/etc/passwd中复制对应乱码,将其粘贴到自制的文件系统中,重新编译文件系统镜像即可。现在默认密码为123456,用户如需修改,自行用passwd修改即可。

(2) /etc/fstab

proc   /proc   proc   defaults 0 0

sysfs  /sys    sysfs   defaults 0 0

tmpfs  /tmp   tmpfs  defaults 0 0

tmpfs  /dev   tmpfs    defaults 0 0 这里注意后面的错误分析

(3) /etc/group,

root:x:0:root

bin:*:1:root,bin,daemon

daemon:*:2:root,bin,daemon

(4) /etc/inittab

::sysinit:/etc/init.d/rcS

::respawn/sbin/getty 115200 yjp_serial0

::ctrlaltdel:/bin/reboot

::shutdown:bin/umount -a –r

然后修改该文件权限:chmod 777 inittab

(5) /etc/shadow 这个空着,不需要写内容

(6) /etc/profile

# Ash profile

# vim: syntax=sh

 

USER="`id -un`"

LOGNAME=$USER

PS1='[\u@\h \W]# '

PATH=$PATH

 

HOSTNAME=`/bin/hostname`

 

export USER LOGNAME PS1 PATH

(7) resolve.conf

nameserver 202.96.128.86

(8) init.d/rcS

#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin

runlevel=S

prevlevel=N

umask 022

export PATH runlevel prevlevel

#

#    Trap CTRL-C &c only in this shell so we can interrupt subprocesses.

#

#    hotplug

mount -a

mkdir /dev/pts

mount -t devpts devpts /dev/pts

echo /sbin/mdev > /proc/sys/kernel/hotplug

mdev -s

 

mkdir -p /var/lock

 

/bin/hostname -F /etc/sysconfig/HOSTNAME

修改权限:chmod 777 etc/init.d/rcS

(9) /etc/rc.d/init.d 暂时空着

(10) /etc/sysconfig/HOSTNAME

yjp

(11) /etc/mdev.conf

sd[a-z]*[0-9] 0:0 0660 @(mount -t vfat -o iocharset=utf8 /dev/$MDEV /mnt/udisk)

sd[a-z]*[0-9] 0:0 0660 *(umount /mnt/udisk)

与U盘载在相关。

至此,etc目录完成。

 

dev:设备文件及其他特殊文件。进入dev目录,执行

mkdir shm

mknod console c 5 1

mknod null c 1 3

建立两个系统是必须用到的设备,终端和内核“黑洞”。

 

home:用户主目录。

mkdir yjp

修改权限:chmod 777 yjp

 

lib:必要的程序库以及内核模块。该目录将交叉编译器的库文件复制过来。

cp -f /opt/EmbedSky/4.3.3/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*.so* lib –a

删除PPP相应的库,不需要。

rm -f lib/libwv* lib/libuniconf*

 

mnt:挂载点,用于暂时挂载文件系统。我们要挂载U盘,在mnt中执行

mkdir udisk

 

opt:附加的软件套件,空着。

proc:用于提供内核与进程信息的虚拟文件系统,空着。

root:root用户主目录,空着。

sys:系统信息与控制(总线,设备以及驱动程序)的虚拟文件系统,mdev可能会在下面建立某些文件,空着。

tmp:暂时性文件,空着。

var:用于存放监控程序和工具程序的可变数据,空着。

usr/bin:非用户必备的二进制文件。这里复制了tq的几个数据传输文件,以方便传输数据。

 

为是系统正常启动,这里再完成串口驱动移植。

 

串口驱动移植

修改内核源码arch/arm/mach-s3c2440/mach-smdk2440.c

static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {

        [0] = {

                .hwport      = 0,

                .flags       = 0,

                .ucon        = 0x3c5,

                .ulcon       = 0x03,

                .ufcon       = 0x51,

        },

        [1] = {

                .hwport      = 1,

                .flags       = 0,

                .ucon        = 0x3c5,

                .ulcon       = 0x03,

                .ufcon       = 0x51,

        },

        /* IR port */

        [2] = {

                .hwport      = 2,

                .flags       = 0,

                .ucon        = 0x3c5,

                .ulcon       = 0x03,

                            .ufcon       = 0x51,

        }

};

修改了ULCON2寄存器值,代表发送与接收每帧的数据位数为8位。

然后修改drivers/serial/samsung.c

添加头文件#include ,该头文件包含了S3C2440的引脚定义。

在函数s3c24xx_serial_startup(struct uart_port *port)的return前添加

if(port->line == 2)

{

     s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_TXD2);

     s3c2410_gpio_pullup(S3C2410_GPH6, 1);

     s3c2410_gpio_cfgpin(S3C2410_GPH7, S3C2410_GPH7_RXD2);

     s3c2410_gpio_pullup(S3C2410_GPH7, 1);

}

分别将2号串口的GPH6和GPH7引脚设置为TXD2和RXD2功能,并禁止上拉。

static struct uart_driver s3c24xx_uart_drv = {

   .owner          = THIS_MODULE,

.dev_name      = "yjp_serial",

   .nr       = 3,

   .cons          = S3C24XX_SERIAL_CONSOLE,

   .driver_name   = S3C24XX_SERIAL_NAME,

   .major         = S3C24XX_SERIAL_MAJOR,

   .minor         = S3C24XX_SERIAL_MINOR,

};

修改了设备名。

添加配置单内容如下:

Device Drivers  --->

       Character devices  --->

              Serial drivers  --->

                     Samsung SoC serial support

                     Support for console on Samsung SoC serial port

                     Samsung S3C2440/S3C2442 Serial port support

重新编译镜像,烧写入开发板。

 

建立文件系统过程中出现的错误及解决方案

1. unable to open an initial console

原因:忘记在dev目录下创建console设备节点。

2. mkdir: can't create directory '/dev/pts': File exists

在制作的文件系统的/etc/fstab中添加

tmpfs /dev tmpfs defaults 0 0

原因:将dev/目录挂载为tmpfs,则在开机时会清空,就不存在文件已存在的问题了。

阅读(1938) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~