#### 1.为什么内核一开始就是进行一系列的初始化？
从日常生活的角度看，似乎什么东西直接用就好了，没有必要将行初始化。然而如果仔细想想，何止是操作系统启动需要初始化，绝大部分事情都是需要初始化的。并不是操作系统有什么特殊，而是操作系统也没有例外。从cons_init()看，它是在为一系列的静态变量赋值。从pmm_init()看，它创建了连续内存管理的结构和二级映射的结构，是在为寄存器和内存赋值。从pic_init()看，是在向中断控制器赋值。从idt_init()看，它创建了中断映射的结构，是在为内存和寄存器赋值。从vmm_init()看。从proc_init()看。从ide_init()看。从swap_init()看。从clock_init()看，是在向时钟控制器赋值。

#### 2.进程和线程是怎么来的？
1. 在proc_init()函数为内核线程idle和init的TCB分配内存空间，初始化TCB，并将TCB放入链表proc_list和hash_list中。指定当前线程为idle。于是第一个线程就产生了。  
2. 在cpu_idle()函数中，无限循环执行schedule()函数。  
3. schedule()函数通过查询链表proc_list找到下一个可运行的进程，通过proc_run()函数运行此进程。于是第二个线程就开始运行了。  
4. proc_run()函数最终是通过switch_to()函数里的ret指令切换到第二个线程的。  
5. 第二个线程是init_main()，它创建了第三个内核线程user_main()，在do_wait()函数跳转到schedule()函数。  
6. schedule()函数通过查询链表proc_list，开始运行第三个线程user_main()。  
7. 由于宏TEST未定义，所以会执行宏KERNEL_EXECVE(exit),进而执行__KERNEL_EXECVE(),进而执行kernel_execve()，进而通过系统调用执行SYS_exec,进而执行do_execve()。  
8. do_execve()函数释放了当前线程占用的内存资源，转而执行load_icode().  
9. load_icode()重新为本线程分配内存资源，并将用户代码装载入分配的内存中。返回do_execve()，进而返回SYS_exec，进而返回trapentry.S继续执行。  
10. 在trapentry.S里，最终是通过iret指令跳转到用户指令执行的。此时，内核线程转变成了用户进程。

#### 3.为什么进程通信只说同步互斥，而不说异步互斥？
进程天然就是异步的，虽然异步通信互争资源的情况也是存在的，但同步问题更复杂一些，所以只看到说同步而没看到说异步。但个人认为临界区的划分主要是用来解决异步通信问题的，当然也可以解决同步通信的问题，临界区划分主要是通过锁或信号量来实现的。解决同步通信问题主要是管程和信号量。虽然同步和互斥两个词被放到一块，但个人认为它们不是一个层面的概念。同步是更高级别的抽象，而互斥只是实现同步的一种方式。

#### 4.临界区和互斥量的区别是什么？自旋锁和信号量的区别是什么？

#### 5.elf文件里program header和section header区别是什么？在内存里代码和数据都分为不同的段(segment)，那么段在elf文件里怎么体现？
* 通过readelf观察具体的一个elf文件，可见section可分为两种，一种是放入内存的，一种是不放入内存。
* 从section name推测，字符串列表和符号列表是不放入内存的部分。
* 程序头中描述的部分都是要放到内存中的。放入内存中的section看起来像是对程序头更详细的划分，但放入内存中的section并不能覆盖程序头的全部内存区域。
* 在程序头里filesize和memsize大部分情况下都是相等的，但.bss节所在的程序头filesize要比memsize小。
* 综上可见，program header描述的是程序要载入内存的部分，而section描述的是载入内存中各segment的信息和不载入内存的其它信息。

#### 6.操作系统中的堆区、栈区的概念和数据结构中堆、栈的概念是一回事吗？
#### 7.C语言运算符的优先级为什么如此设定？
#### 8.C语言里main函数的参数是怎么来的？
* main函数是由系统调用的
* 输入的命令本身即为第一个参数
#### 9. 操作系统中console和shell的区别？
