Mik*_*iko 9 memory arm linux-kernel embedded-linux u-boot
在imx50 ARM板上将大量数据(3 MB)从uboot传递到linux内核2.6.35.3有一些问题.内核设备驱动程序探测功能需要此数据,然后才能释放.首先uboot将数据从闪存加载到RAM,然后使用bootargs传递linux内核的物理地址.在内核中,我尝试使用arch/arm/kernel/setup.c文件中的reserve_resource()来保留一定量的内存:
--- 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) {
Run Code Online (Sandbox Code Playgroud)
通过这个我试图告诉内核它保留的这个内存区域,这个数据不应该被内核修改.
70000000-77ffffff : System RAM
70027000-7056ffff : Kernel text
70588000-7062094f : Kernel data
77c00000-77ffffff : My_Region
Run Code Online (Sandbox Code Playgroud)
在驱动程序ioremap(0x77c00000, AREA_SIZE)
中用于获取内核内存地址.但是当我转储内存的内容时,只有零.如果启动内核mem=120M
(总共128MB RAM是可用的),那么我的数据高于内核系统ram区域,然后我得到我期望的数据.
所以,我的问题:
为什么我得到零,如何将大量的二进制数据从uboot传递到linux内核?
您可以使用自定义ATAG来传递数据块或传递数据的地址和长度.请注意,ATAG中的"A" 代表ARM,因此该解决方案无法移植到其他体系结构.一个ATAG最好一个命令行bootarg IMO,因为你不希望用户与物理内存地址淤泥.此外,Linux内核将在启用MMU(即虚拟内存)之前处理ATAG列表.
在U-Boot中,查看lib_arm/armlinux.c
或arch/arm/lib/bootm.c
构建构建ARM标记列表的例程.为新标记编写自己的例程,然后在do_bootm_linux()中调用它.
在Linux内核中,当尚未启用虚拟内存时,将处理ATAGarch/arm/kernel/setup.c
.如果只是从U-Boot传递地址和长度值,那么指针和长度可以分配给导出的全局变量,
void *my_data;
unsigned int my_dlen;
EXPORT_SYMBOL(my_data);
EXPORT_SYMBOL(my_dlen);
Run Code Online (Sandbox Code Playgroud)
然后驱动程序可以检索它.
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);
Run Code Online (Sandbox Code Playgroud)
我已经使用类似的代码来探测U-Boot中的SRAM,然后在自定义ATAG中将起始地址和找到的KBytes数传递给内核.内核驱动程序获取这些值,如果它们非零且具有合理的值,则从SRAM中创建块设备.与您的情况的主要区别在于SRAM与SDRAM的物理地址范围完全不同.
注: 一个ATAG是由U-Boot的专为内核可以使用的物理内存,所以这是真的,你需要定义和排除您预留的RAM.在内核中执行此操作可能为时已晚.