在嵌入式系統開發中,經常需要從主機上傳送映像、文件等到目標機上。實現的方法有很多。如tftp,scp等。
TFTP(Trivial File Transfer Protocol)是用來下載遠程文件的最簡單的網絡協議,它基於UDP協議而實現。
一、TFTP的建立
嵌入式linux的tftp開發環境包括兩個方面:一是linux服務器端的tftp-server支持,二是嵌入式目標系統的tftp-client支持。因為u-boot本身內置支持tftp-client,所以嵌入式目標系統端就不用配置了。我們要做的是在服務器端(即主機)上安裝TFTP服務,並且正確地配置TFTP服務的路徑和參數。
下面我嘗試了搭建TFTP的方法,實測成功。
首先需要安裝:tftp-hpa
sudoapt-get install tftp-hpa
sudoapt-get install tftpd-hpa
tftp-hpa是客戶端,作用是從別人的TFTP服務器端上傳/下載東西。
tftpd-hpa是服務端,字母d代表daemon,作用是為別人提供TFTP服務,供別人上傳/下載東西。
2、創建TFTP目錄
首先需要建立一個TFTP目錄,以供上傳和下載。當然也可以使用現有的目錄。然后需要設定該目錄的權限,決定是否能夠下載和上傳文件。對於日常使用,我們一般就將其權限設置為最高,為所有用戶組都添加所有權限(讀+寫+執行=4+2+1=7):
sudomkdir ~/tftp_boot
sudochmod 777 tftp_boot –R
我們的TFTP目錄為/home/ghostar/tftp_boot,其權限已經是最高。
3、修改配置文件
修改tftpd-hpa相應的配置文件
sudogedit /etc/default/tftpd-hpa
原始的內容如下:
#/etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_ADDRESS="[...]:69"
TFTP_OPTIONS="--secure"
我將其修改為:
#/etc/default/tftpd-hpa
TFTP_USERNAME="ghostar"
TFTP_DIRECTORY="/home/ghostar/tftp_boot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l-c -s"
說明:
TFTP_USERNAME:必須改為當前的用戶名,或者root;
TFTP_DIRECTORY:我們設定的TFTP根目錄;
TFTP_OPTIONS:TFTP啟動參數。意義如下:
-l:以standalone/listen模式啟動TFTP服務,而不是從inetd啟動。
(這里也表明,再像前面一樣裝xinetd,其實是多此一舉)
-c:可創建新文件。默認情況下,TFTP只允許覆蓋原有文件,不能創建新文件。
-s:改變TFTP啟動的根目錄。加了-s后,客戶端使用TFTP時,不再需要輸入指定目錄,填寫文件的完整路徑,而是使用配置文件中寫好的目錄。這樣也可以增加安全性。
我一開始沒有注意TFTP_USERNAME這一項,隨便取了一個名字,一直沒有成功,后來改用自己的用戶名,才測試成功。
4、重新啟動服務
重啟tftpd-hpa服務:
sudo service tftpd-hpa restart
如果顯示如下,說明配置正確:
tftpd-hpastart/running, process 2290
之前我沒有把TFTP_USERNAME該為用戶名,而是隨便取了一個,則會提示如下:
tftpd-hpastart/running
對比發現,這里並沒有啟動進程,因為配置中TFTP_USERNAME不正確,也就沒有成功開啟TFTP。
5、確認tftp服務是否已經開啟
下面確認tftp服務是否開啟。
查看tftp相關進程可以用以下指令:
psaux |grep tftp
彈出以下信息
ghostar@ubuntu:~$ ps aux|grep tftp
root 3151 0.0 0.0 15128 152 ? Ss 23:19 0:00 /usr/sbin/in.tftpd --listen --user ghostar --address 0.0.0.0:69 -l -c -s /home/ghostar/tftp_boot
ghostar 3156 0.0 0.0 15956 956 pts/12 S+ 23:20 0:00 grep --color=auto tftp
可以看到, /usr/sbin/in.tftpd已經啟動,說明TFTP服務已經開啟了,進程號正是3151。
--listen對應配置文件中的參數 -l
--user ghostar 就是配置文件中的TFTP_USERNAME
/home/ghostar/tftp_boot是配置文件中的TFTP_DIRECTORY
另一種方法:
netstat-a|grep tftp
如果看到如下提示,說明TFTP服務開啟了。
udp 0 0 *:tftp *:*
二、TFTP的使用
1、連接本機
連接本機有三種方法,一是輸入真實的IP地址,可以用ifconfig查得;二是用localhost來代表本機;三是使用地址127.0.0.1,這個IP地址始終代表本機的IP。
先在TFTP目錄下新建一個文件a,在里面隨便寫一些內容,然后修改其權限為777。接着,輸入以下指令的任意一條,進入TFTP命令行。
tftp 192.168.1.201 (自己設定的IP)
tftp localhost
tftp127.0.0.1
TFTP命令行的基本指令:
put:將文件上傳到TFTP目錄
get:取得TFTP目錄上的文件
quit/q:退出TFTP
因為TFTP服務將某一設定的目錄視為根目錄,因此不需要打出完整的路徑。既然該目錄下已經有一個文件a,我們就下面輸入指令:
tftp>get a
tftp>put a
如果沒有任何提示,則說明傳輸成功。
下面看看當配置參數和文件權限改變時,會出現什么現象。我列舉了一些常見問題:
tftp>get a
Transfer timed out.
原因:tftpd服務沒有啟動。
需要注意的是,必須使TFTP的用戶名和當前的系統的用戶名一致,否則就無法成功啟動tftpd服務。
tftp>get a
permission denied
原因:操作者權限不夠,比如當前的目錄是/etc,不能隨便get文件下來。需要提升權限。切換到root賬戶,或者直接執行sudo tftp。
tftp>put t1
tftp: t1: No such file or directory
原因:當前目錄下沒有t1文件
tftp>get d
Error code 1: File not found
原因:TFTP根目錄下沒有該文件
Error code 2: Only absolute filenamesallowed
原因:TFTP啟動配置參數沒有-s,或者在DIRECTORY中沒有填寫目錄
tftp>put b
Error code 1: File not found
原因:啟動配置參數無-c,根目錄下無同名文件
(注意和前面情況的區別,不是當前目錄下沒有b文件,而是TFTP目錄下找不到同名文件b)
tftp>put b
Error code 2: File must have global writepermissions
原因:根目錄下有同名文件,該文件無寫權限(啟動配置參數有無-c都這樣)
經測試,在tftp-hpa方法下,下列情況可以put成功:
l 啟動配置參數無-c,根目錄下有同名文件,有寫權限
l 啟動配置參數有-c,根目錄下無同名文件
l 啟動配置參數有-c,根目錄下有同名文件,有寫權限