2012-07-20 25 views
9

Có một số vấn đề với việc truyền lượng dữ liệu lớn (3 MB) từ uboot đến hạt nhân Linux 2.6.35.3 trên bảng ARM imx50. Dữ liệu này được yêu cầu trong hàm thăm dò trình điều khiển thiết bị hạt nhân và sau đó nó sẽ được giải phóng. Đầu tiên uboot tải dữ liệu từ flash vào RAM, sau đó vượt qua địa chỉ vật lý cho hạt nhân Linux bằng cách sử dụng bootargs. Trong hạt nhân tôi cố gắng dành số tiền nhất định của bộ nhớ sử dụng reserve_resource() trong vòm/tay/kernel/file setup.c:Vượt qua số lượng lớn dữ liệu nhị phân từ u-boot tới hạt nhân 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) { 

Bằng cách này, tôi đang cố gắng để nói với kernel rằng vùng nhớ này nó dè dặt và nay dữ liệu không nên được sửa đổi bởi hạt nhân.

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

Trong trình điều khiển ioremap(0x77c00000, AREA_SIZE) được sử dụng để lấy địa chỉ bộ nhớ hạt nhân. Nhưng khi tôi đổ nội dung của bộ nhớ, chỉ có 0 số không. Nếu hạt nhân khởi động với mem=120M (tổng số 128MB RAM có sẵn), thì dữ liệu của tôi ở trên vùng ram hệ thống hạt nhân, sau đó tôi nhận được dữ liệu tôi mong đợi.

Vì vậy, câu hỏi của tôi:

Tại sao tôi nhận được số không và làm thế nào để tôi vượt qua số lượng lớn các dữ liệu nhị phân từ uboot để kernel linux?

+0

Đã lâu rồi kể từ khi tôi làm việc với ARM ... nhưng hãy xem xét boot/compressed/head.S. Tóm lại, khi Linux khởi động nó sẽ xóa RAM. Đó là một chút phức tạp, kể từ khi khởi động u chuẩn bị kích thước bộ nhớ thực tế trước khi khởi động hạt nhân Linux. Tra cứu bootm.c do_bootm_linux() có một cuộc gọi có setup_memory_tags(). Đây là những cũ nhưng ý chí vẫn còn hợp lệ [1] (http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html) và [2] (http://amitshah.bizhat.com/ arm/arm_linux_boot-1.html). HTH –

+0

Đảm bảo rằng bộ nạp khởi động của bạn không thực hiện ghi nhớ trước khi bắt đầu trình tự khởi động. Điều đó có thể giải thích tại sao bạn thấy số không. –

Trả lời

7

Bạn có thể sử dụng tùy chỉnh ATAG để chuyển khối dữ liệu hoặc để vượt qua địa chỉ & độ dài của dữ liệu. Lưu ý rằng "A" trong ATAG là viết tắt của ARM, vì vậy giải pháp này không thể di chuyển sang các kiến ​​trúc khác. An ATAG thích hợp hơn với dòng lệnh bootarg IMO vì bạn không muốn người dùng bỏ qua các địa chỉ bộ nhớ vật lý. Ngoài ra hạt nhân Linux sẽ xử lý danh sách ATAG trước khi MMU (tức là bộ nhớ ảo) được bật.

Trong U-Boot, hãy xem lib_arm/armlinux.c hoặc arch/arm/lib/bootm.c cho các thường trình tạo danh sách thẻ ARM. Viết thói quen của riêng bạn cho (các) thẻ mới của bạn và sau đó gọi nó trong do_bootm_linux().

Trong hạt nhân Linux ATAGs được xử lý trong arch/arm/kernel/setup.c, khi bộ nhớ ảo chưa được bật. Nếu bạn chỉ cần vượt qua một địa chỉ & giá trị chiều dài từ U-Boot, sau đó chiều dài con trỏ & thể được gán cho các biến toàn cục mà được xuất khẩu,

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

và sau đó lái xe có thể lấy nó.

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); 

Tôi đã sử dụng mã tương tự để thăm dò cho SRAM trong U-Boot, sau đó vượt qua các địa chỉ bắt đầu & số KBytes tìm thấy hạt nhân trong một tùy chỉnh ATAG. Một trình điều khiển hạt nhân có được những giá trị này, và nếu chúng là nonzero và có giá trị sane, tạo ra một khối thiết bị ra khỏi SRAM. Sự khác biệt chính từ tình huống của bạn là SRAM nằm trong một dải địa chỉ vật lý hoàn toàn khác với SDRAM.

LƯU Ý Một ATAG được xây dựng bởi U-Boot cho bộ nhớ vật lý mà hạt nhân có thể sử dụng, vì vậy đây thực sự là nơi bạn cần phải xác định và loại trừ RAM dành riêng của bạn. Có lẽ đã quá muộn để làm điều đó trong hạt nhân.