为了在最短的时间内掌握Cygwin原理,我选择了MSYS的源代码来进行分析研究。
以下内容仅为阅读代码时做的笔记,非文献。
当一个Cygwin程序运行时,首先到达mainCRTStartup ()这个入口函数,属于newlib,在newlib的crt0.c里。
mainCRTStartup ()调用msys_crt0或者cygwin_crt0,并传递main函数的地址。
msys_crt0调用了_msys_crt0_common 和 dll_crt0__FP11per_process。
在_msys_crt0_common()里,主要给per_process结构分配空间,然后初始化结构的数据内容。
进入dll_crt0__FP11per_process()后,就不会再返回了。
接着来到_dll_crt0(),获取环境变量和进程信息,通过set_console_handler设置终端IO文件。随后调用dll_crt0_1()
在dll_crt0_1里,设置了异常处理函数,初始化resourcelocks和threadinterface,似乎给线程都分配了名字。
调用了host_dependent.init (),不知道干了什么。
调用memory_init(),若是第一次加载dll,会创建一片共享内存区域。
调用events_init()初始化。
如果是使用fork创建的子进程,则跳到指定的地址去执行。否则,执行下面初始化:
Cygwin进程列表初始化,dtable初始化,信号处理初始化,tty初始化。
对命令行参数的路径进行转换。
调用stdio_init()设置标准的输出输入描述符表。
至此,基本上完成了Cygwin的数据初始化。
最后调用dlls.init (),调用各个premain函数。调整到user_data->main去执行。
至此,我大致已经清楚了Cygwin的启动流程,可以去尝试自己写一个运行库了
经过一晚奋战,结果如下,成功执行MSYS的env.exe程序。