前言

.Net8的本地预编机器码AOT,它几乎进行了100%的自举。微软为了摆脱C++的钳制,做了很多努力。也就是代码几乎是用C#重写,包括了虚拟机,GC,内存模型等等。而需要C++做的,也就仅仅是引导程序,本篇通过代码来看下这段至关重要的引导程序的运作模式。原文:.Net8的AOT引导程序BootStrap

概括

所谓的引导程序,也就是引导被ILC生成的目标文件编译成可执行文件,然后在相应的平台上(MacoS/Linux/Win)进行二进制执行。这里以微软自家的Windows平台为例来剖析下这段引导程序。

引导程序分为两个阶段,其一初始化运行时,其二运行托管的Main入口代码。分别看下,最后就是代码展示了。

1.实例化运行时

这个很好理解,你如果需要运行.Net程序那么必须有一个运行的环境,第一步就是初始化这个运行环境。它主要包括以下步骤:

一:环境变量的初始化

环境变量的初始化主要是指设置的环境变量,对于GC或者JIT的控制。在这里进行一个初始化和区分。比如开启了了内存映射的环境变量

DOTNET_EnableWriteXorExecute=1.它就是此时被AOT识别并进行区分。

二:注册AOT的模块

AOT程序需要用到哪些模块,比如

Runtime.WorkstationGC.lib
System.Globalization.Native.Aot.lib
System.IO.Compression.Native.Aot.lib
eventpipe-disabled.lib
Runtime.VxsortDisabled.lib

等一些模块需要用到,那么这里进行注册下,以便后续调用。

三:模块的初始化

这里的模块初始化实际上,R2R的部分预编译函数替代。

2.托管的Main入口

.Net里面托管的Main函数是一切托管函数的入口点,所以托管Main入口是必须设置正确,并且能够运行完整托管代码。本例展示的托管Main如下:

static void Main()
{
Program pm=new Program();
pm = null;
GC.Collect();
Console.WriteLine("This is Ce Shi");
Console.ReadLine();
}

3.代码展示

上面只是一些概念,具体的行为落实,还得代码来。这里看下BootStrap引导程序的代码。

一:节操作:

1.节存变量

主要是在初始化运行时的模块初始化阶段需要用到

#pragma section(".modules$A", read)
#pragma section(".modules$Z", read)
extern "C" __declspec(allocate(".modules$A")) void* __modules_a[];
extern "C" __declspec(allocate(".modules$Z")) void* __modules_z[];
__declspec(allocate(".modules$A")) void* __modules_a[] = { nullptr };
__declspec(allocate(".modules$Z")) void* __modules_z[] = { nullptr };

2.节合并

这里主要是然链接器进行一个节的合并

#pragma comment(linker, "/merge:.modules=.rdata")
#pragma comment(linker, "/merge:.unbox=.text")

3.节声明函数

实例化运行时注册AOT模块的时候要用到

char _bookend_a;
char _bookend_z; #pragma code_seg(".managedcode$A")
void* __managedcode_a() { return &_bookend_a; }
#pragma code_seg(".managedcode$Z")
void* __managedcode_z() { return &_bookend_z; }
#pragma code_seg()

4.AOT运行环境的初始化

static int InitializeRuntime()
{
//环境变量的初始化
if (!RhInitialize())
return -1;
//获取当前模块的句柄
void* osModule = PalGetModuleHandleFromPointer((void*)&__managed__Main); //注册AOT模块
if (!RhRegisterOSModule(
osModule,
(void*)&__managedcode_a, (uint32_t)((char*)&__managedcode_z - (char*)&__managedcode_a),
(void*)&__unbox_a, (uint32_t)((char*)&__unbox_z - (char*)&__unbox_a),
(void**)&c_classlibFunctions, _countof(c_classlibFunctions)))
{
return -1;
}
//初始化需要的模块
InitializeModules(osModule, __modules_a, (int)((__modules_z - __modules_a)), (void**)&c_classlibFunctions, _countof(c_classlibFunctions)); #ifdef NATIVEAOT_DLL
// Run startup method immediately for a native library
__managed__Startup();
#endif // NATIVEAOT_DLL return 0;
}

5.托管入口

return __managed__Main(argc, argv);

以上是.Net8的AOT引导程序的完整运作模式。

结尾

作者:江湖评谈

关注下面公众号:jianghupt。后台回复暗号:AOT。获取全部以上AOT引导程序Bootstrap全部源码。

.Net8的AOT引导程序BootStrap的更多相关文章

  1. 什么是Bootstrap?

    简介 - 框架:库 lib library- jQuery作为一个框架来讲,提供一套比较便捷的操作DOM的方式- 把大家都需要的功能预先写好到一些文件 这就是一个框架- Bootstrap 让我们的 ...

  2. 深入理解SpringCloud之引导程序应用上下文

    tips:我希望通过这篇文章来给对于bootstrap还不理解的朋友带来帮助.当然这篇文章不仅仅是讲解知识,我更希望给广大朋友带来学习与理解官方文档的一种思路.阅读本文前,建议大家对SpringBoo ...

  3. CSS之Bootstrap(快速布局)

    简介 什么是Bootstrap? Bootstrap官网 框架:库 lib library jQuery作为一个框架来讲,提供一套比较便捷的操作DOM的方式 把大家都需要的功能预先写好到一些文件 这就 ...

  4. angular2自学笔记---官网项目(一)

    1.单向数据绑定的'插值表达式' angular中最典型的数据显示方式:把HTML模板(template)的控件绑定到angular组件的属性(component相当于一个构造函数,下面例子中的这个构 ...

  5. pxe网络安装操作系统 原理与详细过程

    摘要:在实际工作中,我们经常会遇到这样的情况:想要安装Linux但是计算机不带光驱或软驱,或者是笔记本配置的非标准的软驱和光驱,如1394接口,USB接口等,在Linux安装时所引导的Linux内核一 ...

  6. VxWorks镜像简介

    VxWorks镜像可分为三类:   可加载型VxWorks镜像:存储在开发机上,运行在板上RAM中   基于ROM的VxWorks镜像:存储在板上ROM,运行在板上RAM中   ROM驻留的VxWor ...

  7. 操作系统内核Hack:(二)底层编程基础

    操作系统内核Hack:(二)底层编程基础 在<操作系统内核Hack:(一)实验环境搭建>中,我们看到了一个迷你操作系统引导程序.尽管只有不到二十行,然而要完全看懂还是需要不少底层软硬件知识 ...

  8. 使用Student T'test方法做性能测试

    性能测试 日常工作中对比函数间的快慢时,最直接的方法就是根据timer:tc/1结果的时间来衡量,比如想知道lists:reverse/1与直接使用自己写的尾递归函数谁更快?最直接的方法就是 -mod ...

  9. BSP

    1       BSP概述 BSP即Board Support Package,板级支持包.它来源于嵌入式操作系统与硬件无关的设计思想,操作系统被设计为运行在虚拟的硬件平台上.对于具体的硬件平台,与硬 ...

  10. CCNA 之 四 管理和配置CISCO设备

    管理和配置CISCO设备 路由器组件 cpu 执行操作系统的指令 随机访问存储器RAM - RAM中内容断电丢失 - 运行操作系统: - 运行配置文件: - IP 路由表: - ARP 缓存; - 数 ...

随机推荐

  1. 靶机渗透【billu_b0x】

    ip扫描 访问80端口 目录扫描 逐个访问 上传一个图片马,结果没有回显 显示file参数为空.请在"文件"参数中提供文件路径 打开发现有用户名 ![] 发现数据库连接的配置信息, ...

  2. 【Ubuntu】 Perf工具的使用

    一.perf工具的安装 sudo apt-get install linux-tools-common sudo apt-get install linux-tools-"$(uname - ...

  3. 基于DotNetCoreNPOI封装特性通用导出excel

    基于DotNetCoreNPOI封装特性通用导出excel 目前根据项目中的要求,支持列名定义,列索引排序,行合并单元格,EXCEL单元格的格式也是随着数据的类型做对应的调整. 效果图: 调用方式 可 ...

  4. Prometheus监控之SNMP Exporter介绍和数据展现

    由于技术能力有限,文章仅能进行简要分析和说明,如有不对的地方,请指正,谢谢. 1 SNMP协议介绍 SNMP协议全称是:Simple Network Management Protocol,译为简单网 ...

  5. elastic-job源码(1)- job自动装配

    版本:3.1.0-SNAPSHOT git地址:https://github.com/apache/shardingsphere-elasticjob   Maven 坐标 <dependenc ...

  6. 重学C++ (一)基础回顾

    由于C++基础非常重要,所以打算把平时重学C++的总结,抽时间上传到博客! 1.切勿乱用带符号类型和无符号类型 #include <iostream> using namespace st ...

  7. css设置单行多行超出显示省略号

    单行: width: 200px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 多行: text-overflow: ...

  8. [ABC270D] Stones

    [ABC270D] Stones 题意 有两个人玩游戏,有 \(n\) 个石子,和一个长度为 \(k\) 的序列,每次可以取 \(a_i\) 个但前提是剩下来的石子数有 \(a_i\) 个,第一个人先 ...

  9. docker部署gitlab CI/CD (二)终篇:部署gitlab runner和添加gitlab-ci.yml文件 终极踩坑版

    关于gitlab部署的教程还好,有的看,但到了cicd环节,简直痛苦面具,教程虽多,但断断续续,先不说大部分都是只截取片段,让人云里雾里,不会的看不懂,懂的不需要看,根据步骤跑不起来不说,改了一堆,完 ...

  10. 推荐一个日历转换开源工具库,支持C#、Java、PHP等主流的语言

    日历对我们来说,最熟悉的就是阳历和农历,在中国每年都有固定的节日.节气.中国特有传统节日,有些节日是固定的,但是节气这些都需要我们经过一定规则换算出来. 所以,今天给大家推荐一个开源库,它支持阳历.阴 ...