linux下特定处理器的设备物理地址和虚拟物理地址的静态映射的实现


处理器:全志A31; Linux内核3.3

A31 定义的machine信息在mach-sun6i/core.c下面:

MACHINE_START(SUN6I, "sun6i")
	.atag_offset	= 0x100,
	.reserve	= sun6i_reserve,
	.fixup		= sun6i_fixup,
	.map_io		= sun6i_map_io,
	.init_early	= sun6i_init_early,
	.init_irq	= gic_init_irq,
	.timer		= &sun6i_timer,
	.handle_irq	= gic_handle_irq,
	.init_machine	= sun6i_init,
#ifdef CONFIG_ZONE_DMA
	.dma_zone_size	= SZ_64M,
#endif
	.restart	= sun6i_restart,
MACHINE_END


这个结构体的内容说明的是一个处理器的基本信息,主要的有设备类型即机器码等。这里的map_io就是对处理器的设备物理地址和虚拟地址建立固定的映射关系。

这样的好处在于,设备物理地址固定,使得虚拟地址固定,驱动里面就不需要再使用动态的映射,直接操作虚拟地址即可。

static void __init sun6i_map_io(void)
{
	iotable_init(sun6i_io_desc, ARRAY_SIZE(sun6i_io_desc));
}

map_io的调用流程如下:Start_kernel -> setup_arch() --> paging_init() --> devicemaps_init(),最终调用上述结构体中的sun6i_map_io.

iotable_init的处理过程就是将对应处理器所具有的设备物理地址进行映射:

static struct map_desc sun6i_io_desc[] __initdata = {
	{IO_ADDRESS(AW_SRAM_A1_BASE), __phys_to_pfn(AW_SRAM_A1_BASE),  AW_SRAM_A1_SIZE, MT_MEMORY_ITCM},
	{IO_ADDRESS(AW_SRAM_A2_BASE), __phys_to_pfn(AW_SRAM_A2_BASE),  AW_SRAM_A2_SIZE, MT_DEVICE_NONSHARED},
	{IO_ADDRESS(AW_IO_PHYS_BASE), __phys_to_pfn(AW_IO_PHYS_BASE),  AW_IO_SIZE, MT_DEVICE_NONSHARED},
	{IO_ADDRESS(AW_BROM_BASE),    __phys_to_pfn(AW_BROM_BASE),     AW_BROM_SIZE, MT_DEVICE_NONSHARED},
};//固定虚拟地址和物理地址的映射

IO_ADDRESS(AW_SRAM_A1_BASE):该宏其实是将实际的设备物理地址转换为一个虚拟物理地址,处理的过程PH_ADD+0xf0000000的线性映射。

__phys_to_pfn(AW_SRAM_A1_BASE):该宏是将实际的设备物理地址转为物理页地址。

在调用iotable_init的结果就是建立了上述的映射关系,故其他内核驱动模块初始化时,直接调用固定的虚拟物理地址。

#define	AW_DE_FE0_BASE				0x01e00000
#define	AW_DE_FE1_BASE				0x01e20000
#define	AW_DE_BE1_BASE				0x01e40000
虚拟的设备物理地址
#define	AW_VIR_DE_FE0_BASE				0xf1e00000
#define	AW_VIR_DE_FE1_BASE				0xf1e20000
#define	AW_VIR_DE_BE1_BASE				0xf1e40000


map_io通过Start_kernel -> setup_arch() --> paging_init() --> devicemaps_init()中被调用
 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中可以通过`ProcessBuilder`类执行系统命令,因此我们可以通过执行设置IP地址和网关的系统命令来实现设置静态IP地址和网关的功能。下面是一个简单的实现,代码如下: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main(String[] args) { // 设置IP地址和网关,注意替换成自己的IP地址和网关 setStaticIP("eth0", "192.168.1.100", "255.255.255.0", "192.168.1.1"); } /** * 设置静态IP地址和网关 * @param name 网卡名称 * @param ip IP地址 * @param netmask 子网掩码 * @param gateway 网关地址 */ public static void setStaticIP(String name, String ip, String netmask, String gateway) { try { // 执行设置IP地址和网关的命令 ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "ifconfig " + name + " " + ip + " netmask " + netmask + " && route add default gw " + gateway); Process process = pb.start(); // 获取命令执行结果 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } // 等待命令执行完成 int exitCode = process.waitFor(); if (exitCode == 0) { System.out.println("设置静态IP地址和网关成功!"); } else { System.out.println("设置静态IP地址和网关失败!"); } } catch (IOException | InterruptedException e) { e.printStackTrace(); } } } ``` 这段代码中,我们通过执行设置IP地址和网关的系统命令来实现设置静态IP地址和网关的功能。在`setStaticIP`方法中,我们使用`ProcessBuilder`类执行系统命令,其中`ifconfig`命令用于设置IP地址和子网掩码,`route`命令用于添加默认网关。执行命令后,我们使用`BufferedReader`类获取命令执行结果,并使用`waitFor`方法等待命令执行完成。最后根据命令的执行结果输出相应的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值