Windows下有两大子系统:win32和console
win32
子系统为win32的程序一般都是窗口程序,进程启动时默认不创建控制台窗口,而是需要GUI线程自己创建窗口,并从自己的消息队列中不断地获取消息、翻译消息、分发消息、处理消息来维持一个窗口的各种状态
console
子系统为console的程序是控制台程序,进程启动时系统会为其创建一个控制台窗口(就是cmd.exe那样的黑框框),这个黑框框不简单,它兼容了GUI操作系统出现之前的程序交互模型:stdin、stdout、stderr
win10的linux子系统
前两个子系统所运行的可执行文件都是Windows自家的PE格式文件,子系统类型记录在PE文件的一个字段里,系统创建进程时会根据子系统类型初始化相应的程序
linux子系统与前两个不同,系统创建的进程是原生的linux的ELF格式的可执行文件,而且为其模拟了一个linux的文件系统
不过还是可以在任务管理器里看到所创建的linux进程的ID,这个进程应该是真实地存在于Windows内核里的,服从Windows内核的调度
总结
Windows内核提供系统调用,子系统本质上是一系列函数库,这些函数封装了系统调用,向上给应用程序提供相应子系统的二进制界面(API接口)
比如win32子系统最基本的三个函数库:kernel32.dll、user32.dll、gdi32.dll;console子系统最基本的函数库:kernel32.dll
linux这个子系统比较复杂,微软提供的唯二的接口是两个程序:bash.exe和lxrun.exe。通过前者进入linux子系统的bash shell,后者用来管理子系统(安装、卸载、更新软件包)。
通过dumpbin发现bash.exe的子系统还是console(Windows CUI),看来Windows将启动子系统的所有细节都放在这个bash.exe里了,而它是闭源的,所以具体是怎样启动的也不是很清楚(但是也可以通过逆向工程的手段得知)。