Chinaunix首页 | 论坛 | 博客
  • 博客访问: 407706
  • 博文数量: 48
  • 博客积分: 764
  • 博客等级: 上士
  • 技术积分: 1133
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-17 13:29
文章分类

全部博文(48)

文章存档

2014年(5)

2013年(34)

2012年(9)

分类: LINUX

2013-02-21 17:20:03



initrd

initrd 本质上就是ramdisk,用来存储数据的。至于是什么数据,就是硬盘上的整个文件系统的阉割版,简而言之就是Busybox,王家卫的《一代宗师》给我的感觉,反胃!赵本山说一个门派,要有人做里子,有人做面子。面子要光彩夺目,容不的不干净的东西。里子就要去面子做下三烂的勾当。内核要自己纯净一些,不要杂七乱八的东西。initrd就是里子,就要替内核着想。系统启动时需要挂载文件系统,可是文件系统是在硬盘上的,需要驱动。所以initrd里面就包含了kernel需要用到的驱动。等kernel用驱动挂载了文件系统,initrd就被卸磨杀驴了。

如何制作initrd, dd 、编译并copy busybox,到dd出来的文件里,这就ok了。


Bootstrap parameters

splash: 貌似是背景吧。

Ramdisk

What is a RAM disk? A RAM disk is a portion of RAM which is being used as if it were a disk drive. RAM disks have fixed sizes, and act like regular disk partitions. Access time is much faster for a RAM disk than for a real, physical disk. However, any data stored on a RAM disk is lost when the system is shut down or powered off. RAM disks can be a great place to store temporary data.

mkfs.ext4 /dev/ram0 & mount /dev/ram0 /mnt



Kbuild


initcall

#define pure_initcall(fn) __define_initcall("0",fn,0)
#define core_initcall(fn) __define_initcall("1",fn,1)
#define core_initcall_sync(fn) __define_initcall("1s",fn,1s)
#define postcore_initcall(fn) __define_initcall("2",fn,2)
#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
核心思想就是把所有的init函数编译相同的segment里,内核启动时do_one_initcall调用,从0开始执行。
特别说下pure表示不需要其他的依靠,可以直接执行。可是net_ns_init和net_dev_init反了吧。


Kernel logging

 /proc/sys/kernel/printk

dmesg


hlist

hlist_node的成员有一个hlist_node ** pprev,不是普通的一级指针。为什么这样?原因还得从内存紧张说起,hlist_head,只有一个fist指针,为了省内存。既然是循环链表那么第一个hlist_node就得指向即头,可类型是hlist_head,这样hlist_node再用prev指向hlist_head就不和谐了,可是头有一个hlist_node的指针,每个节点也有这个指针所以pprev指向next的地址。
另见这里


Notifier chains
只是简单的事件相应机制,核心还是callback函数没有什么新意。callback函数会被封装到notifier_block当中。显然我们会把由联系的notifier_block,放到一个链表。为什么放到一块,效率!struct raw_notifier_head 就是这个集合的头!notifier block分为4类,atomic在中断中,blocking进程上下文中,raw你自己看着用,sruc这种还不理解Sleepable Read-Copy Update mechanism 自己google吧。操作notifier_chain_register()用来注册nb,notifier_chain_register一般由驱动调用,唤醒notifier block的callback function。当然内核也会调用。

Variable arguments

我又一次将问题复杂化了。

typedef char *va_list;

//向上 or 向下对齐大小
#define  _AUPBND                (sizeof (acpi_native_int) - 1)
#define  _ADNBND                (sizeof (acpi_native_int) - 1)

//对齐后的size
#define _bnd(X, bnd)            (((sizeof (X)) + (bnd)) & (~(bnd)))

//va_arg, 很巧。先加上一个size,ap指向下一个参数,之后减去一个size,再取值,即ap旧的值。
#define va_arg(ap, T)           (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
#define va_end(ap)              (void) 0

//指向第二个参数,你还记得x86是如何传参的吗?先压右面的参数。为什么不是左面?stack是从高向低生长的!

//也正因为这样的入栈方式,最后入栈的是参数列表上的第一个参数(下例的“1”)在stack的低地址处。通过这个地址找到全部参数,这就是Variable arguments的红肚兜,其实没什么。

#define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
For example:void arg_test(1, 2, 3, 4)

void arg_test(int i, ...)//从下面的调用可知 i == 1,  ... == 2 3  4

{va_list va; //临时指针,起到迭代器的作用。

va_start(va, i); // va == &2, 

va_arg(va,int);//返回值 2,va ==&3

va_arg(va,int);//返回值 3, va== &4

va_end(va);

}


Terminal

最开始,在股票市场,typewriter + wires + ticker tape priter。 很简单的组合,目地就是为了打印出股票价格。

后来,概念被拓展了涉及到网络Teletype + telex(网络) ,此时还是和计算机没关系。

事情变味了,Terminal(VT-100)+ wires + computer(可多任务的大型机)

一发不可收拾,Keboard,VGA monitor + Terminal emulator(in computer)

linux console 和 gnome terminal 都是 terminal emulator,功能上是没有区别的, 实现上console是由 kenrel 提供。 gnome-terminal是构筑在 X上的。


tty

Virtual console: 

/dev/tty1 就是virtual console对应Ctrl + alt + F1, X出现后virtual console用的就少了。

/dev/tty0 从用户角度看正在使用(foreground)的virtual console前使用的virtual console,tty0 只能指代virtual console,不能指代X下的pty。

/dev/tty  在进程的task_struct 会保存一个使用的终端,tty就关联到进程里的这个终端。从进程角度出发,和用户正在使用那个foreground 终端无关,可以代表virutal console 和pty 等

区分tty 和tty 0

/dev/console  就是内核启动命令的传参那个,一般和tty0一样,可能指定为ttys0.




Carriage return

Typewriter’s carriage /r 13

Line feed /n 10

newline linux /n windows /r/n


 

 指pid 1到桌面启动过程。
SysVinit:最早的init,已被各种替代。
Upstart:origin form ubuntu
/etc/init: system job is where the upstart init configs live. While they are not scripts themselves, they essentially execute whatever is required to replace sysvinit scripts.
/etc/init.d is where all the traditional sysvinit scripts and the backward compatible scripts for upstart live. The backward compatible scripts basically run
service myservice start instead of doing anything themselves. Some just show a notice to use the "service" command.
reboot -> runlevel RUNLEVEL=6 PREVLEVEL=2 -> /etc/init/rc.conf -> /etc/init.d/rc with 6 -> /etc/rc6.d/*
init -> init.d -> rcN.d
rc.local
systemd:Fedora 15 and next RHEL 7 will used it






sentinel

阅读(3495) | 评论(0) | 转发(0) |
1

上一篇:MIPS

下一篇:Performance testing

给主人留下些什么吧!~~