一、内核配置和编译
1.修改顶层Makefile第195行
ARCH ?= arm
CROSS_COMPILE ?= arm-none-linux-根据自己的环境修改交叉编译器前缀
2.修改arch/arm/boot/Makefile 增加第57行
@echo ' Kernel: $@ is ready'
cp arch/arm/boot/zImage /tftpboot根据自己的ftp服务器目录修改
3.匹配机器码
1) 启动u-boot执行bd将输出开发板的相关信息,包括机器码
SMDKC100 # bd
arch_number = 0x00000722机器码1826
boot_params = 0x20000100
DRAM bank = 0x00000000
-> start = 0x20000000
-> size = 0x10000000
ethaddr = 11:22:33:44:55:66
ip_addr = 192.168.2.203
baudrate = 115200 bps
TLB addr = 0x2FFF0000
relocaddr = 0x2FF8B000
reloc off = 0x0818B000
irq_sp = 0x2FE4AF70
sp start = 0x2FE4AF60
FB base = 0x00000000
2) 内核机器码
arch/arm/mach-s5pc100/mach-smdkc100.c第254行
MACHINE_START(SMDKC100, "SMDKC100")
SMDKC100即为机器码类型
arch/arm/tools/mach-types 第333行
smdkc100 MACH_SMDKC100 SMDKC100 1826
4.执行默认配置
root@zjh:/home/work/linux-3.5.5# make s5pc100_defconfig
5.配置内核
root@zjh:/home/work/linux-3.5.5# make menuconfig
Kernel Features --->
[*] Use the ARM EABI to compile the kernel
[*] Allow old ABI binaries to run with this kernel (EXPERIMENTAL)
注:使用 4.X.X 版本的交叉编译器一定要选中以上两项,否则会出现Kernel panic - not syncing: Attempted to kill init! 这样的错误以致没法启动内核
6.编译内核
root@zjh:/home/work/linux-3.5.5# make zImage
7.制作uImage
1) 将编译好的u-boot目录下的tools目录下的mkimage拷贝到/usr/bin目录下
root@zjh:/home/work# cp u-boot-samsung-ok/tools/mkimage /usr/bin/
2) 进入/tftpboot目录并制作uImage
root@zjh:/tftpboot# mkimage -n 'linux-3.5.5' -A arm -O linux -T kernel -C none -a 0x20008000 -e 0x20008040 -d zImage uImage
Image Name: linux-3.5.5
Created: Thu Oct 4 16:37:42 2012
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1357848 Bytes = 1326.02 kB = 1.29 MB
Load Address: 20008000
Entry Point: 20008040
8.启动u-boot,执行如下操作
SMDKC100 # tftp 20008000 uImage
SMDKC100 # bootm 20008000
## Booting kernel from Legacy Image at 20008000 ...
Image Name: linux-3.5.5
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1357848 Bytes = 1.3 MiB
Load Address: 20008000
Entry Point: 20008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0
Linux version 3.5.5 (root@zjh) (gcc version 4.5.1 (Sourcery G++ Lite 2010.09-50) ) #1 Thu Oct 4 16:36:12 CST 2012
CPU: ARMv7 Processor [412fc081] revision 1 (ARMv7), cr=10c53c7d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: SMDKC100
Memory policy: ECC disabled, Data cache writeback
CPU S5PC100 (id 0x43100000)
S3C24XX Clocks, Copyright 2004 Simtec Electronics
S5PC100: PLL settings, A=1332.0MHz, M=267.0MHz, E=67.500MHz, H=24.0MHz
………………
………………
二、DM9000网卡驱动移植
1.修改arch/arm/mach-s5pc100/mach-smdkc100.c
第57行添加如下代码
#ifdef CONFIG_DM9000
#include <linux/dm9000.h>
#include <linux/irq.h>
#endif
/* DM9000 Support*/
#ifdef CONFIG_DM9000
static struct resource dm9000_resources[] = {
[0] = {
.start=0x88000000,// DM9000网卡基地址(Bank0),ADDR2=0,发送地址时使用这个地址
.end=0x88000000+0x3,
.flags=IORESOURCE_MEM,
},
[1] = {
.start=0x88000000+0x4,// ADDR2=1,发送数据时使用这个地址
.end=0x88000000+0x4+0x3,
.flags=IORESOURCE_MEM,
},
[2] = {
.start=IRQ_EINT(10),// 中断号(根据原理图)
.end=IRQ_EINT(10),
.flags=IORESOURCE_IRQ|IRQ_TYPE_LEVEL_HIGH,
},
};
static struct dm9000_plat_data s5pc100_dm9000_platdata = {
.flags = DM9000_PLATF_16BITONLY,// 数据总线宽度16位
.dev_addr[0] = 0x00,// MAC地址
.dev_addr[1] = 0x00,
.dev_addr[2] = 0x3e,
.dev_addr[3] = 0x26,
.dev_addr[4] = 0x0a,
.dev_addr[5] = 0x00,
};
static struct platform_device s5pc100_device_dm9000 = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(dm9000_resources),
.resource = dm9000_resources,
.dev = {
.platform_data = &s5pc100_dm9000_platdata,
}
};
#endif
第251行添加如下代码
#ifdef CONFIG_DM9000
&s5pc100_device_dm9000,
#endif
2.配置内核支持DM9000
root@zjh:/home/work/linux-3.5.5# make menuconfig
[*] Networking support --->
Networking options --->
<*> Packet socket
<*> Unix domain socket
[*] TCP/IP networking
[*] IP: multicasting
[*] IP: kernel level autoconfiguration
[*] IP: BOOTP support
Device Drivers --->
[*] Network device support --->
[*] Ethernet driver support (NEW) --->
<*> DM9000 support
File systems --->
[*] Network File Systems (NEW) --->
<*> NFS client support
[*] NFS client support for NFS version 3 (NEW)
[*] NFS client support for the NFSv3 ACL protocol extension
[*] Root file system on NFS
3.编译内核并制作uImage
4.启动u-boot,并设置启动参数
注:我之前按照华清远见的设置root=nfs启动不了,查看了一下文档Documentation/filesystems/nfs/nfsroot.txt 第45行root=/dev/nfs
SMDKC100 # set root=/dev/nfs nfsroot=192.168.2.202:/home/work/rootfs ip=192.168.2.203 init=/linuxrc console=ttySAC0,115200
下载内核并启动
SMDKC100 # tftp 20008000 uImage
SMDKC100 # bootm 20008000
## Booting kernel from Legacy Image at 20008000 ...
Image Name: linux-3.5.5
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1959728 Bytes = 1.9 MiB
Load Address: 20008000
Entry Point: 20008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0
Linux version 3.5.5 (root@zjh) (gcc version 4.5.1 (Sourcery G++ Lite 2010.09-50) ) #2 Thu Oct 4 16:58:36 CST 2012
CPU: ARMv7 Processor [412fc081] revision 1 (ARMv7), cr=10c53c7d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: SMDKC100
Memory policy: ECC disabled, Data cache writeback
CPU S5PC100 (id 0x43100000)
S3C24XX Clocks, Copyright 2004 Simtec Electronics
S5PC100: PLL settings, A=1332.0MHz, M=267.0MHz, E=67.500MHz, H=24.0MHz
sclk_mixer: source is clk_27m (0), rate is 27000000
sclk_lcd: source is div_mpll (1), rate is 133500000
sclk_fimc: source is div_mpll (1), rate is 133500000
sclk_fimc: source is div_mpll (1), rate is 133500000
sclk_fimc: source is div_mpll (1), rate is 133500000
sclk_irda: source is div_mpll (1), rate is 66750000
sclk_irda: source is div_mpll (1), rate is 133500000
sclk_pwi: source is ext_xtal (0), rate is 12000000
sclk_uhost: source is div_mpll (1), rate is 133500000
S5PC100: HCLKD0=166.500MHz, HCLKD1=133.500MHz, PCLKD0=83.250MHz, PCLKD1=66.750MHz
………………
………………
dm9000 Ethernet Driver, V1.31
eth0: dm9000a at d0814000,d0816004 IRQ 42 MAC: 00:00:3e:26:0a:00 (platform data)
mousedev: PS/2 mouse device common for all mice
i2c /dev entries driver
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
TCP: cubic registered
NET: Registered protocol family 17
dm9000 dm9000: >eth0: link up, 100Mbps, full-duplex, lpa 0x41E1
IP-Config: Guessing netmask 255.255.255.0
IP-Config: Complete:
device=eth0, addr=192.168.2.203, mask=255.255.255.0, gw=255.255.255.255
host=192.168.2.203, domain=, nis-domain=(none)
bootserver=255.255.255.255, rootserver=192.168.2.202, rootpath=
VFS: Mounted root (nfs filesystem) on device 0:9.
Freeing init memory: 124K
route: SIOCADDRT: Network is unreachable
Please press Enter to activate this console.
Processing /etc/profile...
Done
[root@farsight /]#
三、LED驱动移植
1.在drivers/char/目录下新建led驱动文件
root@zjh:/home/work/linux-3.5.5# touch drivers/char/fsc100_led_drv.c
内容如下
#include <linux/miscdevice.h>
#include <mach/regs-gpio.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio.h>
extern void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);
#define DEVICE_NAME "fsc100_led" /* 设备名,加载模块后执行cat /proc/devices看到的设备名 */
/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
#define IOCTL_GPIO_ON1
#define IOCTL_GPIO_OFF0
static long fsc100_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
switch (cmd)
{
case IOCTL_GPIO_ON:
// 设置指定引脚的输出电平为1
s3c2410_gpio_setpin(S5PC100_GPG3(arg), 1);
return 0;
case IOCTL_GPIO_OFF:
// 设置指定引脚的输出电平为0
s3c2410_gpio_setpin(S5PC100_GPG3(arg), 0);
return 0;
default:
return -EINVAL;
}
}
static struct file_operations dev_fops = {
.owner=THIS_MODULE,
.unlocked_ioctl=fsc100_ioctl,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret;
int i;
for (i = 0; i < 4; i++)
{
s3c_gpio_cfgpin(S5PC100_GPG3(i), S3C_GPIO_OUTPUT); // 设置对应引脚为输出
s3c2410_gpio_setpin(S5PC100_GPG3(i), 0); // 初始全灭
}
ret = misc_register(&misc);
printk (DEVICE_NAME" initialized\n");
return ret;
}
static void __exit dev_exit(void)
{
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
2.修改drivers/char/Kconfig,在menu "Character devices"下面添加如下内容
config FSC100_LED
tristate "FSC100 LED Device Support"
depends on ARCH_S5PC100
---help---
support led test on FSC100 board
3.修改drivers/char/Makefile ,在末尾下添加
obj-$(CONFIG_FSC100_LED) += fsc100_led_drv.o
4.编写用户层测试程序fsc100_led_test.c
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int fd;
int led_no;
int led_ctl;
if (argc != 3 || sscanf(argv[1], "%d", &led_no)!= 1 || sscanf(argv[2], "%d", &led_ctl)!= 1 |
led_no < 1 || led_no > 4 || led_ctl < 0 || led_ctl > 1)
{
fprintf(stderr, "Usage:%s led_no 0|1\n", argv[0]);
exit(1);
}
fd = open("/dev/fsc100_led", O_RDONLY);
if (fd < 0)
{
perror("open");
exit(1);
}
ioctl(fd, led_ctl, led_no - 1);
close(fd);
return 0;
}
5.交叉编译测试程序
root@zjh:/home/work# arm-none-linux-gnueabi-gcc -static fsc100_led_test.c -o led
将可执行文件led拷贝到根文件系统目录rootfs/usr/bin目录下
root@zjh:/home/work# cp led rootfs/usr/bin/
6.静态编译LED驱动
root@zjh:/home/work/linux-3.5.5# make menuconfig
Device Drivers --->
Character devices --->
<*> FSC100 LED Device Support
7.重新编译内核并制作uImage
8.下载内核测试
SMDKC100 # tftp 20008000 uImage
SMDKC100 # bootm 20008000
…………
s3c6400-uart.1: ttySAC1 at MMIO 0xec000400 (irq = 75) is a S3C6400/10
s3c6400-uart.2: ttySAC2 at MMIO 0xec000800 (irq = 76) is a S3C6400/10
s3c6400-uart.3: ttySAC3 at MMIO 0xec000c00 (irq = 77) is a S3C6400/10
fsc100_led initialized
…………
[root@farsight /]# ./led
Usage:./led led_no 0|1
[root@farsight /]# ./led 1 1 点亮LED1
[root@farsight /]# ./led 2 1 点亮LED2
[root@farsight /]# ./led 1 0 熄灭LED1
四、RTC驱动移植
5.arch/arm/mach-s5pc100/mach-smdkc100.c第247行已经添加了rtc设备
&s5pc100_device_ac97,
&s3c_device_rtc,
&s5p_device_fimc0,
6.配置内核
Device Drivers --->
[*] Real Time Clock --->
[*] Set system time from RTC on startup and resume (NEW)
(rtc0) RTC used to set the system time (NEW)
[*] /sys/class/rtc/rtcN (sysfs) (NEW)
[*] /proc/driver/rtc (procfs for rtc0) (NEW)
[*] /dev/rtcN (character devices) (NEW)
<*> Samsung S3C series SoC RTC
7.重新编译内核
启动时输出
s3c-rtc s3c64xx-rtc: >setting system clock to 2012-03-29 14:10:45 UTC (1333030245)
[root@farsight /]# date
Thu Mar 29 14:11:45 UTC 2012
[root@farsight /]# date -s 2012.10.05-16:30:10 设置时间
Fri Oct 5 16:30:10 UTC 2012
[root@farsight /]# hwclock -w 保存设置
这样重启后系统时间会自动更新
五、看门狗驱动移植
1.修改drivers/watchdog/s3c2410_wdt.c第52行
#define CONFIG_S3C2410_WATCHDOG_ATBOOT (1)// 启动看门狗
#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)// 超时值15s
2.arch/arm/mach-s5pc100/mach-smdkc100.c第241行已经添加了WDT设备
&s3c_device_ts,
&s3c_device_wdt,
&smdkc100_lcd_powerdev,
3.配置内核
Device Drivers --->
[ *] Watchdog Timer Support --->
<*> S3C2410 Watchdog
4.重新编译内核并下载到开发板测试
s3c2410_wdt: S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdt s3c2410-wdt: >starting watchdog timer
s3c2410-wdt s3c2410-wdt: >watchdog active, reset enabled, irq disabled
此时由于没有喂狗,系统启动后过会就会自动重启
5.编写喂狗程序feed_wdt.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <linux/watchdog.h>
int main()
{
int fd = 0;
int n = 0;
fd = open("/dev/watchdog", O_RDONLY);
if (fd < 0)
{
perror("/dev/watchdog");
exit(1);
}
for (;;)
{
ioctl(fd, WDIOC_KEEPALIVE); // 一直喂狗
sleep(3);
}
close(fd);
return 0;
}
6.交叉编译feed_wdt.c
root@zjh:/home/work# arm-none-linux-gnueabi-gcc -static feed_wdt.c -o feed_wdt
将生成的可执行文件拷贝到根文件系统目录rootfs/sbin
root@zjh:/home/work# cp feed_wdt rootfs/sbin/
7.修改启动脚本文件rootfs/etc/init.d/rcS
#!/bin/sh
#This is the first script called by init process
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
feed_wdt &
ifconfig lo 127.0.0.1
ifconfig eth0 192.168.2.203 netmask 255.255.255.0 up
route add default gw 192.168.1.1
8.重启开发板
六、SD卡驱动移植
1.Linux-3.5.5已经很好的支持SDka了,只需简单的配置内核就可以了
root@zjh:/home/work/linux-3.5.5# make menuconfig
SD卡驱动配置
Device Drivers --->
<*> MMC/SD/SDIO card support --->
<*> SDHCI support on Samsung S3C SoC
[*] DMA support on S3C SDHCI
文件系统及语言配置
File systems --->
DOS/FAT/NT Filesystems --->
<*> VFAT (Windows-95) fs support
-*- Native language support --->
<*> Codepage 437 (United States, Canada)
<*> Simplified Chinese charset (CP936, GB2312)
<*> ASCII (United States)
<*> NLS ISO 8859-1 (Latin 1; Western European Languages)
<*> NLS UTF-
2.重新编译内核并下载到开发板
SMDKC100 # tftp 20008000 uImage
SMDKC100 # bootm 20008000
## Booting kernel from Legacy Image at 20008000 ...
Image Name: linux-3.5.5
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2020984 Bytes = 1.9 MiB
Load Address: 20008000
Entry Point: 20008040
Verifying Checksum ... OK
XIP Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
Booting Linux on physical CPU 0
Linux version 3.5.5 (root@zjh) (gcc version 4.5.1 (Sourcery G++ Lite 2010.09-50) ) #25 Sun Oct 7 13:04:50 CST 2012
CPU: ARMv7 Processor [412fc081] revision 1 (ARMv7), cr=10c53c7d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
Machine: SMDKC100
Memory policy: ECC disabled, Data cache writeback
CPU S5PC100 (id 0x43100000)
…………
mmc1: mmc_rescan_try_freq: trying to init card at 260742 Hz
mmc2: mmc_rescan_try_freq: trying to init card at 400000 Hz
mmc2: mmc_rescan_try_freq: trying to init card at 300000 Hz
…………
[root@farsight /]#
3.插入SD卡
[root@farsight /]# mmc1: mmc_rescan_try_freq: trying to init card at 400000 Hz
mmc1: new high speed SDHC card at address e624
mmcblk0: mmc1:e624 SU04G 3.69 GiB
mmcblk0: p1
[root@farsight /]# mount /dev/mmcblk0p1 /mnt/ 挂载SD卡
[root@farsight /]# ls /mnt/ 显示SD内容
[root@farsight /]# umount /mnt/ 卸载SD卡
4.制作SD卡自动挂载
在根文件系统根目录下创建用于挂载SD卡的目录
root@zjh:/home/rootfs# mkdir sddisk
在etc/下创建配置文件mdev.conf
root@zjh:/home/work/rootfs# vi etc/mdev.conf
内容如下
mmcblk[0-9]*p[0-9] 0:0 0660 @(mount -t vfat /dev/$MDEV /sddisk)
mmcblk[0-9]*p[0-9] 0:0 0660 *(umount /sddisk)
更多mdev.conf的设置可参考busybox的docs/mdev.txt文件