Thursday, August 18, 2011

功率單位mW和dBm

功率單位mW和dBm
功率單位轉換
換算工具
dBm/mW數值填寫,請參閱您的無線基地台/無線裝置的產品詳細規格"output -power" (Transmit Power)輸出功率。

轉:http://www.cerio.com.tw/cerio-zh-tw/aaa126.asp

疑問小幫手 : 功率單位mW和dBm換算
無線基地台輸出的射頻信號,通過電纜傳送到天線,由天線以無線波形式射頻出去。無線波形到達接收地點後,由天線接收下來(僅僅接收很小很小一部分功率),並通過電纜送到無線基地台接收。因此在無線網路架設規劃中,如何知道無線基地台的發射功率與天線的無線波型射頻能力是非常重要的。 
Tx是發射( Transmits )的簡稱。無線基地台的發射功率是指在使用頻段範圍內的能量,通常有兩種測量標準: 
1、功率( W ): 相對 1 瓦( Watts )的線性水平。例如,WiFi 無線網卡的發射功率通常為 0.063W ,或者說63mW 。
2、增益( dBm ):相對 1 毫瓦( milliwatt )的比例水準。例如是市售 WiFi 無線網卡的發射 增益 為 15.56dBm~18dBm 。 
兩種表達方式可以互相轉換 
1、dBm = 10 x log[ 功率 mW]
2、mW = 10[ 增益 dBm / 10 dBm]
在無線網路系統中,天線被用來把電流波轉換成電頻波,在轉換過程中還可以對發射和接收的信號進行"放大",這種能量放大的度量成為 "增益(Gain)"。 天線增益的度量單位為" dBi "。由於無線系統中的電頻波能量是由發射設備的發射能量和天線的放大總和產生,因此計算發射能量最好同一單位-增益( dB ),例如,發射設備的功率為 100mW ,或20dBm;天線的增益為 10dBi ,則:
發射總能量=發射功率( dBm )+天線增益( dBi ) 
= 20dBm + 10dBi = 30dBm
或者: = 1000mW = 1W
在"無線產品功率"中(例如無線區域網路設備)每個 dB 都非常重要,特別要記住" 3 dB 法則"。每增加或降低 3 dB ,意味著增加一倍或降低一半的功率: 
-3 dB = 1/2 功率 
-6 dB = 1/4 功率 
+3 dB = 2x 功率 
+6 dB = 4x 功率 
例如, 100mW 的無線發射功率為 20dBm ,而 50mW 的無線發射功率為 17dBm ,而200mW 的發射功率為 23dBm 。
(dBm):放大器的輸出能力,一般單位為W、mW、dBm。dBm是取1mW作基準值,以分貝表示的絕對功率。
換算公式:
Power值(dBm)=10lgW
1mW10log1 = 0dBm
2mW10log2 = 3dBm
4mW10log4 = 6dBm
8mW10log8 = 9dBm
10mW10log10 = 10dBm
16mW10log16 = 12dBm
20mW10log20 = 13dbm
100mW10log100 = 20dBm
...
1W → 10lg1000 = 30dBm
5W → 10lg5000 = 37dBm
10W → 10lg10000 = 40dBm
20W → 10lg20000 = 43dBm
所以功率每增加一倍,Power值增加3dBm

Sunday, August 14, 2011

FreeRadius安装和配置-基础

FreeRadius安装和配置-基础
0. 概述
FreeRadius是一个开源的Radius服务器系统,可以作为一般标准化的用户身份验证系统为网络中的用户提供服务,通常用作有线和无线的网络接入,为各种接入设备和方式提供用户身份鉴定和记账服务。
1. 系统
本文以CentOS 5.5系统作为参考操作系统平台,文中的各种命令、参数和设置均基于此系统。其他Linux系统应该大同小异。
本机服务器的IP地址为192.168.8.100。并且可以直接访问互联网(用于软件下载和安装)。

2.安装
使用以下命令安装FreeRADIUS软件模块,一般涉及到的有三个:
yum install freeradius2 (主服务)
yum install freeradius2-mysql (mysql支持)
yum install freeradius2-utils (本地测试工具如ratest等)

安装完成后可以使用下列命令检查已安装的软件包
rpm -qa freeradius\*
freeradius2-mysql-2.1.7-7.el5
freeradius2-2.1.7-7.el5
freeradius2-utils-2.1.7-7.el5

3. 启动和诊断模式
使用以下命令启动 radius服务程序,也可以停止服务和查看服务状态
service radiusd start/stop/status
如果需要随系统启动,下列命令将服务作为启动项目
chkconfig --add radiusd (添加注册)
chkconfig radiusd on (创建启动项目)
在系统调试过程中可以使用诊断模式,该模式可以诊断服务启动过程,配置信息错误和用户连接和响应等过程。但需要注意该模式不能和正常运行模式同时使用。
service radiusd stop (停止服务)
radiusd -X (进入诊断模式)
ctrl-c 退出诊断模式
正常进入诊断模式成功的结果应为
”Ready to process requests”

4. 配置文件
FreeRaduis的设置涉及到很多配置文件,这里稍作总结:
/etc/raddb/radiusd (主服务配置文件)
/etc/raddb/clients.conf (文件方式的客户端设备配置文件)
/etc/raddb/users (文件方式的用户配置)
/etc/raddb/sql.conf (数据库相关配置)

5. 客户端配置
这里的客户端指的是处理用户接入请求的网络设备,系统也为测试提供了一个内置的客户端。可以查看配置文件(默认不需要修改)
/etc/raddb/clients.conf 
系统默认配置了一个名为localhost的本地NAS Client配置设备,默认共享密钥为testing123。
任何需要利用radius服务器来进行验证前,都需要类似的客户端设置,通常的格式为:
client 192.168.8.100 {     
      secret = testing123 
      shortname = myradclient
      nastype=other
}
上述直接在服务器上创建一个客户端(其实是服务器本身)。

6. 测试帐号配置
这里使用一个保存在文件中的帐号作为测试帐号,编辑 /etc/raddb/users 文件,在尾部添加信息创建下列测试帐号
ufiletest Cleartext-Password := “password123”
含义是创建一个名为ufiletest,密码是明文"password123"

7. 服务测试
在运行 radius -X诊断程序后,在新的终端窗口使用下列命令(radtest,需要预先安装
freeradius2-utils
)测试服务是否正常运行
radtest ufiletest password123 localhost 10 testing123

语法为 radtest {用户名} {用户密码} {RADIUS服务器地址或主机名} 10(NAS端口,但好像没什么特别含义) {共享密码}
如果结果中有 Access-Accept 接受指令,表明服务器工作正常并且用户验证正常。也可以试着修改用户名或口令查看相关的错误信息,确认radius基本服务工作正常。


8. sql配置(MySQL)
上面都使用文件来保存相关信息如客户端、用户等等,在真正的较大规模的环境中通常使用数据库来保存和维护这些信息。就需要做相关配置告诉radius服务器如何来连接和使用数据库系统。
a. MySQL配置
我们假设已经在本机安装了MySQL数据库系统。进一步需要在MySQL数据库中创建相应的数据库和表结构。一个参考的表结构可以使用daloradius系统设计的表结构,由于此内容较多,但并不直接影响FreeRadius的设置,关于如何安装和配置MySQL for FreeRadius的更详细的信息,参见另一篇文章:
b. 包含sql.conf配置文件
编辑FR主服务器配置文件,取消注释信息,告诉系统包含sql.conf中的配置信息
$INCLUDE sql.conf 

c.编辑FR数据库配置文件中的连接信息
打开/etc/raddb/sql.conf
修改下列属性
login=”radius” (数据库登录用户)
password=”radpass” (相应密码)
radius_db=”radiusdb” (radius所使用的数据库名)
readclients=yes (是否从数据库中读取客户端设备列表)

d. 添加功能模块支持
编辑 /etc/raddb/sites-enabled/default 文件,取消sql关键字前的注释,以添加相关模块(可能包括authorize-认证,accounting-审计,session-会话用于监测同时连接,post_auth-验证后记录...)对数据库的支持,如:
authorize { (认证组件)
          preprocess (预处理)
          chap (支持chap)
          mschap (对mschap的支持)
          suffix (后缀)
          eap (支持eap)
          sql (支持数据库)
          pap  (支持pap认证协议)
}

重启radiusd服务或者进入诊断模式查看配置是否正确
e. 联合测试
检查在sql.conf中关于数据库特别是表的设置是否和数据库中的实际情况相符,使用sql语句在用户表中添加一个用户记录,就可以使用radiusd-X和radtest来进行测试了。

FreeRadius-EAP配置和测试

FreeRadius-EAP配置和测试
 
0. 目的和前提
本文的目的是在FreeRadius服务器上配置一个测试环境,测试该服务器对于EAP认证方式的支持和工作正常。
前面的过程见《FreeRadius安装和配置-基础
这一部分在前面的基础上,配置FreeRadius支持EAP的各种认证方式。
1、基础配置
a. 测试帐号
确认在/etc/raddb/users中已经配置了测试帐号
ufiletest Cleartext-Password := "password123"
 :这里有个让人有点哭笑不得的问题,需要将这些用户定义放在文件的最开始处,而不是最后面!!否则在后面的测试中可能会失败,提示的错误信息包括:
rlm_eap_md5: Cleartext-Password is required for EAP-MD5 authentication
[eap] Handler failed in EAP/md5
b. 本机在网络上client设置
在/etc/raddb/clients中添加本机的“网络地址”客户端,这里使用服务器自己的为192.168.1.184(原来的测试地址是本机localhost)
client 192.168.1.184 {
      secret = testing123
      shortname = myradserver
 }
c. 模拟从网络上发起的测试
使用下面命令,测试客户端和用户配置,确认认证通过。
radtest ufiletest password123 127.0.0.1 1812 testing1233
radtest ufiletest password123 192.168.1.184 1812 testing1233

2. 简单EAP测试
我们可以使用最简单的EAP-MD5协议来测试服务器对EAP的支持是否正常。默认的FreeRadius不需要做其他设置即可支持EAP-MD5,但需要用另外一个工具 radeapclient(已随FreeRadius Utility安装):
编辑一个 eaptest.md5文件,内容为认证请求信息:
User-Name = "ufiletest"
Cleartext-Password = "password123"
EAP-Code = Response
EAP-Id = 210
EAP-Type-Identity = "ufiletest"
Message-Authenticator = 0x00
运行下列命令载入认证信息
radeapclient -x 127.0.0.1 auth testing123 <eaptest.md5
验证成功的标准是一个Access-Accept包和EAP-code=Success提示。

3. EAP证书配置
全功能的EAP认证方式需要证书系统的支持,包括主要的三个协议:EAP-TLS,EAP-TTLS和PEAP。
首先需要三个证书文件,分别为ca.pem(根CA证书表明了可信任的证书颁发机构),server.pem(服务器证书),server.key(服务器公钥),这三个文件在FreeRadius安装过程中已经生成,并保留在/etc/raddb/certs目录下(注,他们是自签名的测试用证书,不建议在实际应用环境中使用)。
为使这些证书发挥正常作用,需要在 /etc/raddb/eap.conf 文件中确定下列设置(其中confdir变量是在radiusd.conf中定义的):
certdir = ${confdir}/certs
cadir = ${confdir}/certs
private_key_password = whatever
private_key_file = ${certdir}/server.pem
CA_file = ${cadir}/ca.pem 
这些设置的正确性还可以在 radiusd -X 启动时的诊断信息中检查。

4. 高级测试工具 eapol_test
eapol_test工具可能需要自己编译,在开始前需要先安装gcc工具:
yum install gcc++
否则在编译时会出错:
make: cc: Command not found
make: *** [config.o] Error 127

然后到下列地址下载wpa_supplicant的源代码
http://hostap.epitest.fi/wpa_supplicant/
下载-解压-编译-运行:
cd ~
wget http://hostap.epitest.fi/releases/wpa_supplicant-0.7.3.tar.gz
tar xvf wpa_supplicant-0.7.3.tar.gz
cd wpa_supplicant-0.7.3/wpa_supplicant
cp defconfig .config
make eapol_test
......
cp eapol_test /usr/local/bin

也可以在下列地址下载二进制文件(http://www.eduroam.cz/rad_eap_test/eapol_test/ 
wget http://www.eduroam.cz/rad_eap_test/eapol_test/eapol_test
为了清楚期间,我们编辑一个配置文件作为该测试工具的EAP参数输入,来分别测试各种EAP功能的实现,命令为: 
eapol_test -c <测试文件> -a 127.0.0.1 -p 1812 -s testing123 -r 1

5. EAP高级测试(PEAP)
编辑一个测试用文件 eaptest.peap,包含下列请求信息:
network={
eap=PEAP
eapol_flags=0
key_mgmt=IEEE8021X
identity="ufiletest"
password="password123"
ca_cert="/etc/raddb/certs/ca.pem"
phase2="auth=MSCHAPV2"
anonymous_identity="anonymous"
}
运行测试命令:
eapol_test -c eaptest.peap -a 127.0.0.1 -p 1812 -s testing123 -r 1
语法为
eapol_test -c {请求信息文件} -a {认证服务器地址} -p {端口} -s {共享密钥} -r 1
如果成功,将在最后一行看到 SUCCESS,否则为FALLURE

6. EAP高级测试(TLS)
编辑一个测试用文件 eaptest.tls,包含下列请求信息:
network={
eap=TLS
eapol_flags=0
key_mgmt=IEEE8021X
identity="ufiletest"
password="password123"
ca_cert="/etc/raddb/certs/ca.pem"
client_cert="/etc/raddb/certs/server.pem"
private_key="/etc/raddb/certs/server.key"
private_key_passwd="whatever"
}
测试命令:
eapol_test -c eaptest.tls -a 127.0.0.1 -p 1812 -s testing123 -r 1
注:TLS需要客户端和服务器双方的证书(在此例中相同,都为server.pem)。
6. EAP高级测试(TTLS)
EAP-TTLS-MD5的配置文件为 eaptest.ttls.md5
network={ eap=TTLS eapol_flags=0 key_mgmt=IEEE8021X identity="ufiletest" password="password123" anonymous_identity="anonymous" ca_cert="/etc/raddb/certs/ca.pem" phase2="auth=MD5" }
EAP-TTLS-MSCHAPv2,配置文件为 eaptest.ttls.chap
network={
eap=TTLS
eapol_flags=0
key_mgmt=IEEE8021X
identity="ufiletest"
password="password123"
anonymous_identity="anonymous"
ca_cert="/etc/raddb/certs/ca.pem"
phase2="auth=MSCHAPV2"
}
注:两者的区别在于第二阶段的密码验证方式不同(MD5和MSCHAPv2)。
如果上述测试都能够通过,则证明RADUIS服务器为这些验证方式都做好了准备。

6. 一些相关名词解释和总结
PAP(Password Authentication Protocol 密码验证协议)
最基础的身份验证,直接使用明文传送用户名和密码信息,安全性较低。

CHAP(Challenge-Handshake Authentication Protocol 挑战-握手验证协议)
其特点是使用哈希来处理密码,并使用一个随机生成的信息来维持会话,提高了安全性。

MS-CHAP和MS-CHAPv2
是CHAP的微软实现方式,但也是国际标准协议。在CHAP基础上提供了更多特性和安全性。

EAP(Extensible Authentication Protocol 可扩展身份验证协议):
其实它是一个身份验证的标准框架,它可以和其他算法或者身份验证协议组合起来,提供一个灵活的,可支持多种验证方法,能提供更高安全性的验证机制。

EAP-MD5
使用MD5算法的EAP协议。是基本的最简单的EAP协议实现,这一协议的实现不需要证书体系。

EAP-TLS(EAP Trnsport Level Security EAP传输层安全协议)
大体上是SSL的升级版本,使用PKI来保护通讯,是IETF的开放标准,具有较好的兼容性。

EAP-TTLS(EAP-Tunneled Transport Layer Security EAP隧道传输层安全协议)
IETF的开放标准草案,提供非常优秀的安全性。而且不需要客户端认证协议。

PEAP(Protected EAP 保护性EAP)
和EAP-TTLS类似,使用一个加密和认证过的传输层安全来保护EAP,需要PKI,但只需要服务器端。有两个实现PEAP-MSCHAP和PEAP-GTC。

LEAP(Lightweight EAP 轻量级EAP)
基本上是Cisco的私有协议实现。

EAP-SIM,EAP-AKA....其他较少应用的EAP

7. 相关常见问题
- 各种证书的位置(CA、服务器、客户端)
- 共享密钥
- 客户端配置(client.conf)
- 各种验证相关功能开启

Sunday, August 7, 2011

嵌入式系統軟硬體環境建構步驟

嵌入式系統軟硬體環境建構步驟
轉:http://blog.xuite.net/jackie.xie/bluelove/5224669

軟硬體環境

硬體平台:Ciruss Logic EDB72xxARM720T CPU)
使用軟體:
  • Cross compile  Binutils : binutils2.10 , linux-2.4.0-test1.tar.gz , patch-2.4.0test1-ac19.bz2 , patch-2.4.0-test1-ac19-rmk1.gz
    Gcc : gcc-2.95.2.tar.gz , gcc-2.95.2-diff-991022.gz
    Glibc : glibc-2.1.3 , glibc-linuxthreads-2.1.3.tar.gz , glibc-crypt-2.1.tar.gz
為了得到可以在EDB7209上執行的kernel,我們須要cross compiler工具,它的功用是讓我們能在一般的PC Linux平台編譯出可以在ARM CPU上執行的可執行檔。我們在這一部份採用GNU gcc 2.95.2做為compiler並且將其patchARMcross compiler,同時我們必須有一台PC Linux平台來當做程式發展的平台,以便當我們在此平台完成kernel的編譯後再將kernel下載到EDB7209上執行
  • Linux kernel nkernel version 2.4.2
Patch : patch-2.4.2-rmk1.gz , patch-2.4.2-rmk1-bluemug7.gz
一般針對i386平台散布的Linux並不能在ARM720T CPU執行,為了讓我們的硬體平台有Linux可以執行,我們必須找到特別針對ARM為硬體架構而發展的Linux patch。目前在Linux的討論社群上可以發現有一些專門幫ARM CPU補正Linux kernel的計畫,較知名的有Russell King 所持續釋出的ARM patch。另外,有一個組織是專門針對Ciruss Logic 所出產的EDB72xx系列的平台釋出其週邊裝置的driver patch。此外,此組織亦提供了將Linux kernel下載到平台上的工具ShoehornHermit
  • Downloader shoehorn-3.4
    hermit-1.1
Shoehorn是將kernel下載到EDB7209DRAM裡,這種方式在將EDB7209的電源切斷後,一切資料就會消失,下一次必須重新載入kernel。而Hermit則是將kernel下載到板子的FLASH中,如此一來當電源關閉時Linux仍然是存在於FLASH中,下一次再開啟電源Linux即會開機開始執行。
 
nn

建構步驟

Creating ARM tool-chain
binutils
gcc
glibc
Creating ARM-LINUX kernel
Kernel patching
Creating ramdisk
Application program : busybox0.46
Creating downloader
Shoehorn downloader
Hermit downloader
Downloading kernel and ramdisk

Tool chain 的建立  Binutils  Gcc  Libc
ARMtool-chain共分為三個部份:binutilsgccglibcbinutils包含一些binary tools,可以用來處理已編譯完的binary檔。gcc是我們所需要的cross compilerglibc則是一些常用的函式庫。

Binutils
binutils是一些用來對binary檔做特殊處理的工具程式,這些工具將在建立cross compiler時被用到。建立步驟如下:
  1. 從下列任一網站下載binutils的原始碼檔案,在這裡我們使用binutils2.10為例,將下載的binutils-2.10.tar.gz放置於/tmp目錄下。 
    · ftp://ftp.gnu.org/gnu/binutils/  - binutils的官方網站
  2. binutils-2.10.tar.gz解開: 
     $cd /tmp 
     $tar zxvf ./binutils-10.1.tar.gz 
  3. 現在我們準備對binutils做一些組態設定,將目錄切換至binutils的目錄。 
       如果我們要ARM Linux的平台上建立native tool-chain則輸入下列命令: 
       $./configure --prefix=/usr/local 
        若我們要在一個x86平台建立cross tool-chain則輸入下列命令:(這是我們所要的選項) 
       $./configure --target=arm-linux --prefix=/usr/local 
        在下達上面的命令後,組態程式便會開始檢查系統的一些設定,包括平台,使用的gcc 版本以及測是一些C的函式庫是否有支援。在上面的命令中,prefix代表的是我們想要安裝binutils的目錄,而target則表示binutilsprefix目錄中的目錄名稱,也就是說將來安裝完成後binutils會被安裝到/usr/local/arm-linux/目錄中。
  4. 在組態設定完成後便可進行編譯的動作: 
      $make 
      此命令會啟動gcc compiler進行編譯的動作,編譯完成後進行binutils的安裝: 
     $make install 
 這時所有的工具程式將會被安裝到/usr/local/arm-linux/目錄下。
Gcc
  現在我們可以開始進行gcc的建立,在編譯ARMgcc 之前,我們須要ARM Linux kernel的標頭檔(headers)。當然假如我們要建立的是一個native compiler時這個步驟可以省略,因為在我們的系統上就已經有ARM Linuxkernel source了。但如果我們要建立的是cross compiler,那我們必須有一個ARM Linux kernel source,以便在編譯gcc時可以參考到kernel的標頭檔。
  1. 到下列網站下載Linux kernel source/tmp目錄中,由於kernel版本眾多,在這裡只要是v2.4版以上的都可以,我們採用2.4.0-test1版,將linux-2.4.0-test1.tar.gzpatch-2.4.0test1-ac19.bz2下載到/tmp目錄: 
    接下來到下列網站下載2.4.0-test1-ac19版的Russell M. King ARM patch patch-2.4.0-test1-ac19-rmk1.gz,一樣置於/tmp目錄中:
  2. kernel source/tmp目錄下解開: 
       $tar zxvf linux-2.4.0-test1.tar.gz  
       這樣在/tmp目錄下會出現linux的目錄,接下來做kernel source的更新: 
    $cd linux 
    $bzcat ../patch-2.4.0test1-ac19.bz2 | patch -p1 -s -E  
       這個命令共包含兩個動作bzcatpatch,首先bzcat是兩種命令的組合:bzip2cat。所以當執行bzcat時會先將patch-2.4.0test1-ac19.bz2解壓縮(bzip2),並將其內容列印在標準輸出裝置上(cat)。而patch則是負責將patch file所更正的部份在原始檔上做修改。為了將bzcat的輸出導正為patch的輸入我們使用了pipe( | )這個命令。 
       接著是ARM patch的更新: 
       $ zcat ../patch-2.4.0-test1-ac19-rmk1.gz | patch -p1 -s -E  
       由於ARM patch檔是以gzip壓縮,所以我們改用zcat取代bzcat
  3. 現在必須編輯/tmp/linux/目錄中的Makefile檔案,將 
       ARCH := $(shell uname ... 略 ...) 
       改成 
       ARCH := arm  
       這麼做的原因是為了讓將來編譯gcc時可以正確的參考到ARM的部份。
  4. linux目錄下執行下列命令: 
       $make menuconfig  
       畫面上會出現選單式的畫面,這是用來設定kernel組態的畫面,目前我們不需要做任何的設定,只要存檔之後就可以離開。接著下此命令: 
       $make dep 
        如此一來,將會建立header檔的dependency tree
  5. 接著在我們要建立tool-chain的目錄中加入kernel header的聯結 
       $cd /usr/local/arm-linux 
       $mkdir include 
       $cd include 
       $ln -s /tmp/linux/include/asm-arm asm 
             $ln -s /tmp/linux/include/linux linux
  6. 到下列網站下載gccsource file及其ARM patch,在本論文採用的是gcc-2.95.2.tar.gzARM patch則是gcc-2.95.2-diff-991022.gz及:  
    下載至/tmp後將gcc source file解開並以patch檔更新: 
       $tar zxvf gcc-2.95.2.tar.gz 
       $cd gcc-2.95.2 
       $ zcat ../gcc-2.95.2-diff-991022.gz | patch -p1 -s -E 
     接著必須修改gcc-2.95.2/gcc/fold-const.c檔,以編輯器開啟後在 
    tree rhs = make_range (TREE_OPERAND (exp, 1), &in1_p, &low1, &high1); 
    tree tem; 
       與 
       /* If this is an OR operation, invert both sides; we will invert 
      again at the end. */ 
       if (or_op) 
      之間加入下列程式碼: 
       /* Fail if anything is volatile. */ 
    if (TREE_SIDE_EFFECTS (lhs) || TREE_SIDE_EFFECTS (rhs)) 
     return 0; 
      存檔後,開啟gcc-2.95.2/gcc/config/arm/t-linux檔,將 
       TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC 
       置換成 
       TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h 
     存檔後回到gcc-2.95.2/目錄下
  7. 開始設定組態,並編譯gcc 
       若要建立native compiler則下 
       $./configure --prefix=/usr/local  
       我們要建立的是 cross compiler 
       $./configure --target=arm-linux --prefix=/usr/local --disable-threads  
       設定完成後便可開始編譯,編譯完成後進行安裝 
       $make LANGUAGES="c" cross  
       $make install
Glibc
Cross compiler完成後就可以編譯一些user-space常用的函式庫,glibc就是一些基本函式庫的集合。同時由於前面在編譯gcc時有關glibc的部份我們都避開了,所以當glibc完成後我們還必須回過頭來將整個gcc再編譯一次,以得到完整的gcc cross compiler。以下就是建立glibc的步驟。 
 
  1. 從下列網站下載glibc的原始碼檔glibc-2.1.3.tar.gz及其附加(add-ons)函式庫glibc-linuxthreads-2.1.3.tar.gzglibc-crypt-2.1.tar.gz/tmp目錄中。 
  2. 切換目錄至/tmp,分別將三個檔案解開 
       $tar zxvf glibc-2.1.3.tar.gz 
       $cd glibc-2.1.3 
       $tar zxvf ../glibc-linuxthreads-2.1.3.tar.gz 
       $tar zxvf ../glibc-crypt-2.1.tar.gz 
  3. 將環境變數CC設定為cross compiler arm-linux-gcc,並進行組態設定。 
       $export CC = arm-linux-gcc 
       $./configure arm-linux --build=i586-linux  --prefix=/usr/local/arm-linux/ --enable-add-ons  
       組態完成後即可進行編譯的動作 
       $make  
       $make install
  4. 現在我們已經有了glibc函式庫,現在我們必須回頭將gcc重新編譯。首先修改gcc-2.95.2/gcc/config/arm/t-linux檔,將先前加進去的部份去掉。 
       將 
    TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h 
       置換成 
       TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC  
       存檔後回到gcc-2.95.2目錄下,重新設定組態但省略--disable-threads設定如下: 
       $./configure --target=arm-linux --prefix=/usr/local 
       完成後便可開始編譯完整的gcc cross compiler 
       $make 
       $make install
    完成上述步驟後,我們就擁有了一個完整的ARM tool-chain,完成後的gcc compiler會被安裝在/usr/local/bin中,所有ARM tool-chain均以arm-linux-為開頭。往後在使用這些工具程式時必須以下列命令來指定其路徑: 
      
    $export PATH=/usr/local/bin:$PATH  
    也可以在shell啟始描述檔中加入路徑設定,這樣每次登入後路徑就會自動設定。 
    Ps. 
    在編譯cross compiler時最後會出現下列錯誤訊息:
    In file included from iogetline.c:26:
    libioP.h:30: errno.h: No such file or directory
    In file included from iolibio.h:1,
                     
       from libioP.h:47,
                       
     from iogetline.c:26:
    libio.h:30: _G_config.h: No such file or directory
    iogetline.c:27: string.h: No such file or directory
    make[2]: *** [iogetline.o] Error 1
    make[2]: Leaving directory `/root/gcc-2.95.2/arm-linux/libio'
    make[1]: *** [all-target-libio] Error 2
    make[1]: Leaving directory `/root/gcc-2.95.2'
    make: *** [cross] Error 2

    雖然編譯中斷,但此時我們所需的cross compiler已經編譯完成,
    所以可以不管這個錯誤訊息,進行cross compiler的安裝。

Kernel 的建立
在建立了cross compiler後,我們可以接著建立ARM Linuxkernel。如前所述,我們的核心版本採用2.4.2版,在ARM Linux的討論社群上定期會有新版本的ARM patch會更新,我們必須將原始的Linux kernelARM patch更新,同時針對EDB7209的一些週邊驅動程式也有patch必須一一更新,才能編譯出可在EDB7209上執行的kernel。以下就是ARM Linux kernel的建立過程。

  1. 到下列網站下載Linux kernel - linux-2.4.2.tar.gz/tmp目錄中: 
    · ftp://ftp.uk.kernel.org/pub/linux/kernel/v2.4/ 
    /tmp建立一新目錄,將kernel解至該目錄: 
       $mkdir arm_linux 
       $cd arm_linux 
       $tar zxvf ../linux-2.4.2.tar.gz
  2. 分別到下列網站下載ARM Linux patch - patch-2.4.2-rmk1.gz EDB7209 driver patch - patch-2.4.2-rmk1-bluemug7.gz/tmp目錄下: 
    · ftp://ftp.uk.kernel.org/pub/linux/kernel/v2.4/ 
    · http://aruba.bluemug.com/~miket/arm/linux/v2.4/ 
    分別以ARM patchEDB7209 driver patch更新Linux kernel 
       $cd /tmp/arm_linux/linux 
       $zcat ../patch-2.4.2-rmk1.gz | patch -p1 -s -E 
       $cat ../patch-2.4.2-rmk1-bluemug7.gz | patch -p1 -s -E 
  3.   完成核心的更新後便可以開始進行核心的建立。現在我們要進行的是核心的組態設定,這個步驟可以讓我們設定硬體平台架構,CPU型態等,以及一些週邊的支援情形的設定,是整個建立核心過程的一個重點。在這裡Linux提供了兩種設定的方式,分別是make configmake menuconfig。兩種的差異在於使用介面的不同,make config是單純文字敘述且若設定錯誤則必須重頭來過,make menuconfig則提供了一個選單的介面讓使用者可以勾選要設定的項目在這裡我們用make menuconfig來設定組態,這裡要注意在系統的搜尋路徑中必須包含cross compiler所在的路徑: 
    $cd /tmp/arm_linux/linux 
    $make menuconfig
 
首先,Code maturity level options選項,選擇Prompt for development and/or incomplete code/drivers
Loadable module support,不勾選。System Type,先進入ARM system type選項,選CLPS711X/EP721X-based
接著回到上一層選CLPS711X/EP721X Implementations
CLPS711X/EP721X Implementations裡還有子選項,選擇EDB7211。在這裡可以看到有一個選項EDB7211 Boot Mode,這個選項是在選擇kernel的開機模式,這部份在實作Ramdisk時將會說明,在此不勾選。
回主選單,General setup,勾選:Networking supportSystem V IPCSysctl supportNWFPE math emulationKernel support for ELF binaries
回主選單,Parallel port support,不勾選。 
   Memory Technology Devices (MTD),不勾選。 
   Plug and Play configuration,不勾選。 
 Block devices部份,勾選RAM disk supportInitial RAM disk (initrd) support。同時更改Default RAM disk size參數為8192.
回主選單,Multi-device support (RAID and LVM),不勾選。 
為了讓kernel支援網路功能,Networking options部份,勾選Unix domain socketsTCP/IP networking其餘不選.
Network device support部份,我們必須根據我們的硬體平台選擇驅動程式,在EDB7209上內建了乙太網路介面,其所使用的晶片組為CS8900。勾選Network device support並進入Ethernet (10 or 100Mbit)子選單,接著勾選EISA, VLB, PCI and on board controllers,此時會出現子選項,勾選CS89x0 support. 
回主選單,Amateur Radio support,不勾選。 
   IrDA (infrared) support,不勾選。 
   ATA/IDE/MFM/RLL support,不勾選。 
   SCSI support,不勾選。 
   Synchronous Serial Interfac,不勾選。 
   I2O device support,不勾選。 
   ISDN subsystem,不勾選。 
   Input core support,不勾選。 
   Character devices部份,分別勾選Virtual terminalSupport for console on virtual terminalCLPS711X serial port supportSupport for console on CLPS711X serial portUnix98 PTY supportEnhanced Real Time Clock Support其餘不勾選。在這裡我們選擇了字元裝置裡的序列埠支援。
回主選單,Multimedia devices,不勾選。 
 File systems部份,勾選Simple RAM-based file system support/proc file system supportSecond extended fs support。我們的kernel必須支援Ext2 file system,因為我們的RAM disk將以Ext2的格式建立。 Console drivers部份,勾選Support Frame buffer devicesSupport for console on virtual terminal.
  接著進入Frame-buffer support子選單,勾選Support for frame buffer devices (EXPERIMENTAL)、EP7211 LCD support、Advanced low level driver optionsMonochrome support、2 bpp packed pixels support、4 bpp packed pixels support
回主選單,USB support,不勾選。 
Kernel hacking部份,勾選Compile kernel without frame pointerVerbose kernel error messagesVerbose user fault messagesKernel low-level debugging functions.
  設定完成後回主選單,並選Exit便可存檔並離開組態設定。
4.   進入include/asm/arch-ep7211/目錄,編輯hardware.h檔,將 
   #ifdef CONFIG_EP7211_JUMPERED_BOOT 
#define  IO_EXTKBD_START 0x40000000 /* physical */ 
#else 
#define  IO_EXTKBD_START 0x30000000 /* physical */ 
#endif 
   改成 
   #ifdef CONFIG_EP7211_JUMPERED_BOOT 
#define  IO_EXTKBD_START 0x40010000 /* physical */ 
#else 
#define  IO_EXTKBD_START 0x30010000 /* physical */ 
#endif  
   這樣在編譯完核心後,鍵盤才可以正常動作,原先的版本是7211板子的設定,而我們採用的是EDB7209,其設定必須採用後者。
5.    組態設定完成後接下來就可以開始編譯,步驟如下: 
   $make dep 
   $make Image  
   make dep的作用在幫我們檢查引用的標頭檔是否在正確的位置,檢查完畢就可開始正式編譯核心,若沒有錯誤的話make Image會在arch/arm/boot/目錄下產生一個Image檔,這就是我們所需要的核心檔,接下來將它壓縮: 
   $gzip Image  
   我們將會用Hermit downloader程式將Image.gz下載至EDB7209板中。
6.    在Step3我們在System Type選項中沒有勾選EDB7211 Boot Mode,現在重新進入組態選單並勾選EDB7211 Boot Mode,存檔後重新編譯核心: 
   $make dep 
   $make Image  
   完成後同樣在arch/arm/boot目錄下會產生Image檔,但不須將其壓縮,將其更名為Image_boot以茲區別。此Image_boot檔是以Shoehorn downloader下載至EDB7209

Initial ramdisk 建立

在建立了ARM Linux kernel後,我們還需要一個檔案系統來當系統的root device。如前所述,由於EDB7209並不支援磁碟機,所以我們的檔案系統只能利用板子上的記憶體來虛擬成磁碟機,也就是ramdisk。這一節將詳細說明如何建立此一檔案系統,以及這個檔案系統需要具備哪些必要的檔案以便開機時可以用到。以下是建立的步驟:
  1. 首先我們必須有一個裝置來存放我們要建立的檔案系統,這裡我們採用系統的ramdisk來儲存,不過必須確定系統的記憶體足夠。以下命令會在/dev/ram0建立一個Ext2格式的檔案系統: 
       $mke2fs -m 0 -i 2000 /dev/ram0  
       此命令會在/dev/ram0裝置上建立Ext2格式的檔案系統,同時設定其inode數為2000個,而此檔案系統的大小則會依Linux kernel的預設值來決定,我們的Linux 發展平台所產生出來的檔案系統可達8192Kbytes
  2. 接下來要將此裝置掛載(mount)至系統中: 
       $mount /dev/ram0 /mnt  
       此時/dev/ram0相當於系統中的一個目錄,如此以來我們可以進入/mnt目錄中準備我們的檔案系統。
  3. Linux的檔案系統中,有幾個目錄是必須存在的,分別是: 
    • /dev -- 裡面存放裝置檔 (Devices) ,為達成 I/O 工作所需  
    • /proc -- 存放一些系統的資訊,必須支援/proc 檔案系統 
    • /etc -- 裡面存放系統組態設定檔  
    • /sbin  -- 重要的系統執行檔 
    • /bin  -- 一些系統工具程式的存放目錄,如:lscd  
    • /lib  -- 提供 run-time 支援的共享函式庫  
    • /mnt  -- 維護其它磁碟所用的磁碟掛入點 (mount point)  
    • /usr  -- 額外的工具程式與應用程式 
    使用mkdir指令在/mnt目錄下建立上述目錄。
  4. 進入dev目錄,我們必須建立一些裝置檔以便讓一些週邊裝置或是系統裝置能夠被正常使用,其中有一些裝置檔可以從Linux平台上取得: 
       $cd /mnt/dev 
    $cp -dpR /dev/console ./ 
       $cp -dpR /dev/kmem ./ 
       $cp -dpR /dev/mem ./ 
       $cp -dpR /dev/null ./ 
       $cp -dpR /dev/ram0 ./ 
       $cp -dpR /dev/tty0 ./ 
       $cp -dpR /dev/tty1 ./ 
       $cp -dpR /dev/initrd ./    
       另外序列埠裝置檔必須手動加入,而此動作必須知道此裝置的主要代碼與此要代碼,這一部份由前節所述的driver patch可查到:
       $mknod ttyS0 c 204 16 
       $mknod ttyS1 c 204 17
      
       在這裡序列埠裝置的主要代碼為204,次要代碼分別為1617
  5. 接著進入etc目錄,我們必須準備一些設定檔在這個目錄中以便讓Linux順利開機,有幾個檔案是必備的:inittabfstab、以及rc.d/目錄下的檔案。這些可以從系統的/etc目錄下取得,並做適當的修改即可: 
       $cd /mnt/etc 
    $cp /etc/inittab ./ 
       $cp /etc/fstab ./ 
       $cp -r /etc/rc.d ./  
       inittab檔案是在描述傳遞給系統第一個程序(init)的參數,inittab檔至少須包含下列參數:  
        id:2:initdefault: 
     告訴init進入runlevel 2,以下是Linux中定義的runlevel 
      0 - halt (Do NOT set initdefault to this) 
      1 - Single user mode 
     2 - Multiuser, without NFS (The same as 3, if you do not have networking) 
     3 - Full multiuser mode 
     4 - unused 
      5 - X11 
     6 - reboot (Do NOT set initdefault to this) 
      si::sysinit:/etc/rc.d/rc.sysinit 
       此行定義了系統一開始要執行的script檔,在此設定的是/etc/rc.d裡的rc.sysinit script檔。 
    1:12345:respawn:/bin/getty tty1 9600 vt100 
       此行定義了允許使用者可以以vt100的終端機模式在tty19600的速率登入。 
        fstab檔則定義了系統開機時須要自動掛載(mount)哪些檔案系統,此檔至少須有下列描述: 
    /dev/ram0 / ext2 defaults
    
    /proc /proc proc defaults
    
      rc.d/rc.sysinit檔則可視需求增減原來的內容。
  6. binusr/binusr/sbinsbin目錄中的系統程式或應用程式則視需求至網路上下載程式的原始碼檔,並以cross compiler編譯即可在ARM Linux中執行。在此採用另一種解決方案,專為嵌入式系統而設計的Busybox。所謂的Busybox乃是將一些常用的Unix指令及小程式適當的刪減其功能並整合在一個執行檔Busybox中,這麼做的原因是因為在大部份嵌入式系統通常不具備很大的記憶體,因此ramdisk也不能太大,而為了在有限的資源下能使用大部份的Unix指令及常用的小程式,有一群人開始試著將這些程式刪減整合成單一執行檔,稱為Busybox。通常Busybox所提供的指令會比原本的指令在功能上稍微有所不同,主要是因為空間的考量。以下將說明Busybox的建立過程: 
       至下列網站下載Busybox原始碼檔busy-0.46.tar.gz/tmp目錄中 
    解開busy-0.46.tar.gz,並進行組態設定: 
    $cd /tmp 
       $tar zxvf busy-0.46.tar.gz  
       Busybox可以選擇要編譯哪些程式進入busybox中,進入busybox目錄中,編輯busybox.def.h檔,即可選擇欲加入的應用程式。 
       以cross compiler編譯busybox 
       $make  
       編輯Makefile檔,設定PREFIX/mnt 
       $make install
        如此busybox將會被安裝到我們新建的檔案系統的bin目錄中,並且會建立一些連結(links)busybox,這是因為若要使用busybox中的應用程式有兩種方法,一種是: 
       $/bin/busybox ls  
       另一種方法是建立一個連結: 
       $ln –sf /bin/busybox ls 
       $ls  
       當我們執行make install時,會在相對應的目錄內產生這些應用程式的連結。到了這裡我們的Busybox算是完成了。
  7. 接下來我們進入lib目錄,此目錄必須存放應用程式執行所需要的共享函式庫及載入函式庫,有時我們可能不清楚某個程式到底用到了哪些函式庫,這時可以用ldd指令來檢查。
    libc-2.1.3.sold-2.1.3.so,是大部份程式都需要的函式庫,我們必須在lib目錄中加入: 
       $cd /mnt/lib 
       $cp /usr/local/arm-linux/lib/libc-2.1.3.so ./ 
       $cp /usr/local/arm-linux/lib/ld-2.1.3.so ./  
       在lib目錄中除了要存放函式庫本身之外,通常應用程式是以連結的方式來使用這些函式庫,所以我們除了將函式庫本身複製到lib目錄外還需為每一個函式庫建立相對應的連結: 
       $cd /mnt 
       $chroot /mnt /sbin/ldconfig  
       上述命令主要是透過ldconfig來完成函式庫的設定更新。ldconfig會在/mnt/etc中產生一個ld.so.cache的檔案,這個檔案是用來告訴loader去哪裡找函式庫,同時ldconfig也會為每個函式建立相對應的連結。
  8. 完成了所有必備檔案的準備後,接下來要進行的是將整個檔案系統轉換為單一檔案以便讓我們使用downloader下載到EDB7209板子中。 
       $cd tmp 
       $dd if=/dev/ram0 of=./ramdisk bs=1k count=4000  
       在上述命令中,dd指令可以將/mnt目錄中的所有檔案轉成單一檔案ramdisk,選項bs指的是block size,在這裡定為1kbytes。而count則是設定所欲轉換的大小,在這裡可以視實際使用的大小來定,使用df指令可以看到/dev/ram0的總容量及其目前使用量。    
       到這裡為止我們以經建立好一個可以讓downloader下載到EDB7209板子上的initial ramdisk 了。

Downloader 的建立

最後,我們需要一個下載的工具。由於EDB7209並不支援磁碟機,所以若是要讓EDB7209能夠像一般的Linux系統一樣開機的話,不管是kernel或是ramdisk都必須事先燒錄在EDB7209onboard flash中。本節將介紹兩種downloaderShoehorn以及Hermit。兩者的不同點在於Shoehorn是將kernelramdisk下載至EDB7209onboard DRAM中。當EDB7209電源關閉時,儲存在DRAM中的kernelramdisk將會消失,下一次必須再從主電腦下載一次,Hermit是將kernelramdisk燒錄至EDB7209FLASH中,當開機時再從FLASH中載入DRAM。當電源切斷時,FLASH中的資料並不會消失,所以當電源恢復後還是可以重FLASH中將kernleramdisk載入DRAM而重新開機。 
EDB7209有兩種開機模式,在EDB7209板上JP2是用來選擇這兩種模式的接點。當JP2短路時,EDB7209進入Jumpered Boot Mode,系統會從EP7212 ARM chipon-chip Boot ROM開始執行,由圖所示,此模式下on-chip Boot ROM被定址到0x0000:0000的位址,所以程式會從此開始執行。在on-chip Boot ROM中的程式是CPU出廠時就燒錄在裡面,這一小段程式的主要功用是透過UARThost computer相連,並且讓我們能傳輸程式至on-chip SRAM中。這個功能對downloader來說非常重要,因為這樣我們才能將downloader的目的端程式下載到on-chip SRAM中,Shoehorn downloader就是工作在這個模式下。
當我們讓JP2斷路,並開啟電源,此時EDB7209將進入External Boot Mode 
CPU 將會從外部FLASH開始提取指令,如圖4.20所示,在External Boot Mode時外部FLASH是被從0x0000:0000開始定址,而on-chip Boot ROM則被定址到0x7000:0000。所以若是我們將kernel的映像檔燒錄到FLASH中,且讓JP22斷路,則在開機後kernel將會被從 FLASH中載入進行開機。 Hermit downloader必須利用到兩種開機模式來將kernelramdisk燒錄到FLASH中,以下將分別說明ShoehornHermit的原理及其建立程序。
Shoehorn downloader建立
編譯完成的Shoehorn可以得到兩個獨立的程式,分別是在Host端執行的shoehorn以及在target(EDB7209)執行的loader.bin。如前所述,Shoehorn downloader是工作在EDB7209Jumpered Boot Mode下,當我們在Host端執行shoehorn時,shoehorn首先會將loader.bin載入EP7212on-chip SRAM中,接著系統的PC(program counter)會被指到SRAM的起始位址並開始執行loader.bin 
而在Host端的shoehorn會開始跟loader.bin建立傳輸管道(透過serial port)然後將kernelramdisk下載到EDB7209DRAM中,其過程如圖4.21所示。另外,若使用Shoehorn下載kernel則在編譯kernel時必須勾選EDB7211 Boot Mode選項,這是因為EDB7209在不同的開機模式下其keyboardEthernetI/O address會有不同的映對位址,所以若沒有根據所使用的開機模式編譯kernel的話,鍵盤及網路可能將失去作用。以下將詳細介紹Shoehorn的建立過程。 
  1. 到下列網站下載Shoehorn原始碼檔,目前Shoehorn最新版為3.4版適用於Linux kernel 2.4.2版本,但亦可向下相容,若是Shoehorn 3.1版則無法適用於2.4.2版的kernel 
    shoehorn-3.4.tar.gz下載至/tmp目錄下。
  2. Shoehorn原始碼檔解開: 
     $tar zxvf shoehorn-3.4.tar.gz 
  3. 開始編譯Shoehorn,必須注意的是,系統的搜尋路徑必須包含cross compiler所在的路徑。 
     $make  
       編譯完成後在shoehorn-3.4/目錄下會出現shoehornloader.bin兩個檔案,如此Shoehorn的建立便完成。
  Hermit downloader建立
如同Shoehorn一樣,建立完成的Hermit downloader也是分為Host端(hermit)與target(loader.boot.binloader.flash.bin)兩部份的程式。如前所述Hermit downloader分別工作在EDB7209的兩種開機模式下,但Hermit必須依賴Shoehorn downloader才能順利運作。首先在Jumpered Boot ModeShoehorn downloaderloader.boot.bin下載至EDB7209DRAM中並開始執行,接著以hermitloader.boot.bin連線將loader.flash.bin下載至EDB7209 FLASHBoot Sector中.
  1. 至下列網站下載Hermit原始程式碼hermit-1.1.tar.gz/tmp目錄下: 
    將其解開: 
     $cd /tmp 
     $tar zxvf hermit-1.1.tar.gz
  2. 如前所述,我們必須修改Hermit downloader的原始碼,而Hermit原始碼分hosttarget兩部份,我們所要修改的是target端的程式,修改完的程式經編譯後會成為loader.flash.bin檔,它便可以將kernelramdiskFLASH中載入至DRAM中。 
       進入/tmp/hermit-1.1/src/target/epp7211目錄,編輯linux.c
       在linux.c檔前面加入以下定義: 
     #define INITRD_SIZE 4096 
    #define INITRD_START DRAM2_START 
       上述定義中,INITRD_SIZE定義的是我們的initial ramdisk的大小,以1kbytes為單位,在本論文中initial ramdisk大小是4000kbytes。而INITRD_START定義的是initial ramdisk被載入DRAM後的起始位址,也就是0xC100:0000  
       另外在函式linux_cmdfunc中加入下列宣告: 
     unsigned char *dramptr; 
    unsigned char *flashptr; 
    unsigned rdsize;  
    dramptr = (unsigned char *) DRAM2_START; 
    flashptr = (unsigned char *) 0x003E8000;  
       上面宣告了兩個指標,其中dramptrinitial ramdiskDRAM中的起始位址,而flashptr則是initial ramdisk被燒錄在FLASH中的起始位址。    
    linux_cmdfunc函式中有以下程式: 
     /* initialize param block */  
     /* system page size */ 
     ps->u1.s.page_size = 0x1000; 
     /* number of pages in all banks */ 
     ps->u1.s.nr_pages = 4096; 
     /* param flags */ 
     ps->u1.s.flags = FLAG_READONLY | FLAG_RDLOAD; 
     /* default root device is currently ramdisk; XXX should be flash */ 
     ps->u1.s.rootdev = MKDEV(RAMDISK_MAJOR, 0); 
      /* pages per bank */ 
     ps->u1.s.pages_in_bank[0] = 2048; 
     ps->u1.s.pages_in_bank[1] = 2048;  
       這段程式的功用是在設定Linux kernel的參數,這些都是kernel的起始參數,主要是設定硬體的參數,我們必須加入下列參數: 
     ps->u1.s.initrd_start = INITRD_START; 
     ps->u1.s.initrd_size = 4096000; 
     ps->u1.s.ramdisk_size = INITRD_SIZE;  
       我們所加入的參數主要是設定系統的initial ramdisk起始位址(initrd_start)initial ramdisk的大小(initrd_size,以byte為單位)以及ramdisk大小(ramdisk_size,以kbytes為單位,與initial ramdisk大小相同)  
       接下來在 
     /* decompress kernel image to DRAM */ 
     gunzip_kernel();  
       的下面加入以下程式: 
     for(rdsize=0;rdsize < 4096000;rdsize++) 
      
     *dramptr = *flashptr; 
     dramptr++; 
     flashptr++; 
     }  
       加入這段程式的目的是為了在將kernelFLASH中載入DRAM後繼續將initial ramdisk載入。  
       存檔後,繼續編輯keyboard.c檔: 
      
     #ifdef BOOTMODE 
    #define EXT_KBD_ADDR 0x40000000 
    #else 
    #define EXT_KBD_ADDR 0x30000000 
    #endif  
       修改成 
     #ifdef BOOTMODE 
    #define EXT_KBD_ADDR 0x40010000 
    #else 
    #define EXT_KBD_ADDR 0x30010000 
    #endif  
       如同我們在kernel中的修改一樣,這麼做的原因是讓鍵盤能正常動作。
  3. 將程式修改完成後回到Hermit主目錄下,開始編譯程式。Hermit在編譯時分成兩部份,首先是編譯出loader.boot.bin 
     $cd /tmp/hermit-1.1 
     $make BOOTMODE=bootstrap  
       編譯完成後在src/target/ep7211目錄中會出現loader.bin檔,我們將其更名為loader.boot.bin,並將其搬移到Hermit主目錄下: 
     $mv src/target/ep7211/loader.bin ./loader.boot.bin
  4. 接著要編譯出loader.flash.bin 
     $make scrub 
     $make  
       同樣的,編譯完成後在src/target/ep7211目錄下會產生loader.bin檔,此檔與前面的loader.bin不同,它將會在FLASH中執行,所以我們將其更名為loader.flash.bin,並搬移到Hermit主目錄下,同時也將hermit主程式搬移到Hermit主目錄下: 
     $mv src/target/ep7211/loader.bin ./loader.flash.bin 
     $mv src/host/common/hermit ./  
     Hermit downloader建立完成。
ARM Linux kernelInitial ramdisk下載

在這裡我們將說明如何利用downloader(Shoehorn or Hermit)kernelinitial ramdisk下載至EDB7209中。在整個系統的發展過程中,由於必需重覆的下載kernelinitial ramdisk,所以採用Shoehorn downloader是不錯的選擇。如前節所述,Shoehorn downloader是將kernelinitial ramdisk下載至EDB7209DRAM中,唯一的缺點就是無法長久保存資料。而當我們的系統發展到一定階段後,為了達到嵌入式的目標,就必須讓kernelinitial ramdisk長存在硬體平台中,這時就要採用Hermit downloader,讓kernelinitial ramdisk可以儲存在FLASH中。下面將分別說明兩種downloader的下載過程。
  Shoehorn downloader下載流程
在使用Shoehorn downloader下載kernel之前必須先確認kernel的設定,如前所述,在System type選項中的EDB7211 Boot Mode一定要勾選。
  1. Host端電腦與EDB7209(UART1)null modem cable連接,而EDB7209另外有ethernet介面可視需求使用。將EDB7209板上的JP2短路,開啟EDB7209電源,進入Jumperred Boot Mode 
  2. 進入Shoehorn主目錄輸入以下命令下載:
    $./shoehorn --edb7211 --initrd ../ramdisk --ethernet –terminal --kernel ../arm_linux/linux/arch/arm/boot/Image_boot
    其中edb7211是用來指定硬體平台,ethernet選項則是指定採用Ethernet傳輸下載kernelinitial ramdiskinitrd指定initial ramdisk的檔名,預設是initrdkernel選項是用來指定欲下載的核心檔名,預設為Imageloader選項則是指定欲下載至EDB7209 on-chip SRAMloader檔名,預設為loader.binTerminal參數則是要求Shoehorn在下載完成後進入終端機模式,以便登入ARM Linux
    執行後,Shoekorn會等待EDB7209 wakeup,此時必須依序按下EDB7209板上的Reset按鈕及Wakeup按鈕,如此Shoehorn將自動開始下載。 
            在這裡我們採用乙太網路的方式來下載kernelinitial ramdisk,其速度將比採用序列埠傳輸快,但即使如此仍然須要利用序列埠來下載loader.bin,所以序列埠的連線一定要接上。當下載完成,若kernel編譯正確,且initial ramdisk內容完整,則此時EDB7209LCD顯示幕便會出現開機畫面,且Host端亦會出現Linux的提示符號,表示以開機完成。
  Hermit downloader下載流程
如前所述,Hermit必須依靠Shoehorn的幫助才能順利將kernelinitial ramdisk下載至EDB7209FLASH中。另外,在使用Hermit下載kernel之前必須確定在編譯kernel時,EDB7211 Boot Mode選項不可勾選,並且在核心編譯完成後必須將Imagegzip壓縮。
  1. Hermittarget端共有兩個程式分別是loader.bootloader.flash.bin。首先我們使用Shoehornloader.boot.bin下載到EDB7209DRAM中,依照前述Shoehorn下載步驟,參數更改如下: 
 $cd /tmp/shoehorn --edb7211 --kernel=../hermit-1.1/loader.boot.bin --initrd /etc/motd --terminal
上述命令除了在kernel選項指定為我們所要下載的loader.boot.bin外,initrd的部份則任意指定一個檔案即可,下載完成後若出現Hermit提示符號則表是loader.boot.bin以開始執行。按Ctrl + c離開終端機模式。
2.進入Hermit主目錄,此時EDB7209上執行著loader.boot.bin,此時我們開始使用hermitloader.boot.bin連線,並將loader.flash.bin下載到FLASH中:
 $./hermit download --force-locked --input-file ./loader.flash.bin --region flash-1 
   此命令是告訴Hermitloader.flash.bin下載至第一個FLASH區塊,並將此區塊設定為強制鎖定狀態(force locked)以避免此區塊被重複寫入。
3.成功將loader.flash.bin下載至FLASH後,接下來將EDB7209電源關閉,將JP2開路,重新開啟電源。按下EDB7209板子上的Reset按鈕,接著按住EDB7209鍵盤上的任意鍵不放,同時按一下EDB7209板子上的Wakeup按鈕,直到板子上的LED亮起才可放開鍵盤。如此做的原因是,loader.flash.bin開始執行時會先掃描鍵盤,當鍵盤上沒有任何鍵被按下時,它就會將FLASH中的kernel載入DRAM中執行。由於目前尚無kernel存在FLASH中,所以我們必須按住EDB7209的鍵盤任意鍵,讓loader.flash.bin繼續執行。我可以用以下命令確認loader.flash.bin是否正確執行
 $./hermit termial
若出現Hermit提示符號則表示正確。接下來我們就可以利用Hermitloader.flash.bin連線來將kernelinitial ramdisk下載至FALSH 
 $./hermit download --input-file ../arm_linux/linux/arch/arm/boot/Image.gz \ 
 --address 0x10000 --ethernet --remote-mac 12:34:56:78:9a:bc 
 上述命令會將Image.gz檔以乙太網路傳輸至EDB7209,並FLASH0x10000位址開始寫入。之所以從0x10000開始寫入是因為要避開前面的loader.flash.bin,以免重疊。而Hermit使用乙太網路傳輸必須指定EDB7209MAC address,在此只須輸入任意位址即可。
4. kernel下載成功後接下來就是initial ramdisk的下載: 
 $./hermit download --input-file ../ramdisk --address 0x003E8000 --ethernet \ 
--remote-mac 12:34:56:78:9a:bc 
   如同下載kernel的步驟,將input-file參數改為ramdisk,而位址亦需跳過kernel的所在位址,從0x003E8000開始寫入,這個位址也已經被我們寫死在loader.flash.bin程式碼中。
5. initial ramdisk下載完成後,按下EDB7209板子上的Reset按鈕,讓系統重置,接著按下Wakeup按鈕,此時以不用再按住EDB7209的鍵盤,讓loader.flash.binkernelinitial ramdsik載入DRAM並開始執行kernelkernel編譯正確,且initial ramdisk內容完整,則不久後即可在EDB7209LCD顯示幕上看到開機訊息。