1 交叉編譯環境配置
1.1 交叉編譯工具鏈的獲取
文件準備: arm-linux-tools-20061213.tar.gz.
下載地址: http://ftp.snapgear.org/pub/snapgear/tools/arm-linux/arm-linux/arm-linux -tools-
20061213.tar.gz
1.2 交叉編譯工具鏈的安裝和驗證
解壓文件:到你想安裝的目錄下面解壓文件。以/Work/ arm-linux2006 爲例。
(1)在Ubuntu (9.04) 上,首先經過將文件arm-linux-tools-20061213.tar.gz 拷貝到/Work/armlinux2006
目錄下。
(2)打開終端, cd /Work/ arm-linux2006 ,進入/Work/ arm-linux2006 目錄。
(3)解壓文件:sudo tar zx vf arm-linux-tools-20061213.tar.gz 解壓完成後會生成一個usr 目錄。
(4)解壓完成後,能夠看見有一個usr 目錄,經過cd usr/local/bin 進入bin 目錄。經過ls 能夠
查看目錄下的文件信息。html
如下步驟是爲了操做方便而增長的,若是你利用絕對路徑來引用arm-linux-gcc 的,就能夠不用
作操做。
4
(5)增長系統環境變量,使之後能在任何地方均可以使用arm-linux-gcc 等等工具。在終端中
輸入sudo gedit /etc/environment, 在輸入密碼後,能夠看見一個別打開的環境變量的文件。經過
在最後的環境變量路徑後( 」號前)加一個冒號,而後輸入你的安裝路徑,在本實驗中,輸入
「/Work/arm-linux2006/usr/local/bin 」。而後關閉文件,從新啓動linux 系統後,新的環境變量才
能生效。
2 Linux Kernel編譯過程
2.1 獲取Linux Kernel源代碼及補丁
內核獲取地址: http://www.kernel.org/pub/linux/kernel/ v2.6/
打開上述網頁後,在下面的各類文件中找到linux-2.6.22.2.tar.gz 這個文件,而後下載此文件。
保存到linux 的你喜歡的目錄下面。在本次實驗中,我保存到了。/home/tekkaman/working/ker nel
目錄下。因爲在linux 的linux-2.6.22 版本中,已經對ARM 架構的S3C2410CPU 進行支持了,
所以,不用再像2.4 內核那樣去其餘網站下載移植補丁。因此,對補丁的描述略過。
2.2 內核配置詳解
如下配置信息是根據給出的參考資料肯定的,通過實際實踐,原資料對配置和編譯沒有問題,能
正常編譯並生成zImage 鏡像。
編譯步驟:
5
一、將Linux2.6.22.2 內核源碼放到工做目錄的kernel 文件夾下,並解壓。
#tar xzvf linux2.6.22.2.tar.gz
#pwd
/home/tekkaman/working/kernel
# cd linux2.6.22.2
進入內核解壓後的目錄,之後示例中,只要是相對路徑所有是相對於
/home/tekkaman/working/kernel/linux2.6.22.2/此目錄
二、修改內核源碼根目錄下的Makefile 文件(CROSS_COMPILE =的值因我的狀況而定,
其餘能夠照作。)
#vi Makef ile
......
#SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
# -e s/arm.*/arm/ -e s/sa110/arm/ \
# -e s/s390x/s390/ -e s/parisc64/parisc/ \
# -e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
......
#ARCH ?= $(SUBARCH)
#CROSS_COMPILE ?=
ARCH = arm
CROSS_COMPILE = /Work/arm-linux2006/usr/local/bin/arm-linux-
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
(注意,這裏須要把arm-linux- 工具集的路徑放成你本身工具鏈的路徑。)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6
三、修改arch/arm/plat-s3c24xx/common-smdk.c 文件,修改Nand Flash 的分
區信息和Nand Flash 的硬件信息。
(LED 器件的初始化也在這個文件裏,可是博創的平臺沒有那四個LED 管,因此要不要那些
程序都無所謂。我就把它們放在那裏,反正啓動時不會有影響,也沒有出錯信息。)
注意:請不要多此一舉地在進行自定義nand flash 分區時仍然按照之前內核的移植步驟,在
devs.c 中本身添加分區信息,否則系統啓動時會有出錯信息:
/* NAND parititon from 2.4.18-swl5 */
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "U-Boot-1.2.0",
.size = SZ_128K,
.offset = 0,
},
[1] = {
.name = "U-Boot-1.2.0 Parameter",
.offset = SZ_128K,
.size = SZ_64K,
},
[2] = {
.name = "Linux2.6.22.2 Kernel",
.offset = SZ_128K+SZ_64K,
.size = SZ_4M+(SZ_1M-SZ_128K-SZ_64K),
},
[3] = {
.name = "Root-JFFS2",
.offset = SZ_1M * 5,
.size = SZ_1M * 5,
},
[4] = {
7
.name = "Boot-Root(cramf s)",
.offset = SZ_1M * 10,
.size = SZ_1M * 10,
},
[5] = {
.name = "YAFFS",
.offset = SZ_1M * 20,
.size = SZ_1M * 44,
}
/*, [6] = {
.name = "S3C2410 flash partition 6",
.offset = SZ_1M * 24,
.size = SZ_1M * 24,
},
[7] = {
.name = "S3C2410 flash partition 7",
.offset = SZ_1M * 48,
.size = SZ_16M,
}
*/
};
......
static struct s3c2410_platf orm_nand smdk_nand_inf o = {
.tacls = 0,
8
.twrph0 = 30,
.twrph1 = 0,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets, };
......
四、修改drivers/mtd/nand/s3c2410.c,去掉nand flash 的ECC。
這個內核是經過U-BOOT 寫到Nand Flash 的, U-BOOT 經過的軟件ECC 算法產生ECC
校驗碼, 這與內核校驗的ECC 碼不同, 內核中的ECC 碼是由S3C2410 中Nand Flash 控制
器產生的。因此,在這裏選擇禁止內核ECC 校驗。
搜索關鍵字NAND_ECC_SOFT ,在s3c2410_nand_init_chip 函數裏,修改
NAND_ECC_SOF T 爲NAND_ECC_NONE
五、增長Yaffs2 文件系統的支持
一、下載Yaffs2
URL:http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/
二、解壓Yaffs2 並將其加入Linux 內核(打補丁的方式)
#cd yaffs2
#./patch-ker.sh c /home/tekkaman/working/kernel/linux-2.6.22.2/
六、博創2410-S 所配網卡AX88796(NE200 0兼容網卡)驅動的移植。
(1)修改arch/arm/目錄下的Kconfig 文件,增長ISA 總線支持,使其在make menuconfig
時出現NE2000 的網卡配置選項。
config ARCH_S3C2410
bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
select GENERIC_GPIO
select ISA
9
help
Samsung S3C2410X CPU based systems, such as the Simtec Electronics
BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
the Samsung SMDK2410 development board (and derivatives).
(2)修改include/asm-arm/arch-s3c2410 文件夾下的map.h 文件。加入AX88796 的地址映
射。
/***************tekkaman****************************/
#define S3C2410_VA_ISA_NET S3C2410_ADDR(0x02100000)
#define S3C2410_PA_ISA_NET __phys_to_pfn(0x10000000)
#define S3C2410_SZ_ISA_NET SZ_1M
/**********************tekkaman********************/
(3)修改arch/arm/mach-s3c2410 文件夾下的mach-smdk2410.c 文件。在smdk2410_iodesc
中加入AX88796 的地址信息。
static struct map_desc smdk2410_iodesc[] __initdata = {
/* nothing here yet */
{
.virtual = S3C2410_VA_ISA_NET,
.pfn = S3C2410_PA_ISA_NET,
.length = S3C2410_SZ_ISA_NET,
.type = MT_DEVICE,
}
};
如下修改成選作,能夠不改:
隨便在這裏取消LCD 的初始化,否則啓動時會有出錯信息:
static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_usb,
// &s3c_device_lcd,
&s3c_device_wdt,
10
&s3c_device_i2c,
&s3c_device_iis,
};
修改開發板的名稱(能夠自定義):
MACHINE_START(SMDK2410, "Tekkaman2410")
(4)修改網卡驅動的主要文件drivers/net/ne.c。
a、添加頭文件和定義
#include <asm/system.h>
#include <asm/io.h>
//**********************tekkaman*************************
#include <linux/irq.h>
#include <asm/arch-s3c2410/map.h>
#include <asm/arch-s3c2410/regs-mem.h>
#include <asm/arch-s3c2410/irqs.h>
#include <asm/arch-s3c2410/hardware.h>
#include <asm/arch-s3c2410/regs-gpio.h>
#define AX88796_BASE (vAX88796_BASE+0x200)
#define AX88796_IRQ IRQ_EINT2
#define pAX88796_BASE S3C2410_PA_ISA_NET
#define vAX88796_BASE S3C2410_VA_ISA_NET
#define EXTINT_OFF (IRQ_EINT4 - 4)
//**********************tekkaman*****************************
......
在static struct { const char *name8, *name16; unsigned char SAprefix[4];}
bad_clone_list[] __initdata 中增長AX88796 的MAC 地址前三位(不必定須要) :
{"AX88796", "NE2000-compatible", {0x08, 0x08, 0x08}},
b、確保定義總線寬度爲16 位。
將
11
#if defined(CONFIG_PLAT_MAPPI)
# define DCR_VAL 0x4b
#elif defined(CONFIG_PLAT_OAKS32R) || \
defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
# define DCR_VAL 0x48 /* 8-bit mode */
#else
# define DCR_VAL 0x49
#endif
修改成
#if 0
#if defined(CONFIG_PLAT_MAPPI)
# define DCR_VAL 0x4b
#elif defined(CONFIG_PLAT_OAKS32R) || \
defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
# define DCR_VAL 0x48 /* 8-bit mode */
#else
#endif
#endif
# define DCR_VAL 0x49
c、在do_ne_probe 函數中增長配置總線參數、基地址和中斷的語句(其參數參考劉淼的
書)
static int __init do_ne_probe(struct net_device *dev)
{
unsigned long base_addr = dev->base_addr;
#ifdef NEEDS_PORTLIST
int orig_irq = dev->irq;
#endif
//******************************tekkaman********************************
12
static int once=0;
if (once) {
return -ENXIO;
}
unsigned int value;
value = __raw_readl(S3C2410_BWSCON);
value &= ~(S3C2410_BWSCON_WS2|S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_32);
value |= (S3C2410_BWSCON_ST2|S3C2410_BWSCON_DW2_16);
__raw_writel(value, S3C2410_BWSCON);
value=0;
value =
(S3C2410_BANKCON_Tacs4|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON
_Tcoh4|S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6|S3C2410_BANKCON_PMCnorm);
__raw_writel(value,S3C2410_BANKCON2);
set_irq_type(AX88796_IRQ,IRQ_TYPE_LEVEL_LOW );
s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2);
s3c2410_gpio_pullup(S3C2410_GPF2, 0);
if(base_addr==0){
dev->base_addr = base_addr = AX88796_BASE ;
dev->irq = AX88796_IRQ;
once++;
}
//***********************************tekkaman************************************
SET_MODULE_OWNER(dev);
/* First check any supplied i/o locations. User knows best. <cough> */
if (base_addr > 0x1ff) /* Check a single specified location. */
return ne_probe1(dev, base_addr);
13
else if (base_addr != 0) /* Don't probe at all. */
return -ENXIO;
......
d、修改ne_probe1 函數
增長自定義的網卡MAC 地址(這個地址能夠自行修改,可是MAC 也有必定的規則,最重要
的是千萬不要把它配置爲廣播或組播地址, 請參考網絡的相關書籍):
static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
{
int i;
unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x12,0x27,0};//tekkaman
unsigned char SA_prom[32];
int wordlength = 2;
......
增長網卡MAC 地址的配置語句,屏蔽經過EEPROM 配置網卡的語句
......
struct {unsigned char value, offset; } program_seq[] =
{
{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
{0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */
{0x00, EN0_RCNTLO}, /* Clear the count regs. */
{0x00, EN0_RCNTHI},
{0x00, EN0_IMR}, /* Mask completion irq. */
{0xFF, EN0_ISR},
{E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
{E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
{32, EN0_RCNTLO},
{0x00, EN0_RCNTHI},
{0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
{0x00, EN0_RSARHI},
14
{E8390_RREAD+E8390_START, E8390_CMD},
};
for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
}
//****************************************tekkaman*********************************
{
unsigned char *ep;
ep = (unsigned char * ) &ne_defethaddr[0];
ne_defethaddr[5]++;
for(i=0;i<6;i++) {
SA_prom[i] = ep[i];
}
SA_prom[14] = SA_prom[15]=0x57;
wordlength =2;
}
//****************************************tekkaman*********************************
#if 0 //tekkaman
for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
SA_prom[i] = inb(ioaddr + NE_DATAPORT);
SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
if (SA_prom[i] != SA_prom[i+1])
wordlength = 1;
}
#endif //tekkaman
if (wordlength == 2)
{
#if 0 //tekkaman
for (i = 0; i < 16; i++)
15
SA_prom[i] = SA_prom[i+i];
/* We must set the 8390 for word mode. */
outb_p(DCR_VAL, ioaddr + EN0_DCFG);
start_page = NESM_START_PG;
/*
* Realtek RTL8019AS datasheet says that the PSTOP register
* shouldn't exceed 0x60 in 8-bit mode.
* This chip can be identified by reading the signature from
* the remote byte count registers (otherwise write-only)...
*/
if ((DCR_VAL & 0x01) == 0 && /* 8-bit mode */
inb(ioaddr + EN0_RCNTLO) == 0x50 &&
inb(ioaddr + EN0_RCNTHI) == 0x70)
stop_page = 0x60;
else
stop_page = NESM_STOP_PG;
#endif //tekkaman
outb_p(0x49, ioaddr + EN0_DCFG);
start_page = NESM_START_PG;
stop_page = NESM_STOP_PG;
} else {
start_page = NE1SM_START_PG;
stop_page = NE1SM_STOP_PG;
}
......
屏蔽自定檢測中斷號的語句(參考劉淼的書):
......
#if 0 //tekkaman
if (dev->irq < 2)
16
{
unsigned long cookie = probe_irq_on();
outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */
outb_p(0x00, ioaddr + EN0_RCNTLO);
outb_p(0x00, ioaddr + EN0_RCNTHI);
outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
mdelay(10); /* wait 10ms for interrupt to propagate */
outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */
dev->irq = probe_irq_off(cookie);
if (ei_debug > 2)
printk(" autoirq is %d\n", dev->irq);
} else if (dev->irq == 2)
/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
or don't know which one to set. */
dev->irq = 9;
#endif //tekkaman
if (! dev->irq) {
printk(" failed to detect IRQ line.\n");
ret = -EAGAIN;
goto err_out;
}
AX88697 的移植到此結束!
七、配置內核
在配置內核前,先拷貝s3c2410 開發板的默認配置到內核根目錄下,以簡化配置過程。
#pwd
/home/tekkaman/working/kernel/linux-2.6.22.2
# cp arch/arm/conf igs/s3c2410_def config .config
# make menuconf ig
General setup --->
17
[*] Conf igure standard kernel features (for small systems) --->
選上這項,不然文件系統中的一些選項不會出現
System Type --->
S3C2410 Machines --->
[*] SMDK2410/A9M2410 留下這項就夠了,其餘所有「N」掉
「N」掉S3C2412 Machines ---> 、S3C2440 Machines ---> 和S3C2443
Machines ---> 裏的全部選項,都是和2410 無關的選項。
Boot options --->
將(root=/dev/hda1 ro init=/bin/bash console=ttySAC0) Def ault kernel
command string
改爲(noinitrd root=/dev/mtdblock4 rootfstype=cramf s console=ttySAC0,1152
00 init=/linuxrc mem=64M ) Def ault kernel command string
#說明:
#mtdblock4 表明第5 個flash 分區,用來做根文件系統rootfs;
# console=ttySAC0,115200 使kernel 啓動期間的信息所有輸出到串口0 上,波特率爲
115200 ;
# 2.6 內核對於串口的命名改成ttySAC0,但這不影響用戶空間的串口編程。
# 用戶空間的串口編程針對的還是/dev/ttyS0 等
# mem=64M 表示內存是64M,若是是32 則設爲32M
Userspace binary formats --->
< > Kernel support for a.out and ECOFF binaries (去除該選項, a.out 和ECOFF
是兩種可執行文件的格式,在ARM-Linux 下通常都用ELF,因此這兩種基本用不上。)
Networking --->
Networking options --->
<*> Packet socket
[*] Packet socket: mmapped IO
-下面能夠不選-
Wireless --->
--- Improved wireless configuration API
--- Wireless extensions
<*> Generic IEEE 802.11 Networking Stack (mac80211)
[*] Enable LED triggers
[ ] Enable debugging output (NEW)
<*> Generic IEEE 802.11 Networking Stack
18
[ ] Enable full debugging output (NEW)
--- IEEE 802.11 WEP encryption (802.1x)
< > IEEE 802.11i CCMP support (NEW)
< > IEEE 802.11i TKIP encryption (NEW)
<*> Software MAC add-on to the IEEE 802.11 networking stack
[ ] Enable full debugging output (NEW)
Device Drivers --->
「N」掉Parallel port support ---> 裏的全部選項。
Plug and Play support --->裏的全部選項必定要「N」掉,否則編譯會出錯! !!!!!!!
Network device support --->
Ethernet (10 or 100Mbit) --->
「N」掉< > DM9000 support 和< > Generic Media Independent Interf ace
device support
---------如下必定要選上,是AX88796 的驅動---------
[*] Other ISA cards
<*> NE2000/NE1000 support
-----------------------------------
「N」掉[ ] Ethernet (1000 Mbit) --->和[ ] Ethernet (10000 Mbit) --->
Wireless LAN --->
[*] Wireless LAN (pre-802.11)
[*] Wireless LAN (IEEE 802.11)
USB Network Adapters --->
<*> Multi-purpose USB Networking Framework
<*> MMC/SD card support --->
Real Time Clock --->
「N」掉[ ] Set system time from RTC on startup and resume
#接下來作的是針對文件系統的設置,我實驗時目標箱上要掛的根文件系統是cramf s,故作以下
配置
(注意:不要試圖按照舊內核的方法增長devfs 的支持,由於在這個內核裏已經完全刪除了
devfs 的源代碼。我曾試圖將舊內核的devfs 源代碼複製過來,不過編譯會出錯!
補救的辦法就是用BusyBox 的mdev 來代替,在講根文件系統的創建時我會說明,你也可
以到網上找mdev 的資料。)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
File systems -->
< > Second extended fs support #去除對ext2 的支持
< > Ext3 journalling file system support #去除對ext3 的支持
<*> Kernel automounter support
<*> Kernel automounter version 4 support (also supports v3)
19
<*> Filesystem in Userspace support
Pseudo filesystems -->
[*] Virtual memory file system support (former shm fs)
<*> Userspace-driven configuration filesystem (EXPERIMENTAL)
Miscellaneous filesystems -->
<*> YAFFS2 file system support
「N」掉[ ]Autoselect yaffs2 format 和
[ ]Cache short names in RAM ,由於這是給每頁大於1024B 的NAND Flash 設計的
<*> Journalling Flash File System v2 (JFFS2) support
(0) JFFS2 debugging verbosity (0 = quiet, 2 = noisy)
[*] JFFS2 write-buffering support
[ ] JFFS2 summary support (EXPERIMENTAL)
[ ] JFFS2 XATTR support (EXPERIMENTAL)
[*] Advanced compression options for JFFS2
[*] JFFS2 ZLIB compression support
[*] JFFS2 RTIME compression support
[*] JFFS2 RUBIN compression support
JFFS2 default compression mode (priority) --->
Network File Systems -->
<*> NFS file system support
--如下最好選上,由於在掛載NFS 時可能出現protocol 不支持的狀況--
[*]Provide NFSv3 client support
[*]Provide client support for the NFSv3 ACL protocol extension
[*] Provide NFSv4 client support (EXPERIMENTAL)
[*] Allow direct I/O on NFS files
--------------------------------------------------
<*> NFS server support
[*] Provide NFSv3 server support
[*]Provide server support for the NFSv3 ACL protocol extension
[*] Provide NFSv4 server support (EXPERIMENTAL)
--- Provide NFS server over TCP support
[*] Root file system on NFS
保存退出,產生.config 文件。
八、編譯內核
#make zImage
20
2.3 內核編譯操做過程
3 參考資料
[1]2 中的移植步驟就是下面的三篇文章中的如出一轍,根據個人實際作了一遍,能順利生
成壓縮內核,所以未加改動, http://blog.chinaunix.net/u1/ 34474/showart_369449.htmllinux