2013-03-22 18:46:18 fgq1990 阅读数 523

Linux-2.6.30.4在2440上的移植之RTC时钟驱动

一、移植环境

· 主 机:VMWare--Fedora 9

· 开发板:Mini2440--64MB Nand

· 编译器:arm-linux-gcc-4.3.2

二、移植步骤

1. 查看没有添加对RTC时钟支持的系统。从系统启动信息可以看出RTC设备不能正常打开,系统启动后运行#date命令显示的是原始时间:1970年1月1日

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2. 修改内核代码,添加对RTC时钟的支持。2.6.30.4内核对RTC的驱动已经非常完善了,我们只需要把他设备初始化列表中即可 

#cd linux-2.6.30.4/
#gedit arch/arm/mach-s3c2440/mach-smdk2440.c

3. 配置内核选项对RTC的支持

<*> Real Time Clock --->
         [*] Set system time from RTC on startup and resume
         (rtc0) RTC used to set the system time
         [*] /sys/class/rtc/rtcN (sysfs)
         [*] /proc/driver/rtc (procfs for rtc0)
         [*] /dev/rtcN (character devices)
         <*> Samsung S3C series SoC RTC

4. 重新编译内核后下载到开发板上测试。从系统启动信息可以看出RTC设备正常工作,系统启动后运行#date命令显示的就是当前正确的时间

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5. 测试设置系统时间。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

使 用命令:date -s 设置时间后用hwclock -w保存到RTC设备中,但是这里出错了,说找不到文件或目录,这是为什么呢?这是因为我们还没有在dev中添加RTC设备节点。我们先查看该设备的主设 备号是多少?执行命令:#cat /proc/devices 可以看到rtc的主设备号是254

 

2013-03-22 18:54:30 fgq1990 阅读数 740

嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。

一、移植环境

· 主  机:VMWare--Fedora 9 

· 开发板:Mini2440--64MB Nand 

· 编译器:arm-linux-gcc-4.3.2

二、移植步骤

1. 添加SD卡设备到系统设备初始化列表中。2.6.30.4内核对MMC/SD卡的支持已经非常完善了,而且支持超大容量32GB,所以这里我们只需把 s3c_device_sdi添加到列表中即可,该设备在arch/arm/plat-s3c24xx/devs.c中定义

2. 修改MMC/SD驱动源码。主要是添加SD卡的中断处理,去掉驱动的Bug和一些多余的调试信息 

#gedit drivers/mmc/host/s3cmci.c

 

 

 

3. 修改内核配置选项。完成后重新编译内核下载到开发板上

Device Drivers --->
    <*> MMC/SD/SDIO card support ---> 
        --- MMC/SD/SDIO card support 
        [ ] MMC debugging 
        [ ] Allow unsafe resume (DANGEROUS) 
        *** MMC/SD/SDIO Card Drivers *** 
        <*> MMC block device driver 
        [*] Use bounce buffer for simple hosts 
        < > SDIO UART/GPS class support 
        < > MMC host test driver 
        *** MMC/SD/SDIO Host Controller Drivers *** 
        < > Secure Digital Host Controller Interface support 
        < > MMC/SD/SDIO over SPI 
        <*> Samsung S3C SD/MMC Card Interface support

4. 插入SD卡。当系统启动后插入SD卡就会出现一些信息,还可以看到mmcblk0就是SD设备了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 5. 挂载SD卡。执行mount命令将SD卡挂载到/mnt/mmc/目录下,但是没成功,出错啦

 

 

 

 

 

 

 

 6. 错误分析处理。首先查看/dev/目录下并没有mmcblk0p1节点所以出错,我们查看/proc/partitions/目录发现SD卡的主设备号是179,次设备号是1,那么我们就创建这个设备的节点,b代表块设备,最后再执行mount命令,没有出错

 

   

 

 

 

 

 

 

 

 

 

 

 7. SD卡成功挂载。查看SD卡中的内容

 

 

  

 

 

 

 

 

 

 

 

 

 

2014-07-23 17:18:31 huang446276616 阅读数 638

工作平台:fedora 10虚拟机

硬件平台:tq2440

内核版本:2.6.30.4

下载地址http://www.kernel.org/pub/linux/kernel/

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

下载地址https://sourcery.mentor.com/sgpp/lite/arm/portal/subscription3057

内核存放位置:/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文件系统的补丁,可到下面官方下载页www.yaffs.net下载。下载后,解压缩,进入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,下载地址为http://www.busybox.net/downloads/

 

进入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 <netinet/ip.h>注释掉即可,分析原因应该是重复引用造成的。

       这样,在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 <mach/regs-gpio.h>,该头文件包含了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,则在开机时会清空,就不存在文件已存在的问题了。

2012-11-19 21:36:06 liuxuebest 阅读数 745
linux-2.6.30.4之设备驱动结构体 Cdev【原创】
    在做linux-2.6.30.4版本的驱动之前,首先我们要抛弃Linux-2.4版本内驱动方式的影响。因为该linux-2.6和linux-2.4版本在驱动模式上发生了很多很大的变化,首先是linux-2.6内核引入 了驱动设备结构体一词,其次就是生成的模块不同。
   下面就将linux-2.6.30.4版本的关于gpio口驱动加以说明,驱动的开发涉及到的知识很多,比如32位级处理器的底层程序的编写(实际上是对相关功能的寄存器的操作),还要熟悉linux-2.6内核以上文件系统的源码(所谓的内核源码)和关于基于QTOPIA(移植版的面向手持设备C++ Gui的开发)等相关知识。
    首先从内核驱动说起吧,在编写驱动函数之前,必须完成内核目录树文件的生成。
   其次是必须有机的利用cdev_init()、cdev_add(),cdev_del()、register_chrdev_region()、unregister_chrdev_region()等函数的使用,并且建立起file_operations和设备驱动文件的建立对应关系。
  再次当insmod 加载OK的时候,可以查看dev/目录下是否生成了相关的设备文件。在linux系统中,我们始终保持这样一个概念:一切设备皆为文件,通过内核对应的关系,建立访问、操作该设备。如果没有的话我们必须创建设备文件节点,在这个过程中,要明确主设备号和次设备号的关系以及字符设备驱动、块设备驱动、网络设备等相关基础知识。
最后就是当我们去检测驱动函数是否是正确的时候,通过qtopia编写基于GUI的linux版本的测试工具。在这里我要说下,qt-x11-opensource-src-4.3.4 功能是很强大的,在gui应用程序中很好的结合了文件系统的操作。将C++的优越性大大的展现出来了。

上面是本人基于编写的测试功能模块做得一点点总结。。。下面就附图加以说明
图片 
                                                                                                                                  
                                                                                                                   刘学
                                                                                                            2012-11-19
   同时该文章会在我的个人技术博客上出现。http://blog.csdn.net/liuxuebest 欢迎哦。。
2009-11-22 19:14:00 sanlinux 阅读数 2587

 一、下载linux-2.6.30.4源码,并解压

ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.4.tar.gz

 

tar zxvf linux-2.6.30.4.tar.gz

 

并且下载支持ARM的补丁文件,给标准内核打上ARM补丁。

 

ftp://ftp.arm.linux.org.uk/pub/linux/arm/kernel/v2.6/patch-2.6.0-rmk2.bz2

 

二、在系统中添加对ARM的支持

 

$vim Makefile

193#ARCH           ?= $(SUBARCH)
194 #CROSS_COMPILE  ?=
195 ARCH=arm
196 CROSS_COMPILE=arm-linux-

 注意:还需将arm-linux-编译器的路径添加到PATH环境变量。否则编译时无法找到编译器。


三、修改系统时钟

 

$vim arch/arm/mach-s3c2440/mach-smdk2440.c

 

系统的外部时钟为12MHz

160 static void __init smdk2440_map_io(void)
161 {
162         s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
163         //s3c24xx_init_clocks(16934400);
164         //edit by San

165         s3c24xx_init_clocks(12000000);
166         s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
167 }

 

说明:如果系统时钟不匹配,则出现乱码。

 

四、制作或者获取内核配置单.config

 

$make menuconfig

 

说明:一个比较好的做法是先调用自带的配置清单,该配置清单在arch/arm/configs目录,文件名为:s3c2410_defconfig,该配置文件几乎S3C24XX系列CPU的配置项,可以在此基础上修改配置项。x86的配置项在arch/x86/configs目录下,文件名为:i386_defconfig(32为cpu)。

 

五、修改机器码

【linux内核源码中查看机器码相关文件:】

$vim arch/arm/mach-s3c2440/mach-smdk2440.c

 

178 MACHINE_START(S3C2440, "SMDK2440")
179         /* Maintainer: Ben Dooks <ben@fluff.org> */
180         .phys_io        = S3C2410_PA_UART,
181         .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
182         .boot_params    = S3C2410_SDRAM_PA + 0x100,
183
184         .init_irq       = s3c24xx_init_irq,
185         .map_io         = smdk2440_map_io,
186         .init_machine   = smdk2440_machine_init,
187         .timer          = &s3c24xx_timer,
188 MACHINE_END

修改机器码,使之与bootloader的机器码相同,这里使用的是u-boot,机器码为168

 

$vim arch/arm/tools/mach-types

 

 379 s3c2440                 ARCH_S3C2440            S3C2440                 168

 

$vim arch/arm/tools/Makefile

 7 include/asm-arm/mach-types.h: $(src)/gen-mach-types $(src)/mach-types
 8         @echo '  Generating $@'
 9         @mkdir -p $(dir $@)
10         $(Q)$(AWK) -f $^ > $@ || { rm -f $@; /bin/false; }

 

$vim include/asm/mach-types.h

375 #define MACH_TYPE_S3C2440              168


【U-boot中的相关配置文件】

$vim include/asm-arm/mach-types.h

377 #define MACH_TYPE_S3C2440              168

 

总结:首先从linux内核源码中找出机器类型(如S3C2440),其次,根据u-boot中给出的对应机器类型的机器码(如377 #define MACH_TYPE_S3C2440 168)修改内核机器码。流程如下:

内核:

$vim arch/arm/mach-s3c2440/mach-smdk2440.c

U-boot:

$vim include/asm-arm/mach-types.h

内核:

$vim arch/arm/tools/mach-types

 

说明:如果机器码错误,则系统提示选取平台,死机。

 

六、编译镜像

 

$make zImage

 

七、板子烧写

 

使用DNW工具将内核镜像烧写至开发板中

 

 八、遇到的问题

 

问题:

  Kernel panic - not syncing: Attempted to kill init!

 

解决办法:

  $make menuconfig

选择以下两项:

 Kernel Features  --->

 [*] Use the ARM EABI to compile the kernel                               
 [*]   Allow old ABI binaries to run with this kernel (EXPERIMENTAL)

 

九、NandFlash驱动移植

 

linux里面已经包含NandFlash驱动,只需对源码进行修改即可。

 

1、$vim arch/arm/plat-s3c24xx/common-smdk.c

 

107 /* NAND parititon from 2.4.18-swl5 */
108
109 static struct mtd_partition smdk_default_nand_part[] = {
110 #if defined(CONFIG_San_64MB_NAND)
111         [0] = {
112                 .name   = "San_Board_uboot",
113                 .size   = 0x00040000,
114                 .offset = 0x00000000,
115         },
116         [1] = {
117                 .name   = "San_Board_kernel",
118                 .size  = 0x00200000,
119                 .offset= 0x00200000,
120         },
121         [2] = {
122                 .name   = "San_Board_yaffs2",
123                 .size   =  0x03BF8000,

124                 .offset = 0x00400000,
125         }
126 #elif defined(CONFIG_San_128MB_NAND)
127         [0]={
128                 .name   ="San_Board_uboot",
129                 .offset =0x00000000,
130                 .size   =0x00040000,
131         },
132         [1]={
133                 .name   ="San_Board_kernel",
134                 .offset =0x00200000,
135                 .size   =0x00200000,
136         },
137         [2]={
138                 .name   ="San_Board_yaffs2"
139                 .offset =0x00400000,
140                 .size   =0x07BA0000,
141         }
142 #elif defined(CONFIG_San_more_than_256MB_NAND)

143         [0]={
144                 .name   ="San_Board_uboot",
145                 .offset =0x00000000,
146                 .size   =0x00040000,
147          },
148          [1]={
149                  .name   ="San_Board_kernel",
150                  .offset =0x00200000,
151                  .size   =0x00200000,
152          },
153          [2]={
154                  .name   ="San_Board_yaffs2",
155                  .offset =0x00400000,
156                  .size   =0x0FB80000,
157          }
158 #endif
159 };

 

2、$vimdrivers/mtd/nand/Kconfig

 

166 choice
167         prompt "Nand Flash Capacity select"
168         depends on MTD
169         help
170           SanBoard Nand Flash Capacity select
171
172 config San_64MB_NAND
173         boolean "64MB Nand for SanBoard"
174         depends on MTD
175         help
176           Set 64MB Nand parts
177
178 config San_128MB_NAND
179         boolean "128MB Nand for SanBoard"
180         depends on MTD
181         help
182           Set 128MB Nand parts
183
184 config San_more_than_256MB_NAND
185         boolean "256MB~1GB Nand for SanBoard"
186         depends on MTD
187         help
188           Set 256MB~1GB Nand parts
189
190 endchoice

注:如果在make menuconfig中选中San_64MB_NAND,则在.config表现形式如下:

CONFIG_San_64MB_NAND=y

这实际是给C源文件提供预编译变量,如#if defined(CONFIG_San_64MB_NAND).......

这个过程就是实现了内核的定制,比如新增Nand驱动、或者去除wireless驱动。。。

 

十、移植yaffs2文件系统

 

1、获取yaffs2源码

http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/

 

2、在内核中添加对yaffs2的支持

在刚下载的yaffs2源码中,执行:

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

此时在内核fs目录下,新增“yaffs2”目录,同时fs/目录下面的Makefile文件和Kconfig文件也添加了yaffs2的配置和编译条件。

 

3、在配置单中添加对yaffs2的支持


$make menuconfig

 

File systems  --->

                [*] Miscellaneous filesystems  --->

                                     <*>   YAFFS2 file system support

注意:假如在内核中没有添加对yaffs2的支持,则出现找不到或者挂载文件系统是失败的提示:

List of all partitions:
0100       4096 ram0 (driver?)
0101       4096 ram1 (driver?)
0102       4096 ram2 (driver?)
0103       4096 ram3 (driver?)
0104       4096 ram4 (driver?)
0105       4096 ram5 (driver?)
0106       4096 ram6 (driver?)
0107       4096 ram7 (driver?)
0108       4096 ram8 (driver?)
0109       4096 ram9 (driver?)
010a       4096 ram10 (driver?)
010b       4096 ram11 (driver?)
010c       4096 ram12 (driver?)
010d       4096 ram13 (driver?)
010e       4096 ram14 (driver?)
010f       4096 ram15 (driver?)
1f00        256 mtdblock0 (driver?)
1f01       2048 mtdblock1 (driver?)
1f02      63168 mtdblock2 (driver?)
No filesystem could mount root, tried:  ext3 ext2 cramfs msdos vfat romfs
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(31,2)

 

4、yaffs2移植完成,重新编译内核

 

十一、在内核中添加tmpfs支持

如果不添加tmpfs支持,那么将会出现那/tmp挂载失败的提示。关于tmpfs的作用待研究。

mount: mounting tmpfs on /tmp failed: Invalid argume

文件系统配置:

[root@san /]#cat /etc/fstab
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
var /dev tmpfs defaults 0 0

 

File systems  --->

                      Pseudo filesystems  --->

                                      [*] Virtual memory file system support (former shm fs)

 

                                      [*]   Tmpfs POSIX Access Control Lists

 

 

没有更多推荐了,返回首页