经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Bootstrap » 查看文章
.Net8的AOT引导程序BootStrap
来源:cnblogs  作者:江湖评谈  时间:2023/7/14 10:22:46  对本文有异议

前言

.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程序需要用到哪些模块,比如

  1. Runtime.WorkstationGC.lib
  2. System.Globalization.Native.Aot.lib
  3. System.IO.Compression.Native.Aot.lib
  4. eventpipe-disabled.lib
  5. Runtime.VxsortDisabled.lib

等一些模块需要用到,那么这里进行注册下,以便后续调用。
三:模块的初始化
这里的模块初始化实际上,R2R的部分预编译函数替代。

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

  1. static void Main()
  2. {
  3. Program pm=new Program();
  4. pm = null;
  5. GC.Collect();
  6. Console.WriteLine("This is Ce Shi");
  7. Console.ReadLine();
  8. }

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

一:节操作:
1.节存变量
主要是在初始化运行时的模块初始化阶段需要用到

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

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

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

3.节声明函数
实例化运行时注册AOT模块的时候要用到

  1. char _bookend_a;
  2. char _bookend_z;
  3. #pragma code_seg(".managedcode$A")
  4. void* __managedcode_a() { return &_bookend_a; }
  5. #pragma code_seg(".managedcode$Z")
  6. void* __managedcode_z() { return &_bookend_z; }
  7. #pragma code_seg()

4.AOT运行环境的初始化

  1. static int InitializeRuntime()
  2. {
  3. //环境变量的初始化
  4. if (!RhInitialize())
  5. return -1;
  6. //获取当前模块的句柄
  7. void* osModule = PalGetModuleHandleFromPointer((void*)&__managed__Main);
  8. //注册AOT模块
  9. if (!RhRegisterOSModule(
  10. osModule,
  11. (void*)&__managedcode_a, (uint32_t)((char*)&__managedcode_z - (char*)&__managedcode_a),
  12. (void*)&__unbox_a, (uint32_t)((char*)&__unbox_z - (char*)&__unbox_a),
  13. (void**)&c_classlibFunctions, _countof(c_classlibFunctions)))
  14. {
  15. return -1;
  16. }
  17. //初始化需要的模块
  18. InitializeModules(osModule, __modules_a, (int)((__modules_z - __modules_a)), (void**)&c_classlibFunctions, _countof(c_classlibFunctions));
  19. #ifdef NATIVEAOT_DLL
  20. // Run startup method immediately for a native library
  21. __managed__Startup();
  22. #endif // NATIVEAOT_DLL
  23. return 0;
  24. }

5.托管入口

  1. return __managed__Main(argc, argv);

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


结尾

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

原文链接:https://www.cnblogs.com/tangyanzhi1111/p/17541637.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号