初识Linux-在Debian上启动到GNOME界面

久久以前刚准备要从Windows 换到GNU/Linux 时, 才知道有些事并不是那么理所当然. 例如这些Windows 上的大家都这样认为

  • 操作系统升级要重装
  • 操作系统坏掉要重装
  • 换主板驱动不同很可能重装
  • 用久了变慢要重装(那个时代)
  • 安装一些系统更新要重新开机
  • 安装很多大软件后要重新开机

这些在GNU/Linux 上并不一定还需要.

当时没想太多就找了Debian Linux 来安装.用没多久发现有些程序没有或太旧,很快就决定从stable升级到testing;再从testing升到unstable.除了最开始安装Debian potato外,后来都只用到apt-get.等到后来买了本本第二次装Debian,也已经是3年后的事了.而这中间的更新除非有动到kernel,不然也大都也没有重开机.顶多只是重启X server.即使换了CPU跟主板,还是旧硬盘的系统继续用.甚至换硬盘时也只用到cp或dd跟grub-install来迁移系统.一切就像没发生地一样美好.

期间当然有很多次更新后有东西坏掉或不能开机, 但总是幸运地能够修好. 能够做到这点很重要的因素就是对开机流程有基本认识:

Linux启动顺序

Linux启动顺序

知道系统是怎么从你按下开机按钮开始,从 BIOS 到 Bootloader 进到桌面环境, 系统更新后出了问题才不会束手无策. 虽然有时候这比重装或重新开机更花时间.

Bootloader: GRUB

在传统BIOS 的环境, grub 由boot.img 跟core.img 两部份组成. 因为MBR 大小的限制, 只有boot.img 会被写到MBR. 也就是说当BIOS 把MBR 读到内存并跳过去执行时, 实际上是在运行boot.img. 它做的事只是把core.img 最前头的部份读到内存就再跳过去. 而这个最前头的部份才是真正把core.img剩余的部份读完到内存, 并接着执行后才显示出我们熟悉的GRUB开机菜单. 换句话说, grub 的主体是core.img. boot.img 只是为因MBR 大小限制, 而被设计来载入core.img用的.

在系统中, 可以用grub-setup 来把boot.img 写到MBR. core.img 则可以用grub-mkimage 产生. 之所以需要动态产生core.img 是因为依硬盘的分区表 跟 文件系统 不同,我们需要不同的core.img. 不过一般只要执行一个命令grub-install 就会帮我们都处理好.

系统更新后如果重开机不能进GRUB或Kernel,通常是GRUB坏了.这时得用Debian安装光盘或U盘(或其它像是SystemRescueCd )开机.开好机后进终端(Console)把原来的root分区 mount 起来重新运行一次grub-install常常就能解决问题.如果是因为新版grub本身的问题,那要先找旧版的grub (或许还在/var/cache/apt/archives ),装好再跑grub-install.

而在 EFI 的环境, grub 只会有core.img. grub-install 会把core.img 复制到EFI system partition 并设定好EFI boot manager. 要注意的是在执行grub-install 前需要先把EFI system 分区 mount 到/boot/efi 并且载入efivars kernel module. 现在支持EFI的主板慢慢的多起来,但是有使用到EFI来引导的用户还是较少. 

Kernel & initramfs

bootloader 会负责把kernel 跟initramfs 载入到记忆体并执行. 详细的作法规范在Documentation/x86/boot.txt.

没特别设定时kernel image 本身也会带一份空的initramfs, 所以这里的initramfs 指的是external initramfs. 它是独立的一个文件. bootloader 可以透过旧有的initrd 机制把external initramfs 指定给kernel.

kernel 初始化好系统后会去执行第一个user space 的程式: init. 在initramfs 里有/init 这个可执行文件时kernel 会去执行它. 否则kernel 会把root mount 起来, 并执行root 里的/ sbin/init.

initramfs 的/init 如果存在时, 它在做的通常也是把root mount 起来, 并执行root 里的/sbin/init. 之所以会需要initramfs 是因为有些环境, 例如root 在远程(NFS rootfs)时, kernel 做这些事比较麻烦.

kernel 没办法进到user space 常常是因为缺少driver. 最常见的应该是SATA 或filesystem driver 没有被编进kernel 或者没有在initramfs 里.

init: sysvinit

sysvinit之后可能会被Systemd取代(Ubuntu里Init机制用的是Upstart),不过在这之前还是得熟悉sysvinit,毕竟现在不少发行版都还是sysvinit.

sysvinit 的配置在/etc/inittab. 在Debian 里它主要会去执行/etc/rcS.d 跟/etc/rc2.d 里所有的script, 并让使用者可以从tty1 到tty6 登入系统(用户可以通过按组合键Ctrl + Alt + F1-6来切换1-6号不同终端, 一般默认F7是第一个X Server用的). 这些script在做的不外乎是mount filesystem, 对网路, 系统时间等做基本设定, 还有启动系统服务. 很多script 会到/etc/default 底下读设定, 所以可以透过修改/etc/default 里的档案来改变这些script 的行为.

如果开机过程在这个部份出问题时, 可以试着在kernel command line 加上single 进入单人模式或init=/bin/sh 让shell 当init process. 因为这边都是script, 有问题时也比较容易解决.

在一个安装了多个系统的电脑上开机到Windows 后再回来可能会出现的问题是系统时间差了8 小时. 这是因为Debian(大部分Linux) 在把系统时间写到RTC 时会用UTC 时间, 而Windows 会把RTC 的时间当成是UTC+8.如果遇到这个问题可以到/etc/default/rcS 把UTC 设定no.

Display Manager: gdm

gdm (GNOME Display Manager)会把X server 跑起来, 并显示我们熟悉的图形登入画面. 它会扫描

/usr/share/gdm/BuiltInSessions 跟 /usr/share/xsessions

里面的.desktop 档找出系统提供的session. 当我们选好session 并成功登入时, 它会执行

/etc/gdm/Xsession session-name

/etc/gdm/Xsession 这个script 会读入/etc/X11/Xsession.d 底下所有的script. 它们在最后通常会执行类似这样的命令

ssh-agent dbus-launch some-session-manager

让session manager 带出桌面环境来.

如果想要额外设置别的环境变量的话, 可以写在~/.xsessionrc. 或者如果不想运行系统现有的session 的话, 也可以自己写shell script 存成~/.xsession. 如此/etc/gdm/Xsession 最后会改执行~/.xsession 而不是some-session-manager. 这些细节可以在/etc/X11/Xsession.d 里看到.

在Debian 里输入法现在是透过im-config 在管理. 它也是利用Xsession.d 的机制在登入的过程中被运行起来.

 

Session Manager: gnome-session

登录后的桌面环境是由session manager 带出来的. 一般情况gnome-session 会参照/usr/share/gnome-session/sessions/gnome.session 执行gnome-shell 与gnome-settings-daemon. 它同时也会执行

~/.config/autostart /usr/share/gnome/autostart /etc/xdg/autostart

里所有没被disable 的程序. 后者可以利用gnome-session-properties 做修改.

 

gnome-shell 就是眼睛看得到的部分, 这边不提. gnome-settings-daemon 的功能之一是它会监看某些GSettings key 并做回应. 例如在terminal 执行

$ gsettings set org.gnome.desktop.background picture-uri file://<path-to-image>

gnome-settings-daemon 会收到这项改变, 并且把桌面的背景图片换成新指定的图片. 或者执行

$ gsettings set org.gnome.desktop.interface gtk-theme <theme-name>

gnome-settings-daemon 会把新的GTK+ theme name 广播出去. 所有GTK+-based 的程式也会自动换用新的theme.

这些操作相当于Windows系统的修改注册表.

 

想学习Linux的童鞋们,多多试验哦. 不管你是想学习Linux系统编程开发还是想学习Linux系统管理运维,都应该要对Linux系统了如指掌,这样工作才能得心应手. 这一篇就相当于是初识Linux.

Via 戴维营教育

标签: , , ,
文章分类 Linux服务器开发

发表评论