前言

.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. django中使用celery,模拟商品秒杀。

    Celery是Python开发的简单.灵活可靠的.处理大量消息的分布式任务调度模块 安装: pip install celery # 安装celery库 pip install redis # cel ...

  2. 【SSM项目】尚筹网(五)项目改写:使用前后端分离的SpringSecurityJWT认证

    在项目中加入SpringSecurity 1 加入依赖 <!-- SpringSecurity --> <dependency> <groupId>org.spri ...

  3. 扎实打牢数据结构算法根基,从此不怕算法面试系列之004 week01 02-04 使用泛型实现线性查找法

    1.算法描述 在数组中逐个查找元素,即遍历. 2.上一篇文的实现结果 在 扎实打牢数据结构算法根基,从此不怕算法面试系列之003 week01 02-03 代码实现线性查找法中,我们实现了如下代码: ...

  4. AppScan-使用入门

    一.介绍 AppScan是IBM公司出的一款Web应用安全测试工具,采用黑盒测试的方式,可以扫描常见的web应用安全漏洞 工作原理 首先是根据起始页爬取站下所有可见的页面,同时测试常见的管理后台 获得 ...

  5. Vue拖拽排序

    转载至https://www.crazyming.com/note/757/ 使用拖拽功能来实现排序. 需要先学习w3cschool 关于拖拽的教程:http://www.w3school.com.c ...

  6. 2022-11-19:第二高的薪水。表结构和数据的sql语句如下,输出200,因为200是第二大的。请问sql语句如何写? DROP TABLE IF EXISTS `employee`; CREAT

    2022-11-19:第二高的薪水.表结构和数据的sql语句如下,输出200,因为200是第二大的.请问sql语句如何写? DROP TABLE IF EXISTS `employee`; CREAT ...

  7. 2022-10-01:给定一个字符串 s,计算 s 的 不同非空子序列 的个数 因为结果可能很大,所以返回答案需要对 10^9 + 7 取余 。 字符串的 子序列 是经由原字符串删除一些(也可能不删除

    2022-10-01:给定一个字符串 s,计算 s 的 不同非空子序列 的个数 因为结果可能很大,所以返回答案需要对 10^9 + 7 取余 . 字符串的 子序列 是经由原字符串删除一些(也可能不删除 ...

  8. 浅谈如何使用 github.com/yuin/gopher-lua

    最近熟悉 go 项目时,发现项目中有用到 github.com/yuin/gopher-lua这个包,之前并没有接触过,特意去看了官方文档和找了些网上的资料,特此记录下. 本次介绍计划分为两篇文章,这 ...

  9. 【汇编】DOS系统功能调用(INT 21H)

    前言 最近又听了听汇编的课程,发现代码里的MOV xxxxx INT 21H,老师都是一句话带过,而不讲讲其中的原因(也可能前面讲了我没有听QAQ). 顺便夸一下老师,老师懒省事录的视频画质已经成功从 ...

  10. 代码随想录算法训练营Day11 栈与队列|20. 有效的括号  1047. 删除字符串中的所有相邻重复项  150. 逆波兰表达式求值

    20.有效的括号 题目链接:20.有效的括号 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合 ...