全部博文(75)
分类: 嵌入式
2009-11-25 10:46:27
Linux-
by天海一线
|
一、环境介绍:
Host: Fedora Core4,arm-linux-gcc-
Client: linux-
二、移植过程
1、基本移植
(1)修改Makefile文件:
ARCH?=arm
CROSS_COMPILE?=arm-linux-
(2)拷贝基本配置文件
cp arch/arm/configs/s3c2410_defconfig .config
(3)编译测试
Make
(4)添加NAND FLASH分区信息
开发板上NAND共64M,分区为:
0-0x30000 Bootloader 192K(0x30000)
0x30000-0x200000 Kernel 1586K(0x1d0000)
0x200000-0x1800000 rootfs 22M(0x1600000)
0x1800000-0x4000000 yaffsfs 40M(0x2800000)
在arch/arm/mach-s3c2410/devs.c中添加
/* NAND Controller */
#include
#include
#include
static struct mtd_partition partition_info[]={
{
name:"bootloader",
size:0x30000,
offset:0,
},
{
name:"kernel",
size:0x1d0000,
offset:0x30000,
},
{
name:"rootfs",
size:0x1600000,
offset:0x200000,
},
{
name:"yaffsfs",
size:0x2800000,
offset:0x1800000,
},
};
struct s3c2410_nand_set nandset={
nr_partitions:4,
partitions:partition_info,
};
struct s3c2410_platform_nand gyhPlatform={
tacls:0,
twrph0:30,
twrph1:0,
sets:&nandset,
nr_sets:1,
};
在s3c_device_nand结构中添加dev属性:
.dev = {
.platform_data = & gyhPlatform
}
在arch/arm/mach-s3c2410/mach-smdk2410.c中的smdk2410_devices[]结构体中添加&s3c_device_nand使内核在启动的时候初始化nand flash信息。
(5)测试
make
(6)编写生成uImage的脚本mkuImage.sh
#!/bin/sh
mkimage -A arm –O linux –T kernel –C none –n “linux-
chmod u+x mkuImage.sh
./mkuImage.sh
(7)复位开发板,在minicom下,停到uboot的下载模式:
setenv wk tftp 30008000 uImage\;nand erase 30000 1d0000\;nand write 30008000 30000 1d0000
saveenv
run wk
bootm 30008000
能够启动系统且分区信息正确。
2、定制系统
make menuconfig:
Code maturity level optionsà全选
Loadable module supportàEnable loadable module support
Module unloading
Module versioning support
Automatic kernel module loading
General setupàSupport for hot-pluggable devices选择
SCSI device supportàSCSI disk support选择
Probe all LUNs on each SCSI device选择
Input device supportàTouchscreen interface选择
Event interface选择
Event debugging选择
File systemsàKernel automounter support
Kernel automounter version 4 support
Pseudo filesystemsà/devfile system support(OBSOLETE)
Miscellaneous filesystemsàCompressed ROM filesystem support(cramfs)
Network File SystemsàNFS相关的全面选择即可
Native Language Supportà选择437,cp936,Latin1,NLS UTF8
暂时只修改这些,重新编译并下载(run wk)。
3、RTC移植
执行hwclock,提示/dev/misc/rtc不存在。
在arch/arm/mach-s3c2410/mach-smdk2410.c中的smdk2410_devices[]结构体中添加&s3c_device_rtc使内核在启动的时候初始化rtc。
重新编译下载内核,执行hwclock成功。
date 112415372009.20
hwclock –s
hwclock
显示Tue Nov 24 15:39:05 2009 0.000000 seconds (时间更新了,成功)
4、移植yaffs文件系统支持
下载yaffs文件系统源码,进入yaffs2文件夹下,执行
./patch-ker.sh c ~/linux-2.6.11.1/
给内核打上yaffs文件系统补丁。
回到内核目录,make menuconfig
File SystemsàMiscellaneous filesystemsàYAFFS2 file system support
Let’s yaffs do its own ECC
重新编译下载内核,可以挂在yaffs分区了,但是出现了读写NAND时未进行ECC校验的提示,找到drivers/mtd/nand/nand_base.c文件中的nand_write_page,nand_read_ecc,nand_scan三个函数,分别注释掉相应的提示语句即可消除烦人的提示了。
5、网卡CS8900A的驱动移植
(1)拷贝cs8900源码至内核目录
#cp cs8900.c ./drivers/net/arm/
#cp cs8900.h ./drivers/net/arm/
(2)修改cs8900.c
在cs8900_probe()函数中,memset (&priv,0,sizeof (cs8900_t));函数之后添加如下两条语句:
__raw_writel(0x2211d110,S3C2410_BWSCON);
__raw_writel(0x1f7c,S3C2410_BANKCON3);
应该先添加头文件#include
(3)修改Kconfig以允许配置
修改drivers/net/arm/目录下的Kconfig文件,在最后添加如下内容:
Config ARM_CS8900
tristate "CS8900 support"
depends on NET_ETHERNET && ARM && ARCH_SMDK2410
help
Support for CS8900A chipset based Ethernet cards. If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from as well as .
To compile this driver as a module, choose M here and read
. The module will be
called cs8900.o.
(4)修改Makefile加入编译
修改drivers/net/arm/目录下的Makefile文件,在最后添加如下内容:
obj-$(CONFIG_ARM_CS8900) += cs8900.o
(5)在/arch/arm/mach-s3c2410/mach-smdk2410.c文件中,找到smdk2410_iodesc[]结构数组,添加如下如下内容:{vSMDK2410_ETH_IO, pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE}
应先添加头文件#include
在include/asm-arm/arch-s3c2410/目录下创建smdk2410.h文件,其内容为:
#ifndef _INCLUDE_SMDK2410_H_
#define _INCLUDE_SMDK2410_H_
#include
#define pSMDK2410_ETH_IO 0x19000000
#define vSMDK2410_ETH_IO 0xE0000000
#define SMDK2410_ETH_IRQ IRQ_EINT9
#endif // _INCLUDE_SMDK2410_H_
(6)make menuconfig选择CS8900A项,编译下载,CS8900可以工作了。
6、LCD移植
(1)拷贝驱动源代码
cp s3c2410fb.h drivers/video/
cp s3c2410fb.c drivers/video/
(2)修改drivers/video目录下的Kconfig文件,在最后添加如下内容:
config FB_S3C2410
tristate "S3C2410 LCD support"
depends on FB && ARM && ARCH_S3C2410
help
This is a framebuffer device for the S3C2410 LCD Controller. If you plan to use the LCD display with your S3C2410 system, say Y here.
(3)修改drivers/video目录下的Makefile文件,在最后添加如下内容:
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
(4)make menuconfig配置LCD,重新编译并下载,看到小企鹅了。
注:其他配置会影响LCD驱动,导致OOPS,
Code maturity level optionsà全选
Loadable module supportàEnable loadable module support
Module unloading
Module versioning support
Automatic kernel module loading
(5)测试
ls –l > /dev/tty1 LCD上显示目录,搞定。
7、触摸屏移植
(1)拷贝驱动源文件
cp s3c2410_ts.c drivers/input/Touchscreen/
(2)修改drivers/input/Touchscreen/下Makefile文件
添加obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o
(3)修改drivers/input/Touchscreen/下Kconfig文件,在最后添加
config TOUCHSCREEN_S
tristate "Samsung S3C2410 touchscreen input driver"
depends on ARCH_SMDK2410 && INPUT && INPUT_TOUCHSCREEN
select SERIO
help
Say Y here if you have the s3c2410 touchscreen.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called s3c2410_ts.
config TOUCHSCREEN_S3C2410_DEBUG
boolean "Samsung S3C2410 touchscreen debug messages"
depends on TOUCHSCREEN_S3C2410
help
Select this if you want debug messages
(4)在arch/arm/mach-s3c2410/mach-smdk2410.c, 中增加如下内容:
#include
static struct s3c2410_ts_mach_info sbc2410_ts_cfg __initdata = {
.delay = 10000,
.presc = 49,
.oversampling_shift = 2,
};
在smdk2410_devices结构中,添加:
&s3c_device_ts,
在smdk2410_map_io函数中添加:
set_s3c2410ts_info(&sbc2410_ts_cfg);
(5)在 arch/arm/mach-s3c2410/devs.h 文件中添加:
extern struct platform_device s3c_device_ts;
(6)在arch/arm/mach-s3c2410/devs.c文件中添加如下几行:
#include
/* Touchscreen */
static struct s3c2410_ts_mach_info s3c2410ts_info;
void __init set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)
{
memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c2410_ts_mach_info));
}
EXPORT_SYMBOL(set_s3c2410ts_info);
struct platform_device s3c_device_ts = {
.name = "s3c2410-ts",
.id = -1,
.dev = {
.platform_data = &s3c2410ts_info,
}
};
EXPORT_SYMBOL(s3c_device_ts);
(7)创建asm/arch-s3c2410/s3c2410_ts.h文件,内容如下
#ifndef __ASM_ARM_S3C2410_TS_H
#define __ASM_ARM_S3C2410_TS_H
struct s3c2410_ts_mach_info {
int delay;
int presc;
int oversampling_shift;
};
void __init set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info);
#endif /* __ASM_ARM_S3C2410_TS_H */
(8)创建asm/arch-s3c2410/regs-adc.h文件,内容如下
#ifndef __ASM_ARCH_REGS_ADC_H
#define __ASM_ARCH_REGS_ADC_H "regs-adc.h"
#define S3C2410_ADCREG(x) (x)
#define S3C2410_ADCCON S3C2410_ADCREG(0x00)
#define S3C2410_ADCTSC S3C2410_ADCREG(0x04)
#define S3C2410_ADCDLY S3C2410_ADCREG(0x08)
#define S3C2410_ADCDAT0 S3C2410_ADCREG(0x0C)
#define S3C2410_ADCDAT1 S3C2410_ADCREG(0x10)
/* ADCCON Register Bits */
#define S3C2410_ADCCON_ECFLG (1<<15)
#define S3C2410_ADCCON_PRSCEN (1<<14)
#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)
#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)
#define S3C2410_ADCCON_MUXMASK (0x7<<3)
#define S3C2410_ADCCON_STDBM (1<<2)
#define S3C2410_ADCCON_READ_START (1<<1)
#define S3C2410_ADCCON_ENABLE_START (1<<0)
#define S3C2410_ADCCON_STARTMASK (0x3<<0)
/* ADCTSC Register Bits */
#define S3C2410_ADCTSC_YM_SEN (1<<7)
#define S3C2410_ADCTSC_YP_SEN (1<<6)
#define S3C2410_ADCTSC_XM_SEN (1<<5)
#define S3C2410_ADCTSC_XP_SEN (1<<4)
#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)
#define S3C2410_ADCTSC_AUTO_PST (1<<2)
#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0)
//#define S3C2410_ADCTSC_XY_PST (0x3<<0)
/* ADCDAT0 Bits */
#define S3C2410_ADCDAT0_UPDOWN (1<<15)
#define S3C2410_ADCDAT0_AUTO_PST (1<<14)
#define S3C2410_ADCDAT0_XY_PST (0x3<<12)
#define S3C2410_ADCDAT0_XPDATA_MASK (0x03FF)
/* ADCDAT1 Bits */
#define S3C2410_ADCDAT1_UPDOWN (1<<15)
#define S3C2410_ADCDAT1_AUTO_PST (1<<14)
#define S3C2410_ADCDAT1_XY_PST (0x3<<12)
#define S3C2410_ADCDAT1_YPDATA_MASK (0x03FF)
#endif /* __ASM_ARCH_REGS_ADC_H */
(9)配置内核并编译下载
(10)测试
echo 8 > /proc/sys/kernel/printk
cat /dev/ts0
触动触摸屏,会显示坐标信息。
8、OHCI 驱动移植
(1)拷贝源文件
cp ohci-s3c2410.c drivers/usb/host/
(2)修改drivers/usb/ Kconfig文件,添加
config USB_ARCH_HAS_HCD
boolean
default y if USB_ARCH_HAS_OHCI
default y if ARM # SL-811
default PCI
# many non-PCI SOC chips embed OHCI
config USB_ARCH_HAS_OHCI
boolean
# ARM:
default y if SA1111
default y if ARCH_S3C2410
default y if ARCH_OMAP
default y if ARCH_LH7A404
default y if PXA27x
# PPC:
default y if STB03xxx
default y if PPC_MPC52xx
# MIPS:
default y if SOC_AU1X00
# more:
default PCI
(3)修改drivers/usb/host/下ohci-hcd.c文件
添加
#ifdef CONFIG_ARCH_S3C2410
#include "ohci-s3c2410.c"
#endif
修改
#if !(defined(CONFIG_PCI) \
|| defined(CONFIG_SA1111) \
|| defined(CONFIG_ARCH_OMAP) \
|| defined (CONFIG_ARCH_LH7A404) \
|| defined(CONFIG_ARCH_S3C2410) \
|| defined (CONFIG_PXA27x) \
|| defined (CONFIG_SOC_AU1X00) \
)
#error "missing bus glue for ohci-hcd"
#endif
(4)修改arch/arm/mach-s3c2410/mach-smdk2410.c
添加如下内容
#include
#include
#include
#include
#include
int upllvalue_set(void)
{
unsigned long upllvalue;
unsigned long misccr;
upllvalue = (0x78<<12)|(0x02<<4)|(0x03);
__raw_writel(upllvalue,S3C2410_UPLLCON);
misccr = __raw_readl(S3C2410_MISCCR);
misccr |= S3C2410_MISCCR_USBHOST;
misccr &= ~(S3C2410_MISCCR_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1);
__raw_writel(misccr,S3C2410_MISCCR);
return 0;
}
static struct s3c2410_hcd_info smdk2410_usbcfg = {
.port[0] = {
.flags = S3C_HCDFLG_USED
},
.port[1] = {
.flags = S3C_HCDFLG_USED
}
};
void __init smdk2410_init_usb(void)
{
upllvalue_set();
s3c_device_usb.dev.platform_data = &smdk2410_usbcfg;
}
(5)配置make menuconfig
要关注的配置选项主要有:
SCSI device supportàSCSI disk support
SCSI generic support
Probe all LUNs on each SCSI device
USB supportàSupport for Host-side USB
Support USB verbose debug messages
USB device filesystems
OHCI hcd support
USB Mass Storage support
USB Mass Storage verbose debug
USB Human Interface Device(full HID) support
HID interface layer support
(6)make出错,修改usb_create_hcd函数的定义,对drivers/usb/core/hcd.c和hcd.h分别进行修改。
hcd.h:添加两个参数
extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
struct device *dev, char *bus_name);
hcd.c:对应修改函数
struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
struct device *dev, char *bus_name)
{
struct usb_hcd *hcd;
hcd = kcalloc(1, sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL);
if (!hcd) {
dev_dbg (dev, "hcd alloc failed\n");
return NULL;
}
dev_set_drvdata(dev, hcd);
usb_bus_init(&hcd->self);
hcd->self.op = &usb_hcd_operations;
hcd->self.hcpriv = hcd;
hcd->self.release = &hcd_release;
hcd->self.controller = dev;
hcd->self.bus_name = bus_name;
init_timer(&hcd->rh_timer);
hcd->driver = driver;
hcd->product_desc = (driver->product_desc) ? driver->product_desc :
"USB Host Controller";
return hcd;
}
(7)编译并下载测试
插入U盘,有提示出现,
mount –t vfat –o iocharset=cp936 /dev/sda1 /mnt/temp
cd /mnt/temp
ls有显示,但还是存在中文乱码,未解决。
9、SD/MMC驱动移植
(1)拷贝源码
cp s3c2410mmc.h drivers/mmc/
cp s3c2410mmc.c drivers/mmc/
(2)修改Makefile文件,添加
obj-$(CONFIG_MMC_S3C2410) += s3c2410mci.o
(3)修改Kconfig文件,添加
config MMC_S3C2410
tristate "Samsung S3C2410 Multimedia Card Interface support"
depends on ARCH_S3C2410 && MMC
help
This selects the Samsung S3C2410 Multimedia Card Interface
support.
If unsure, say N.
(4)修改arch/arm/mach-s3c2410/mach-smdk2410.c,添加
在smdk2410_devices[]结构体中添加&s3c_device_sdi,
(5)修改include/linux/mmc/mmc.h
在mmc_command结构体中添加
#define MMC_ERR_BUSY 6
#define MMC_ERR_DMA 7
在mmc_data结构体中添加
#define MMC_DATA_WIDE (1 << 11)
(6)修改include/linux/mmc/host.h
#define MMC_HOST_WIDEMODE 1
(7)修改include/asm-arm/arch-s3c2410/regs-sdi.h,添加如下定义
#define S3C2410_SDIDCON_BLKNUM_MASK (0xFFF)
#define S3C2410_SDICMDCON_SENDERHOST (1<<6)
(8)修改include/linuc/mmc/mmc.h和host.h
在mmc.h的mmc_data结构中添加成员struct request *req;
在host.h的mmc_host结构中添加成员u32 flags;
(9)编译下载调试。
10、UDA1341驱动移植
(1)拷贝源码
cp s
(2)在include/asm/arch-s
#define S
#define S
#define S
#define S
#define S
#define S
并添加头文件#include
(3)修改arch/arm/mach-s
IODESC_ENT(GPIO)
(4)修改sound/oss/目录下的Kconfig文件,在最后添加如下内容:
config SBC2410_SND_UDA1341
tristate "S
depends on SOUND_PRIME!=n && SOUND && ARM && ARCH_SMDK2410
help
Say Y here if you have an SMDK2410 and want to use its Philips
UDA1341 audio chip.
(5)修改sound/oss/目录下的Makefile文件,在最后添加如下内容:
obj-$(CONFIG_SBC2410_SND_UDA1341) +=s
(6)make menuconfig选择驱动,并重新编译下载。
(7)测试
cat test.wav > /dev/dsp
听到声音,说明基本正常,进一步的测试可移植ecasound,见附件中的文档。
11、一些说明
其他的驱动因为没有硬件支持,无法测试,暂时不移植了。
程序中用到的源码为开发板带的,也可以参考其他版本的linux内核中的驱动,然后进行修改,本次移植中已经做过修改了,若您使用的是没做过修改的源码,可参考附件里的修改方法,或者直接使用附件中修改过的源码。
大部分方法都是来自网友的共享,在此一并对他们进行感谢。
移植过程只提供一个思路,开发板的资源请自行调整代码。
移植相对比较简单,弄清驱动的工作过程才是我们应该下大力气做的。
对于移植来说,读者应尽量对内核的组织和编译有清晰地认识。可以先将驱动放到合适的位置,然后修改Kconfig和Makefile,然后配置编译,通过增加宏定义、资源初始化等方法依次解决编译过程中出现的错误即可。