当前位置: 首页 > news >正文

linux x86 setup_arch代码注释

 个人理解加查的资料,不保证正确,有不对可以评论

// 查找个人电脑相关固件占用的地址(来自bootparam中的handler)
olpc_ofw_detect();
// 将 early_idts 设置到 idt_table 并应用 lidt,包含 asm_exc_debug asm_exc_int3(breakpoint)
idt_setup_early_traps(); 
// cpu 供应商等简单检查
early_cpu_init();
// 初始化用于动态修改汇编的 jump label 内存
jump_label_init();
// 根据静态调用的结构体生成汇编代码
static_call_init();
// 初始化用于remap的内存,它用于把物理内存映射到pgtable中,用于临时虚拟地址访问,一个remap slot最大可映射32页的内存
early_ioremap_init();
// 将外设的页表项设置到swapper_pg_dir页表的OLPC_OFW_PDE_NR项上,swapper_pg_dir是初始化阶段用的内核页表
setup_olpc_ofw_pgd();early_reserve_memory();
e820__memory_setup();
// 设置支持 not execute
x86_configure_nx();
// reserve boot 的 setup_data中的每个保留内存到页表和e820_table、e820_table_kexece820__reserve_setup_data();
e820__finish_early_params();// 为 reserve bft 区域保留内存到页表和memblock 512kB - 1MB
reserve_ibft_region();
// 初始化用于访问bios的每个mem设置到dmi_memdev
dmi_setup();
// 时钟周期数寄器,可用于计时
tsc_early_init();
// 检测 video system extension adapter 的 rom 区,并注册request_resource
x86_init.resources.probe_roms();
// 将_text到_end之间的代码区标记为RAM类型
e820_add_kernel_range();
// 标记0-4k从ram转为reserved,将640Kb -> 1Mb的bios区域从e820表去掉,更新e820表,
trim_bios_range();
// 初始化mtrr, pat。MTRR与PAT都是用于对不同区域采用不同缓存策略(如不缓存,写合并,写透,写保护等。),mtrr是用寄存器来控制权限,pat是在页表上控制权限,显然mtrr控制粒度比pat粗。cache_bp_init();
// 为每个 memory region 添加随机的 base
kernel_randomize_memory();
// 检查是否可用高级可编程中断控制器(代替旧中断控制器,如8259A芯片)
check_x2apic();
// 找到 ram 的最大 pfn,其上的内存属于 high_memory
e820__end_of_ram_pfn();
// 从 brk 区分配pgt buffer(32k),用于临时分配p4d,pud,pmd,pte页表项,超出这个范围时如果brk区用完了,将用memblock来分配
early_alloc_pgt_buf();
// 将brk区在memblock中标记(reserve)出来,
reserve_brk();
// 把512m内核内存中_text到_brk_end之外的pmd内存映射抹去
cleanup_highmap();
// 限制分配物理内存只能在1m以内
memblock_set_current_limit(ISA_END_ADDRESS);
// 将 e820 表中ram与kernel reserved区域加入memblock中,用于后面的动态分配
e820__memblock_setup();
// 限制swiotlb为总物理内存的6%,swiotlb是用于虚拟机设备与主机之间的数据缓冲区
sev_setup_arch();
// 初始化扩展固件的内存,镜像,资源表,服务(efi 初始化)
efi_fake_memmap();
efi_find_mirror();
efi_esrt_init();
efi_mokvar_table_init();
efi_reserve_boot_services();
// reserve 用于进程间通信表的内存
e820__memblock_alloc_reserved_mpc_new();
// 保留0-1m内存和realmode.bin使用的内存,0-1m要保留是因为efi可能会以实模式去使用它
x86_platform.realmode_reserve();
// 1m 以下用max_pfn_mapped来标记这之前全部是直接映射
// 1m 以上到max_low_pfn的区域,为每页在页表中分别创建直接映射,并更新页表
init_mem_mapping();
// 在中断表中设置缺页中断handler
idt_setup_early_pf();
// 关闭PCID功能(开启pcid时允许进程上下文切换时不清除tlb),这个功能只在长模式下有用
mmu_cr4_features = __read_cr4() & ~X86_CR4_PCIDE;
setup_log_buf();
// 将ramdisk的镜像(initrd)copy到1m以下的内存中。
reserve_initrd();
// 从__initramfs_start的表中读取kernel/firmware/acpi/文件内容至 acpi_tables_addr,并解析 acpi,的全称是ACPI (Advanced Configuration and Power Interface) 是一种标准化的电脑系统管理接口,用于处理电源管理、硬件配置和设备状态等方面的功能
acpi_table_upgrade();
acpi_boot_table_init();
// 如果是在虚拟机环境下,读取虚拟 cpu 的最大cpu数与ctl信息
vsmp_init();// 判断是否是苹果机,有很多driver的逻辑会不一样
early_platform_quirks();
// 加载解析过的 acpi 配置至acpi_gbl_root_table_list中,并加载一些全局变量,如cmos的port(sbf_port),i8042,计时器(ACPI PM Timer)等
early_acpi_boot_init();
// 初始化NUMA节点,其中cpu与内存的关系记录在SRAT中
initmem_init();
// 将已经映射的1m以下内存记录在dma_mmu_remap中,这些内存会在页表中被全部映射为dma,并且以整个vm_area的形式记录到static_vmlist中
dma_contiguous_reserve(max_pfn_mapped << PAGE_SHIFT);
// 用于coredump
reserve_crashkernel();
// 标记dma_reserve值,在计算一次分配多大内存时(根据当前有多少free的dma内存),这部分dma范围不作为free内存计算。
memblock_find_dma_reserve();
// paging_init(主要是sparse_init和zone_sizes_init)
// sparse_init 中将每个memory region 没有reserved的部分,按找到它对应的section(每个section 大小为128k页=512M,section是按二维组织的,index为(root_idx,sec_idx)),标记上它的numa nid,在对应tag 上标记present和online,表示这个section有内存可用。之后为每个present的section分配128k个struct page作为memmap。
// zone_sizes_init 为每个numa node 初始化它们的每个zone,包括记录起始页、可用页数、总覆盖页数等(可以从memblock.memory.regions中找到每个numa node的所有可用大小(present),总覆盖长度指end - start,包含了中间的空洞,代码在free_area_init_node)。同时会初始化每个zone中的物理页(设置zone类型,numa node id,引用数为1,映射到文件次数为-1,上次使用的cpuid为-1),并为不可访问的页标记PG_reserved(memmap_init)
zone_spanned_pages_in_node();
x86_init.paging.pagetable_init();kasan_init();sync_initial_page_table();
// 检查是否支持Trusted Boot(tBoot),tboot可用于检查内核启动结果是否正常。
tboot_probe();
// __vsyscall_page(位于最高地址-10M的一页),它是用户可访问的一个内核页,在gate_vma标记这一页可执行
map_vsyscall();
// 检测apic driver可用
generic_apic_probe();early_quirks();
// 重加载一些 acpi 配置
acpi_boot_init();
x86_dtb_init();get_smp_config();// 为每个acpi表创建fix映射
init_apic_mappings();prefill_possible_map();init_cpu_to_node();
// 将不需要内存的cpu设置 online
init_gi_nodes();io_apic_init_mappings();x86_init.hyper.guest_late_init();
// 为e820_table每个表项分配iomem_resource
e820__reserve_resources();
// 注册电脑休眠状态下不需要保存的内存(ram和kernelreserve以外的内存区域)
e820__register_nosave_regions(max_pfn);
// 为硬件端口分配ioport resource(dma,pic,timer,keyboard,fpu等)
x86_init.resources.reserve_resources();
e820__setup_pci_gap();
x86_init.oem.banner();
x86_init.timers.wallclock_init();
therm_lvt_init();
mcheck_init();
register_refined_jiffies(CLOCK_TICK_RATE);
unwind_init();
}

相关文章:

  • 2023-12-17 LeetCode每日一题(使用最小花费爬楼梯)
  • Linux操作系统( YUM软件仓库技术 )
  • 【数值分析】choleskey分解,matlab实现
  • OpenEular23.09(欧拉)操作系统为企业搭建独立的K8S集群环境,详细流程+截图
  • DS|队列
  • Docker 容器命令总汇
  • 【温故而知新】探讨下对vue的mixin的理解
  • springcloud微服务篇--6.网关Gateway
  • Mybatis 传参的方式
  • 计算机组成原理-总线概述
  • 【数据结构——二叉树】二叉树及其应用2023(头歌习题)【合集】
  • 解决基于VectorGrid的矢量瓦片Y轴偏移的问题
  • 软件有效找不到dll文件,五种可靠的解决dll方法分享
  • Zookeeprt实战(待完善)
  • java虚拟机内存管理
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • create-react-app项目添加less配置
  • CSS 三角实现
  • Electron入门介绍
  • Java方法详解
  • js如何打印object对象
  • magento2项目上线注意事项
  • MySQL QA
  • Terraform入门 - 3. 变更基础设施
  • 阿里云Kubernetes容器服务上体验Knative
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 智能合约Solidity教程-事件和日志(一)
  • Java总结 - String - 这篇请使劲喷我
  • $(function(){})与(function($){....})(jQuery)的区别
  • (02)Hive SQL编译成MapReduce任务的过程
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (3)llvm ir转换过程
  • (pojstep1.1.2)2654(直叙式模拟)
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (三十五)大数据实战——Superset可视化平台搭建
  • (十)c52学习之旅-定时器实验
  • (十三)Maven插件解析运行机制
  • (转)JAVA中的堆栈
  • (转)我也是一只IT小小鸟
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .net 7 上传文件踩坑
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .net Signalr 使用笔记
  • .net生成的类,跨工程调用显示注释
  • [ C++ ] STL_vector -- 迭代器失效问题
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • [202209]mysql8.0 双主集群搭建 亲测可用
  • [2544]最短路 (两种算法)(HDU)
  • [ACM] hdu 1201 18岁生日
  • [Android] Upload package to device fails #2720