<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Uboot在S3C2440上的移植詳解(六)

          Uboot在S3C2440上的移植詳解(六)

          作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
          一、移植環(huán)境

          二、移植步驟

          10)u-boot利用tftp服務(wù)下載內(nèi)核和利用nfs服務(wù)掛載nfs文件系統(tǒng)。
          知識(shí)點(diǎn):
          1. tftp服務(wù)的安裝與配置及測(cè)試;

          2. nfs服務(wù)的安裝與配置及測(cè)試;

          3. u-boot到kernel的參數(shù)傳遞(重點(diǎn))。

          我們知道使用tftp下載內(nèi)核和使用nfs掛載文件系統(tǒng)的好處是,當(dāng)我們重新編譯內(nèi)核或文件系統(tǒng)后不用重新把這些鏡像文件再燒錄到flash上,而是把這些鏡像文件放到開發(fā)主機(jī)的tftp或nfs服務(wù)的主目錄下,通過網(wǎng)絡(luò)來加載他們,不用頻繁的往flash上燒,這樣一可以保護(hù)flash的使用壽命,二可以方便的調(diào)試內(nèi)核或文件系統(tǒng),提高開發(fā)效率??梢?,讓u-boot實(shí)現(xiàn)這個(gè)功能是一件很有意義的事情。

          實(shí)現(xiàn)這樣的功能很簡單,網(wǎng)上也有很多資料。但有很多細(xì)節(jié)的東西如果稍不注意就導(dǎo)致失敗,這里就結(jié)合本人實(shí)現(xiàn)的過程進(jìn)行講述和一些問題的分析。

          • tftp服務(wù)的安裝與配置及測(cè)試

          要使用tftp服務(wù)及測(cè)試它要安裝兩個(gè)軟件包,一個(gè)就是tftp服務(wù)器,另外一個(gè)就是tftp客戶端,這里安裝客戶端只是用于在主機(jī)本地測(cè)試tftp服務(wù)器是否正常運(yùn)行的,來確保u-boot能夠訪問tftp服務(wù)(u-boot中已有tftp客戶端的功能,其實(shí)在前面幾篇中都已經(jīng)使用了tftp下載內(nèi)核或文件系統(tǒng)到開發(fā)板上,如果那里都做到了,這里就可以直接跳過)。

          首先使用rpm命令查看你的主機(jī)上是否已經(jīng)安裝了tftp服務(wù)器和客戶端,如果沒有安裝就去下載這兩個(gè)軟件包進(jìn)行安裝或者可以使用yum命令進(jìn)行在線安裝,yum會(huì)自動(dòng)的去搜索適合你主機(jī)平臺(tái)的最新軟件包進(jìn)行下載安裝,如果主機(jī)已經(jīng)安裝了,則會(huì)提示軟件包已經(jīng)安裝了最新的版本。如下圖所示:

          配置tftp服務(wù)器,主要是配置tftp的主目錄及訪問權(quán)限。因tftp服務(wù)依賴于xinetd服務(wù),所以一般tftp服務(wù)安裝好后其配置文件一般會(huì)在/etc/xinetd.d/目錄下:

          • nfs服務(wù)的安裝與配置及測(cè)試

          以root的身份在控制臺(tái)輸入setup,在系統(tǒng)服務(wù)選項(xiàng)中選中nfs服務(wù),如下圖:

          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/1032542.png" style="padding:0px;margin:0px;border:0px;" />

          配置NFS服務(wù)器的共享主目錄,也要注意權(quán)限問題:

          • u-boot到kernel的參數(shù)傳遞

          我們知道,在kernel配置選項(xiàng)Boot options中有一個(gè)Default kernel command string參數(shù)項(xiàng),而在u-boot參數(shù)中也有一個(gè)bootargs參數(shù)項(xiàng),他們都是供內(nèi)核啟動(dòng)用的,那他們又有什么區(qū)別呢,內(nèi)核啟動(dòng)時(shí)到底是用哪一個(gè)呢?兩種參數(shù)項(xiàng)分別如下圖所示(kernel中的參數(shù)指定是從開發(fā)板Flash分區(qū)上掛載文件系統(tǒng),u-boot中的參數(shù)指定的是從NFS掛載文件系統(tǒng)):

          實(shí)際上,內(nèi)核中的參數(shù)項(xiàng)是內(nèi)核默認(rèn)提供的,在內(nèi)核配置時(shí)去指定,而u-boot提供的則在u-boot啟動(dòng)時(shí)傳遞到內(nèi)核中取代內(nèi)核提供的參數(shù)。所以當(dāng)u-boot沒有提供bootargs參數(shù)時(shí),內(nèi)核啟動(dòng)就是用內(nèi)核配置時(shí)指定的參數(shù),當(dāng)u-boot提供了bootargs參數(shù)時(shí)就使用u-boot的參數(shù)。

          那么,u-boot是如果將參數(shù)信息傳遞到內(nèi)核中的呢?而內(nèi)核又是怎么接收u-boot傳遞過來的參數(shù)呢?這就涉及到一點(diǎn)點(diǎn)ARM寄存器的知識(shí)了。

          我們知道,ARM有7種工作模式和37個(gè)寄存器(31個(gè)通用寄存器和6個(gè)狀態(tài)寄存器),如下圖:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/1032545.png" style="padding:0px;margin:0px;border:0px;" />

          ARM工作模式之間的轉(zhuǎn)換就是利用這些寄存器進(jìn)行,而u-boot參數(shù)的傳遞也利用了三個(gè)通用寄存器R0、R1和R2。關(guān)于ARM工作模式和寄存器在這里就不做講敘了,以后再講,這里你就理解成u-boot在啟動(dòng)的時(shí)候把參數(shù)存放到這三個(gè)寄存器中,到內(nèi)核啟動(dòng)時(shí)再把寄存器中的參數(shù)取出,當(dāng)然,他們并不是就這樣簡單的操作。下面我們看代碼一一分析。

          首先,我們來分析一下u-boot是怎樣處理和發(fā)送要傳遞的參數(shù),而u-boot要傳遞的參數(shù)又有哪些呢?除了我們最容易知道的bootargs(即內(nèi)核commandline)參數(shù)項(xiàng)外,要傳遞的參數(shù)還有MACH_TYPE(即我們所說的機(jī)器碼)、系統(tǒng)根設(shè)備信息(標(biāo)志,頁面大小)、內(nèi)存信息(起始地址,大小)、RAMDISK信息(起始地址,大小)、壓縮的RAMDISK根文件系統(tǒng)信息(起始地址,大小)。由此可見要傳遞的參數(shù)很多,這時(shí)候,u-boot就提供一種叫做參數(shù)鏈表(tagged list)的方式把這些參數(shù)組織起來,鏈表結(jié)構(gòu)體定義在:include/asm-arm/setup.h中,而實(shí)現(xiàn)鏈表的組織在lib_arm/bootm.c中:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/1032546.png" style="padding:0px;margin:0px;border:0px;" />650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/1032547.png" style="padding:0px;margin:0px;border:0px;" />

          我們可以看到,鏈表的組織是由一系列函數(shù)實(shí)現(xiàn),u-boot規(guī)定,鏈表必須以ATAG_CORE標(biāo)記開始,以ATAG_NONE標(biāo)記結(jié)束,中間就是一些參數(shù)標(biāo)記項(xiàng),這點(diǎn)從代碼中可以體現(xiàn)出來。那么在這些函數(shù)中有一個(gè)bd的參數(shù)是至關(guān)重要的,它是一個(gè)bd_info類型的結(jié)構(gòu)體,定義在include/asm-arm/u-boot.h中,而這個(gè)結(jié)構(gòu)體又被一個(gè)global_data類型的結(jié)構(gòu)體所引用,定義在include/asm-arm/global_data.h中,如下:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/1032548.png" style="padding:0px;margin:0px;border:0px;" />650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/1032549.png" style="padding:0px;margin:0px;border:0px;" />
          那么,那個(gè)bd參數(shù)到底是做什么用的呢?從定義中可以得知,bd記錄了機(jī)器碼、u-boot參數(shù)鏈表在內(nèi)存中的地址等信息,那又問,它在什么地方進(jìn)行記錄的呢?它就在我們自己開發(fā)板初始化代碼中記錄的,如:board/samsung/my2440/my2440.c中
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325410.png" style="padding:0px;margin:0px;border:0px;" />

          注意:bd_t被gd_t所引用,而在global_data.h中我們可以看到,u-boot定義了一個(gè)gd_t的全局指針變量*gd,所以在這里就可以直接使用gd來設(shè)置bd了。

          好了,我們還是接著分析這個(gè)參數(shù)鏈表是如何被傳遞的,組織參數(shù)鏈表的系列函數(shù)在一個(gè)叫do_bootm_linux的函數(shù)中被調(diào)用的,還是定義在lib_arm/bootm.c中
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325411.png" style="padding:0px;margin:0px;border:0px;" />

          從這個(gè)函數(shù)中我們可以看到,要使參數(shù)傳遞生效必須需要CONFIG_SETUP_MEMORY_TAGS和CONFIG_CMDLINE_TAG這兩個(gè)宏的支持,所以需要在include/configs/my2440.h中定義它們。原來我就是沒定義它們,在使用NFS掛載文件系統(tǒng)時(shí)就出現(xiàn)問題。同時(shí),theKernel這個(gè)函數(shù)指針是u-boot參數(shù)傳遞的至關(guān)點(diǎn),我們知道,函數(shù)在內(nèi)存中執(zhí)行的時(shí)候其實(shí)就是一個(gè)地址,而在代碼中首先將這個(gè)函數(shù)指針指向kernel的入口地址,最后還將0、機(jī)器碼和u-boot參數(shù)項(xiàng)在內(nèi)存中的地址帶給這個(gè)入口地址,故執(zhí)行這個(gè)入口地址的時(shí)候即kernel啟動(dòng)的時(shí)候可以有這三個(gè)參數(shù)進(jìn)行接收。那么,這個(gè)入口地址(kernel啟動(dòng)地址或者說kernel入口地址)是怎么來的是誰指定的,又是多少呢?看代碼,是從一個(gè)bootm_headers_t類型的結(jié)構(gòu)體的成員ep取得的,而這個(gè)結(jié)構(gòu)體是從調(diào)用do_bootm_linux的地方傳遞過來的。bootm_headers_t定義在include/image.h中,do_bootm_linux在common/cmd_bootm.c中被調(diào)用,如下:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325412.png" style="padding:0px;margin:0px;border:0px;" />650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325413.png" style="padding:0px;margin:0px;border:0px;" />
          從代碼中可以清楚的看到對(duì)bootm_headers_t的成員ep進(jìn)行了賦值,但是還是不夠直觀這個(gè)入口地址到底是多少?只知道是使用image_get_ep函數(shù)從bootm_headers_t中的legacy_hdr_os_copy上取得的,那它在什么地方被賦值的呢?原來在image_set_ep函數(shù)中,定義在tools/mkimage.c中,如下:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325414.png" style="padding:0px;margin:0px;border:0px;" />
          我們?cè)傧胂?,這個(gè)mkimage.c是做什么用的?原來是用它來制作u-boot格式的內(nèi)核——uImage,還記得怎樣使用mkimage來制作uImage吧,在“u-boot-2009.08在2440上的移植詳解(四)”中講到,如下:

          mkimage [-x]-A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image

          選項(xiàng):
          -A:set architecture to arch//用于指定CPU類型,比如ARM
          -O:set operating system to os//用于指定操作系統(tǒng),比如Linux
          -T:set image type to type//用于指定image類型,比如Kernel
          -C:set compression type comp//指定壓縮類型
          -a:set load address to addr(hex)//指定image的載入地址
          -e:set entry point to ep(hex)//內(nèi)核的入口地址,一般為image的載入地址+0x40(信息頭的大?。?br />-n:set image name to name//image在頭結(jié)構(gòu)中的命名
          -d:use image data from datafile//無頭信息的image文件名
          -x:set XIP (execute in place)//設(shè)置執(zhí)行位置

          例如:
          mkimage -n linux-2.6.30.4-A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage.img

          呵呵,相信此時(shí)的你撥云見日,茅塞頓開了吧!這個(gè)入口地址就是0x30008000,這也正是為什么u-boot一定要使用uImage的格式來啟動(dòng)內(nèi)核的原因之一。注意:這里有個(gè)kernel入口地址0x30008000,在上面還提到一個(gè)u-boot參數(shù)鏈表在內(nèi)存中的地址0x30000100,試想如果這里指定的kernel入口地址覆蓋了參數(shù)鏈表的地址會(huì)怎么樣?

          好了,把上面每個(gè)步驟從下往上看就可以知道u-boot參數(shù)項(xiàng)在u-boot端的傳遞的整個(gè)流程了,那么,接下來再分析u-boot參數(shù)項(xiàng)在kernel端是怎樣接收的。

          kernel啟動(dòng)的流程如下圖所示:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325415.png" style="padding:0px;margin:0px;border:0px;" />
          在文件arch/arm/boot/compressed/head.S中,start是zImage的起始點(diǎn),部分代碼如下:

          start:
          ......

          .word 0x016f2818 @ Magic numbers to help the loader
          .word start @ absolute load/run zImage address
          .word _edata @ zImage end address
          1:mov r7, r1 @ save architecture ID
          mov r8, r2 @ save atags pointer
          ......

          wont_overwrite: mov r0, r4
          mov r3, r7
          bl decompress_kernel
          b call_kernel

          ......

          call_kernel: bl cache_clean_flush
          bl cache_off
          mov r0, #0 @ must be zero
          mov r1, r7 @ restore architecture number
          mov r2, r8 @ restore atags pointer
          mov pc, r4 @ call kernel

          ......

          首先,將u-boot傳遞過來的r1(機(jī)器碼)、r2(參數(shù)鏈表在內(nèi)在中的物理地址)分別保存到ARM寄存器r7、r8中,再將r7作為參數(shù)傳遞給解壓函數(shù)decompress_kernel(),在這個(gè)解壓函數(shù)中再將r7傳遞給全局變量__machine_arch_type,然后在跳轉(zhuǎn)到vmlinux入口之前再將r7、r8還原到r1、r2中。

          在arch/arm/kernel/head.S文件中,內(nèi)核vmlinux入口的部分代碼如下:

          ENTRY(stext)
          setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode @ andirqs disabled
          mrc p15, 0, r9, c0, c0 @ get processor id
          bl __lookup_processor_type @ r5=procinfo r9=cpuid
          movs r10, r5 @ invalid processor (r5=0)?
          beq __error_p @ yes, error p
          bl __lookup_machine_type @ r5=machinfo
          movs r8, r5 @ invalid machine (r5=0)?
          beq __error_a @ yes, error a
          bl __vet_atags
          bl __create_page_tables

          ......

          首先從ARM特殊寄存器(CP15)中獲得ARM內(nèi)核的類型,從處理器內(nèi)核描述符(proc_info_list)表(__proc_info_begin—__proc_info_end)中查詢有無此ARM 內(nèi)核的類型,如果無就出錯(cuò)退出。處理器內(nèi)核描述符定義在include/asm-arm/procinfo.h中,具體的函數(shù)實(shí)現(xiàn)在 arch/arm/mm/proc-xxx.S中,在編譯連接過程中將各種處理器內(nèi)核描述符組合成表。接著從機(jī)器描述(machine_desc)表(__mach_info_begin—__mach_info_end)中查詢有無r1寄存器指定的機(jī)器碼,如果沒有就出錯(cuò)退出,所以這也說明了為什么在u-boot中指定的機(jī)器碼一定要與內(nèi)核中指定的一致,否則內(nèi)核就無法啟動(dòng)。機(jī)器編號(hào)mach_type_xxx在arch/arm/tools/mach-types文件中說明,每個(gè)機(jī)器描述符中包括一個(gè)唯一的機(jī)器編號(hào),機(jī)器描述符的定義在 include/asm-arm/mach/arch.h中,具體實(shí)現(xiàn)在arch/arm/mach-xxxx文件夾中,在編譯連接過程中將基于同一種處理器的不同機(jī)器描述符組合成表。例如,S3C2440處理器的機(jī)器碼為1008的機(jī)器描述符如下所示:

          MACHINE_START(SMDK2440,"SMDK2440")
          /* Maintainer: Ben Dooks */
          .phys_io = S3C2410_PA_UART,
          .io_pg_offst =(((u32)S3C24XX_VA_UART)>> 18)& 0xfffc,
          .boot_params = S3C2410_SDRAM_PA + 0x100,//注意:這個(gè)地址就是與u-boot中參數(shù)鏈表在內(nèi)存中的物理地址相對(duì)應(yīng)

          .init_irq = s3c24xx_init_irq,
          .map_io = smdk2440_map_io,
          .init_machine = smdk2440_machine_init,
          .timer =&s3c24xx_timer,
          MACHINE_END

          最后就打開MMU,并跳轉(zhuǎn)到 init/main.c的start_kernel()初始化系統(tǒng)。函數(shù)start_kernel()的部分代碼如下:

          asmlinkage void __init start_kernel(void)
          {
          ......
          setup_arch(&command_line);
          ......
          }

          函數(shù)setup_arch在arch/arm/kernel/setup.c中實(shí)現(xiàn),部分代碼如下:

          void __init setup_arch(char**cmdline_p)
          {
          ......
          setup_processor();
          mdesc = setup_machine(machine_arch_type);
          ......
          parse_tags(tags);
          ......
          }

          setup_processor()函數(shù)從處理器內(nèi)核描述符表中找到匹配的描述符,并初始化一些處理器
          變量。setup_machine()用機(jī)器編號(hào)(在解壓函數(shù)decompress_kernel 中被賦值)作為參數(shù)返回機(jī)器描述符。從機(jī)器描述符中獲得內(nèi)核參數(shù)的物理地址,賦值給tags 變量。然后調(diào)用parse_tags()函數(shù)分析內(nèi)核參數(shù)鏈表,把各個(gè)參數(shù)值傳遞給全局變量。這樣內(nèi)核就收到了u-boot傳遞的參數(shù)。

          • tftp下載內(nèi)核和nfs掛載文件系統(tǒng)

          好了,上面tftp服務(wù)和nfs服務(wù)都已經(jīng)準(zhǔn)備好了,u-boot到kernel的參數(shù)傳遞也沒問題了,接下來就設(shè)置一下u-boot環(huán)境變量中的參數(shù)項(xiàng)和kernel的配置選項(xiàng)使之能使用tftp自動(dòng)下載kernal和通過網(wǎng)絡(luò)自動(dòng)掛載nfs文件系統(tǒng)。u-boot環(huán)境變量設(shè)置如下:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325416.png" style="padding:0px;margin:0px;border:0px;" />

          bootcmd參數(shù)項(xiàng)就是使用tftp把主機(jī)tftp主目錄下的uImage下載到開發(fā)板SDRAM中的0x31000000位置,接著使用bootm命令執(zhí)行引導(dǎo)內(nèi)核啟動(dòng)。

          而bootargs參數(shù)項(xiàng)就是內(nèi)核啟動(dòng)的命令行參數(shù),u-boot就是把這個(gè)參數(shù)項(xiàng)傳遞給了內(nèi)核,通過nfs掛載文件系統(tǒng)。這里一定要注意serverip和ipaddr的設(shè)置(即服務(wù)器IP或者開發(fā)主機(jī)IP和開發(fā)板的IP)。另外要注意,內(nèi)核要能使用nfs也要配置相應(yīng)的選項(xiàng),如下:

          File systems --->
          Network File Systems --->
          <*> NFS file system support ## 必選
          [*] Provide NFSv3 client support ## 可選
          [*] Root file system on NFS ## 必選
          Networking --->
          [*] Networking support
          Networking options --->
          [*] IP: kernel level autoconfiguration ## 必選

          運(yùn)行結(jié)果如下:

          a. tftp下載內(nèi)核,并引導(dǎo)內(nèi)核啟動(dòng):
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325417.png" style="padding:0px;margin:0px;border:0px;" />

          b. u-boot傳遞的命令行參數(shù)被內(nèi)核所接收:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325418.png" style="padding:0px;margin:0px;border:0px;" />

          c. 內(nèi)核通過nfs掛載文件系統(tǒng):
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325419.png" style="padding:0px;margin:0px;border:0px;" />

          d. 查看掛載的nfs文件系統(tǒng),發(fā)現(xiàn)完全與主機(jī)nfs服務(wù)器主目錄中的文件系統(tǒng)一致,說明成功!
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325420.png" style="padding:0px;margin:0px;border:0px;" />

          [root@localhost home]# vi /etc/exports //如果沒有這個(gè)文件就創(chuàng)建它,添加下面一行配置信息,注意格式一定要正確,否則導(dǎo)致服務(wù)不正常

          /home/filesystem *(rw,no_root_squash,sync)

          注釋:“/home/filesystem”是NFS服務(wù)器的主目錄,注意目錄的權(quán)限

          “*”表示所有的IP都可以訪問NFS主目錄

          “rw”表示可讀可寫

          ”no_root_squash“表示登入到NFS主機(jī)的用戶如果是ROOT用戶,他就擁有ROOT的權(quán)限

          “sync”表示同步

          [root@localhost home]# service nfs restart //重新啟動(dòng)NFS服務(wù),使配置文件生效

          測(cè)試NFS服務(wù)是否正常。將事先準(zhǔn)備好的文件系統(tǒng)放到NFS主目錄下,如下:

          [root@localhost home]# ls /home/filesystem/
          bin dev home lib mnt root sum100 tmp var
          debug etc hostname linuxrc proc sbin sys usr
          [root@localhost home]#

          //在主機(jī)本地測(cè)試NFS服務(wù),將NFS主目錄下的文件系統(tǒng)掛載到/mnt目錄下,192.168.1.101是主機(jī)的IP

          [root@localhost home]#mount -o nolock -t nfs 192.168.1.101:/home/filesystem /mnt

          可以看到/mnt目錄下的內(nèi)容和NFS主目錄/home/filesystem下的內(nèi)容完全一致,說明NFS服務(wù)正常:
          650) this.width=650;" src="http://www.embeddedlinux.org.cn/uploads/allimg/130316/10325421.png" style="padding:0px;margin:0px;border:0px;" />

          [root@localhost home]# vi /etc/xinetd.d/tftp

          service tftp
          {
          disable =no
          socket_type = dgram
          protocol = udp
          wait= yes
          user = root
          server =/usr/sbin/in.tftpd
          server_args =-s /home/tftp-root -c //主要是修改這里,指定tftp服務(wù)器的主目錄,-c選項(xiàng)是指可以創(chuàng)建文件
          per_source = 11
          cps = 100 2
          flags = IPv4
          }

          創(chuàng)建剛才指定的tftp服務(wù)器主目錄,也要注意主目錄的可讀可寫的權(quán)限:

          [root@localhost home]#mkdir /home/tftp-root
          [root@localhost home]#chmod 777 /home/tftp-root

          啟動(dòng)和測(cè)試tftp服務(wù):

          [root@localhost home]#service xinetd restart //重啟xinetd服務(wù)就會(huì)啟動(dòng)其下的所有服務(wù),也包括tftp服務(wù)
          [root@localhost home]#service iptables stop //關(guān)閉防火墻
          [root@localhost home]#tftp 主機(jī)IP地址
          tftp>get 要下載的文件

          tftp>put 要上傳的文件

          tftp>q
          [root@localhost home]#




          關(guān)鍵詞: Uboot在S3C2440移植詳

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();