好吧,其实也不算新,毕竟部分在C89就有了。
1 | struct arg |
1 | // C89的初始化,按照定义的成员顺序赋值,未指定的会被初始化为0 |
ideal's blog
好吧,其实也不算新,毕竟部分在C89就有了。
1 | struct arg |
1 | // C89的初始化,按照定义的成员顺序赋值,未指定的会被初始化为0 |
如果使用gcc编译,并且链接了C的标准库(crti.o, crt1.o以及libc等),那么此时和编译普通的C程序一样,需要提供一个main的符号。(crt1.o里面有_start,_start会调用__libc_start_main,再调用main)。例如:
1 | # example.s |
Linux 0.11保护模式下能寻址16MB地址空间(虽然地址是32位的)。需要的页表数和页目录表数计算方法:
由于页的大小是4096(2^12),那么需要的页表项目是(2^24/2^12)= 2^12,也就是4096个页表项。
每个页表项是4字节,那么总共的大小就是2^14个字节,也就是16KB,刚好是4页。
所以可以看到,它填充了4个页的页表。
很明显4个页表,只需要页目录里的4项,就可以定位这些页表了。
也可以这样计算:16KB,也就是2^14,(2^14/2^12) = 4。所以只占用了页目录表的前4项。
实际上,4KB大小的页目录表,已经能够寻址4GB的空间了。
2^32 / 2^12 = 2^20
每项4字节,也就是需要4MB的页表。
为了寻址4MB的页表:2^22 / 2^12 = 1024,每个4字节,刚好页目录表是4KB。
参考:
这本书里提到,在内核初始化的过程中,会通过内联汇编从RTC读取当前时间。大概逻辑是:通过汇编,分别读取当前秒、当前分钟、当前小时等。每次读取,先针对IO端口0x70设置读取的寄存器,然后从0x71读出相应的字节。再进行一定的转换。然后调用kernel_mktime()得到一个unix时间戳。
至于为什么是0x70,这里有相关的说明。通过/proc/ioports
也可以看到。
1 | $ cat /proc/ioports |
RTC对应的IO端口地址正是0x70~0x77。