2012-07-20 17 views
9

在從imb50 ARM板上的uboot到linux kernel 2.6.35.3傳遞大量數據(3 MB)時遇到一些問題。這些數據在內核設備驅動程序探測功能中是必需的,然後它應該被釋放。首先從閃存加載數據到RAM,然後使用bootargs傳遞Linux內核的物理地址。在內核中我嘗試使用在arch/ARM /內核/ setup.c中文件reserve_resource()保留的內存一定量:將大量的二進制數據從u-boot傳遞到linux內核

--- a/arch/arm/kernel/setup.c Tue Jul 17 11:22:39 2012 +0300 
+++ b/arch/arm/kernel/setup.c Fri Jul 20 14:17:16 2012 +0300 

struct resource my_mem_res = { 
    .name = "My_Region", 
    .start = 0x77c00000, 
    .end = 0x77ffffff, 
    .flags = IORESOURCE_MEM | IORESOURCE_BUSY, 
}; 

@@ -477,6 +479,10 @@ 
    kernel_code.end  = virt_to_phys(_etext - 1); 
    kernel_data.start = virt_to_phys(_data); 
    kernel_data.end  = virt_to_phys(_end - 1); 
+ my_mem_res.start = mi->bank[i].start + mi->bank[i].size - 0x400000; 
+ my_mem_res.end  = mi->bank[i].start + mi->bank[i].size - 1; 

    for (i = 0; i < mi->nr_banks; i++) { 
     if (mi->bank[i].size == 0) 
@@ -496,6 +502,8 @@ 
     if (kernel_data.start >= res->start && 
      kernel_data.end <= res->end) 
      request_resource(res, &kernel_data); 
+ 
+  request_resource(res, &my_mem_res); 
    } 

    if (mdesc->video_start) { 

通過這一點,我想告訴內核這個內存區域預留它是這數據不應該被內核修改。

70000000-77ffffff : System RAM 
    70027000-7056ffff : Kernel text 
    70588000-7062094f : Kernel data 
    77c00000-77ffffff : My_Region 

在驅動程序ioremap(0x77c00000, AREA_SIZE)是用來獲取內核內存地址。但是當我轉儲內存的內容時,只有零。如果啓動內核與mem=120M(總共128MB RAM是可用的),那麼我的數據高於內核系統ram區域,然後我得到我期望的數據。

所以,我的問題:

爲什麼我得到零,如何通過大量的二進制數據從UBOOT到Linux內核?

+0

自從我與ARM合作以來已經有一段時間了......但看看boot/compressed/head.S。簡而言之,當Linux啓動時清除RAM。這有點複雜,因爲u-boot在Linux內核啓動之前準備好實際的內存大小。查找bootm.c do_bootm_linux(),在那裏有一個調用setup_memory_tags()。這些雖然陳舊,但依然有效[1](http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html)和[2](http://amitshah.bizhat.com/臂/ arm_linux_boot-1.HTML)。 HTH – 2012-08-03 04:18:45

+0

確保引導加載程序在啓動引導序列之前未進行memtest。這可以解釋爲什麼你看到零。 – 2012-09-21 09:48:56

回答

7

你可以使用一個自定義ATAG要麼通過數據塊或傳遞數據的地址&長度。請注意,ATAG中的「A」代表ARM,因此該解決方案不適用於其他架構。一個ATAG比命令行bootarg IMO更可取,因爲您不希望用戶使用物理內存地址。此外,Linux內核將在啓用MMU(即虛擬存儲器)之前處理該列表。

在U-Boot中,查看lib_arm/armlinux.carch/arm/lib/bootm.c,查看構建ARM標記列表的例程。爲您的新標籤編寫自己的例程,然後在do_bootm_linux()中調用它。

在Linux內核中ATAGsarch/arm/kernel/setup.c中處理時,虛擬內存尚未啓用。如果你只是通過從U-Boot的地址&長度值,然後將鼠標指針&長度可以被分配到出口的全局變量,

void   *my_data; 
unsigned int my_dlen; 
EXPORT_SYMBOL(my_data); 
EXPORT_SYMBOL(my_dlen); 

,然後司機可以取回它。

extern void   *my_data; 
extern unsigned int my_dlen; 

request_mem_region(my_data, my_dlen, DRV_NAME); 
md_map = ioremap(my_data, my_dlen); 

我已經用類似的代碼探測的U-Boot的SRAM,然後通過起始地址&發現內核千字節數在自定義ATAG。內核驅動程序獲取這些值,如果它們非零並且具有合理的值,則從SRAM中創建塊設備。與您的情況的主要區別在於,SRAM與SDRAM的物理地址範圍完全不同。

注意ATAG是由U-Boot的建成爲物理內存的內核可以使用,所以這是真的,你需要定義和排除您預留的RAM。在內核中這樣做可能已經太遲了。

相關問題