Wednesday, March 2, 2011

how gnome starts

关于 Linux 的启动过程,网上有不少资料。比如这个,从按下开机键到创建 TTY 登录界面这个过程讲的很清楚。但是没有讲到这之后发生的故事。gdm 是怎么启动的?X server 又是怎么启动的?

运行下 pstree,会发现这样一个进程树结构。
init-
     |-gdm-binary-+-gdm-simple-slav-+-Xorg
     |            |                 |-gdm-session-wor-+-gnome-session-+-applet.py
     |            |                 |                 |               |-gdu-notificatio
     |            |                 |                 |               |-gnome-panel---{gnome-panel}
     |            |                 |                 |               |-gnome-power-man---{gnome-power-man}
     |            |                 |                 |               |-gnome-volume-co
     |            |                 |                 |               |-kerneloops-appl
     |            |                 |                 |               |-metacity---{metacity}
     |            |                 |                 |               |-nautilus---2*[{nautilus}]
     |            |                 |                 |               |-nm-applet---{nm-applet}
     |            |                 |                 |               |-polkit-gnome-au---2*[{polkit-gnome-au}]
     |            |                 |                 |               |-stardict---4*[{stardict}]
     |            |                 |                 |               `-2*[{gnome-session}]
     |            |                 |                 `-{gdm-session-wor}
     |            |                 `-{gdm-simple-slav}
     |            `-{gdm-binary}

这些是如何发生的?

下边是一个基于 Foresight Linux 的很简单的讲解。但是应该也适用于所有建立在传统的 sysvinit 之上的 Linux 发行版。而至于 upstart 和 systemd 等等就不适用了。

1. init -> /etc/X11/prefdm

我们都知道 kernel 在启动之后,会执行 init 程序。而 init 的行为是由 /etc/inittab 定义的。

我的系统上 inittab 有这样一行:
$ tail -1 /etc/inittab 
x:5:respawn:/etc/X11/prefdm -nodaemon
也就是说在进入 runlevel 5 的时候,init 会调用 /etc/X11/prefdm。这是 X11 目录下的一个文件,我们应该能大体猜出它的用处。

小插曲: 这个文件其实是 initscripts 提供的,
$ conary q --path /etc/X11/prefdm
initscripts:runtime=foresight.rpath.org@fl:2-qa/9.12.1-0.3-1

2. /etc/X11/prefdm -> gdm

/etc/X11/prefdm 是个很短的 shell 脚本。作用很简单,它会依次尝试运行 gdm, kdm 等等。对 GNOME 来说就是相当于 exec gdm。这样 gdm 进程就取代了 prefdm。

3. gdm -> Xorg

你可能发现了,直到现在 X server 还没有启动呢。上边的进程树中也体现出来了,gdm 是 init 的子进程,而 Xorg 是 gdm 的子进程。

gdm 的全称是 GNOME Display Manager,是 X display manager 的一种。维基百科说了,gdm 是对默认的 xdm 的一个更加易用的替换。

那么什么是 X display manager?还看维基百科
When the display manager runs on the user's computer, it starts the X server before presenting the user the login screen
也就是说,gdm 会首先启动 X server (比如在 tty7 上),然后把登录界面显示出来。这样用户就可以登录了。

其实就是这么简单。再输入密码,gnome-session, gnome-panel 等等就会启动,你就能进入到你的桌面了。