1. Linux 内存的meminfo 获取过程

2024-09-05 22:08

本文主要是介绍1. Linux 内存的meminfo 获取过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. Linux 内存的大小获取过程

硬件:tiny4412

软件:linux3.0.86,uboot-tiny4412

目的:梳理linux start-kernel阶段,获取内核大小的过程,并将内存bank个数,start ,size信息,放入meminfo中

tiny4412平台,传递内存的信息,是通过 u-boot,传递tag的方式来传递内存的大小的,而不是通过dtb的方式。 

【start_kernel()->setup_arch()】

    //首先判断是否从fdt中,获取machine desc mdesc = setup_machine_fdt(__atags_pointer);if (!mdesc)//以tags的方式,获取machine descmdesc = setup_machine_tags(machine_arch_type);
static struct machine_desc * __init setup_machine_tags(unsigned int nr)
{struct tag *tags = (struct tag *)&init_tags;struct machine_desc *mdesc = NULL, *p;char *from = default_command_line;init_tags.mem.start = PHYS_OFFSET;/** locate machine in the list of supported machines.*/for_each_machine_desc(p)if (nr == p->nr) {printk("Machine: %s\n", p->name);mdesc = p;break;}
...if (tags->hdr.tag == ATAG_CORE) {if (meminfo.nr_banks != 0)squash_mem_tags(tags);save_atags(tags);parse_tags(tags);}

首先会通过for_each_machine_desc查找对应的 machine ID。 

machine ID 是放置在 .arch.info.init 这个section的数据。 通过MACHINE_START 注册的machine将会放在在 .arch.info.init 这个section 中。

以tag的形式传递过来的数据 ,不同的数据有不同的tag及进行标识

#define ATAG_CORE    0x54410001
#define ATAG_MEM    0x54410002
#define ATAG_CMDLINE    0x54410003
#define ATAG_RDIMG    0x54410004
parse_tags(tags);static void __init parse_tags(const struct tag *t)
{//编译传递过来的tagfor (; t->hdr.size; t = tag_next(t))if (!parse_tag(t))printk(KERN_WARNING"Ignoring unrecognised tag 0x%08x\n",t->hdr.tag);
}static int __init parse_tag(const struct tag *tag)
{extern struct tagtable __tagtable_begin, __tagtable_end;struct tagtable *t;for (t = &__tagtable_begin; t < &__tagtable_end; t++)if (tag->hdr.tag == t->tag) {t->parse(tag);break;}return t < &__tagtable_end;
}

在setup.c 中,会通过__tagtable 注册以下执行的函数,方式在taglist.init这个setction中,

struct tagtable {u32	tag;int	(*parse)(struct tag *);
};#define __tag __used __attribute__((__section__(".taglist.init")))
#define __tagtable(tag, fn)						\static struct tagtable __tagtable_##fn __tag = { tag, fn static int __init parse_tag_mem32(const struct tag *tag)
{return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
}__tagtable(ATAG_MEM, parse_tag_mem32);

有u-boot传递过来的带有ATAG_MEM 的信息,将会执行 arm_add_memory函数

int __init arm_add_memory(phys_addr_t start, unsigned long size)
{struct membank *bank = &meminfo.bank[meminfo.nr_banks];if (meminfo.nr_banks >= NR_BANKS) {printk(KERN_CRIT "NR_BANKS too low, ""ignoring memory at 0x%08llx\n", (long long)start);return -EINVAL;}/** Ensure that start/size are aligned to a page boundary.* Size is appropriately rounded down, start is rounded up.*/size -= start & ~PAGE_MASK;bank->start = PAGE_ALIGN(start);bank->size  = size & PAGE_MASK;/** Check whether this memory region has non-zero size or* invalid node number.*/if (bank->size == 0)return -EINVAL;meminfo.nr_banks++;return 0;
}

arm_add_memory函数,拿到由u-boot传递过来的哪个bank的start地址和长度,放到变量meminfo中。

 

这篇关于1. Linux 内存的meminfo 获取过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140203

相关文章

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

MySQL中的InnoDB单表访问过程

《MySQL中的InnoDB单表访问过程》:本文主要介绍MySQL中的InnoDB单表访问过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

Navicat数据表的数据添加,删除及使用sql完成数据的添加过程

《Navicat数据表的数据添加,删除及使用sql完成数据的添加过程》:本文主要介绍Navicat数据表的数据添加,删除及使用sql完成数据的添加过程,具有很好的参考价值,希望对大家有所帮助,如有... 目录Navicat数据表数据添加,删除及使用sql完成数据添加选中操作的表则出现如下界面,查看左下角从左

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat