Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行。
fork里copy了父进程的信息,并激活task放到运行队列,当系统发生调度并获得执行机会时开始执行,但这时还不是hello程序,search_binprm_handler找到的是下面这样一个结构体,load_elf_binary才真正的加载了hello文件。
static struct linux_binfmt elf_format = {
.module = THIS_MODULE,
.load_binary = load_elf_binary,
.load_shlib = load_elf_library,
.core_dump = elf_core_dump,
.min_coredump = ELF_EXEC_PAGESIZE,
};
load_elf_binary加载过程中会从ELF文件中获取text、data、bss等段的信息,加载完成之后hello的虚拟内存布局里就是下面这个样子,实际上所有进程的内存布局都是这样,在进程栈里保存了返回地址、argv、envp等信息。
这样一个程序就具备了可以运行的全部条件,在load_elf_binary的最后会调用start_thread->start_thread_common(),改写CPU的寄存器,真正把hello运行起来。
linux程序是如何开始运行的? - 知乎
相对于freeRTOS, 任务在编译前定义好,然后freeRTOS在xCreateTask()里面把任务添加到freeRTOS内核中,linux内核通过shell这个内核与用户交互的接口,动态的加入到任务列表里面。所以freeRTOS更适合小型的嵌入式硬件(功能不复杂,内存较小,处理能力不强)中。