Chinaunix首页 | 论坛 | 博客
  • 博客访问: 779211
  • 博文数量: 265
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1985
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-13 12:33
文章分类

全部博文(265)

文章存档

2011年(1)

2010年(66)

2009年(198)

我的朋友

分类: LINUX

2010-06-24 13:39:49

警告:此文不适合普通用户使用,可能造成系统无法启动等严重后果,虽造成数据丢失的可能性很小,但仍请做好备份,谨慎操作!造成的任何损失需自行承担。
背景:
应lerosua和Shan的邀请,写一下这篇文。
之前因为不小心写错源,升级到64位,然后因为一些需要又降到32位的系统。

为啥有这样的需求?
先决条件:
1. 几乎所有开源软件都可以运行在64位系统上,64位系统现在已经足够日常使用;
2. ArchLinux同时支持这两个架构。

好处:
1. 对大内存支持好;
2. 用64位系统能真正发挥出64位CPU的性能;
3. 没有2038问题;
4. 比起重装,需要的设置工作少许多;
5. 好玩。

坏处:
1. 有风险;
2. 需要学习些东西。


正式开始:
一. 基本需求
0. CPU须支持64位,如果不满足这一条,那么请勿进行本文描述的操作。
1. 备份,如果你真的需要,其实这个过程是安全的,除非误操作,不会造成数据的丢失,如果系统里的二进制文件不算的话;
2. 空间需求:视安装的程序多少,需要5G或更多空间来存储pkg,如果从系统安装起没有进行过 pacman -Scc 这样的操作,可以用 du -sh /var/cache/pacman/pkg,查看需要的空间,因为要下载64位的包,所以需要大约同等大小的空间;
3. 时间准备,除去网络下载的时间,约需要一小时。

二. 准备工作
0. 下载i686的软件包,如果你从未运行过 pacman -Scc 或者手工删除包缓存,可跳过此步。
下列包是至少需要的,其实我们升级过程中需要的仅是pacman,源里写的依赖只有bash和libfetch、libarchive,实际现在的pacman依赖许多包,bash除了readline还依赖ncurses:
代码:
pacman glibc libfetch libarchive openssl acl attr xz-utils bzip2 zlib readline bash ncurses

为了安全起见,可以使用如下命令下载系统中已安的所有软件包:
代码:
pacman -Sw $(pacman -Q |awk '{print $1}')


1. 下载x86_64的软件包
注意:此过程中使用的全部都是-Sw,即仅下载,并不安装,千万不要漏了S后面的w,这会导致系统崩溃!
将 /etc/pacman.d/mirrorlist 中正在使用Server中的 i686 改成 x86_64,运行:
代码:
rm -rf /var/lib/pacman/sync/*
pacman -Sy
pacman -Sw $(pacman -Q |awk '{print $1}')

下载 lib32-glibc,这个包是升级唯一必须的32位兼容性包,因为现在的pacman没有了静态编译版本:
代码:
pacman -Sw lib32-glibc


2. 牛刀小试:安装64位内核
内核虽然是命根子,但是Arch中的64位内核是支持32位程序的,先安装个内核玩玩。
代码:
pacman -S kernel26

注意重启计算机,这次重启是必须的。
重启后一般不会有任何异样,可以通过 uname 来检查一下我们现在运行的内核:
代码:
[kangkang@kangkang ~]$ uname -m
x86_64

为了进一步确认,可以安些的静态程序,比如dash或busybox,用file命令可以很直观的看出来它们是个64位程序。
代码:
[kangkang@kangkang ~]$ file /bin/dash
/bin/dash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped

安装busybox还有个好处便是系统坏处许多命令无法使用的时候它能提供许多很有帮助的命令,比如cp、tar 、gzip等。

到目前为止,我们的所有操作都是安全的。经过上面的预热,我们先放松一下,准备更大的挑战。

三. 真正的开始

0. 真正开始前准备
注意:一旦真正开始了从32位到64位的升级,这个过程暂时是无法中止或回退的,如果出现中断,会导致系统无法启动。
需要准备的有:
良好的电源环境/充足的电池,该过程视机器不同,安装的软件包数量,需要10分钟至一小时时间;
打开两个或以上使用root登录的终端或控制台,建议在控制台登录,一般情况下在运行的程序不会因为库被删除而崩溃,但是不排除这种可能性,有些程序比如Fx在升级过程中就可能出现问题;
打开若干喜欢的程序,比如浏览器,IM,音乐播放器等,升级需要时间,这些玩意可以打发这无聊的时间,也能用来缓解一下紧张情绪,还能用来求助;
确认前面的准备工作已完成,用 uname -m 看看是不是运行的 64位内核。

1. 热身运动:安装32位运行库
代码:
pacman -S lib32-glibc

虽然有可能一次成功安装完成所有的包,但我们仍采用循序渐进的方式来做,一可以了解关键步骤,二可以增加挑战性。
这是我们全过程唯一引入的32位运行库。
测试一下:
代码:
/lib/ld-linux-x86-32.so.2 /bin/ls

看着没什么变化,事实上,到现在,我们的系统还是安全的。

2. 安装开始:最重要的包:glibc
除了内核,最最重要的一个包便是它了,几乎所有的程序都依赖它。
注意:再次提醒,这一步开始,系统就随时可能出现问题,请确认操作!
代码:
pacman -S glibc

进行了这个操作之后,你会发现大部分程序都不能运行了,包括 ls、cp等,试试有什么还可以运行的命令。
动手试试,是不是有点紧张了?

3. 来个扇贝:安装最常用最基本的shell:bash 
到了现在,我们用的环境已岌岌可危了,要跟系统直接打交道,离不开shell,而且,它也是Arch的包管理pacman的显式依赖关系之一。
现在的C库是64位的,而我们所有的程序都是32位的,这如果是好呢,还好我们准备了32位运行库,用它来运行 pacman :
/lib/ld-linux-x86-32.so.2 /usr/bin/pacman -S readline bash ncurses
好了,现在我们的bash又回来了,小心的敲下:
代码:
bash

将会看到:
代码:
[root@kangkang ~]#

似乎还是没有变化。在上一步运行过bash的同学们,心里应该平静一些了。

4. Arch的基础:吃豆豆
包管理现在仍可以运行,甚至,在上面那个新运行过一次bash的环境中可以像完全没有任何改变的方式运行,直接敲 pacman 也是正常的。然而,我们需要64位的系统!不可以停在这里。
代码:
pacman -S libarchive libfetch pacman openssl acl attr xz-utils bzip2 zlib

故障排除:若不能直接运行,可用 /lib/ld-linux-x86-32.so.2 /usr/bin/pacman 的方式来运行。
注意:这是个危险的操作,不可以少任何一个包,不可以中断,否则你的吃豆豆就玩不下去了~
完成了之后,pacman就可以以原生64位的方式运行了。
用 ldd 看看,是不是后面的地址长了很多?
代码:
[root@kangkang ~]# ldd /usr/bin/pacman
        linux-vdso.so.1 =>  (0x00007fff8c5ff000)


5. 吃豆豆:吃掉所有的豆豆
有了 pacman,所有的包都不是问题啦,下面就开始吧:
代码:
pacman -S $(pacman -Q|busybox awk '{print $1}')

如果安装了aur中的包,或手工安装了一些软件,那么这步会中止,请先删掉这些包,最基本的,很可能是安装了 codecs,而64位源中没有这个包。经过几次递归操作,这个过程应该很快就开始了,它需要一些时间来完成。
这时,我们前面准备的IM,浏览器,播放器,就可以派上用场了,先玩一会儿吧。中途如果某个程序挂掉,突然消失等,请不用紧张。

6. 紧张的时刻:Don't panic
安装过程顺利完成后,最最紧张的时刻来了:重启计算机。
我们能做的,就是默默等待它的启动,而我们盼来的,将不是kernel panic,所以,我们也不用panic。

到这,我们就成功的把32位的ArchLinux升级到64位啦,享受64位系统给您带来的快乐与麻烦吧!

四. 故障排除和清理
本章介绍的内容不仅仅是故障排除和清理,还将有些关于Arch及Linux系统的说明。
如果仅仅是升级,不必看本章内容,除非:
升级过程中,发生了错误;
想要个所谓的“纯净”的系统。

1. 清理工作
有人有洁癖,喜欢一个“纯净”的64位系统,很遗憾的告诉你,用Arch的方式做到这点几乎是不可能的,至少,它的内核是支持32位程序运行的。
能做的只尽量不使用32位的程序。
到了现在,我们的系统已经是完整的64位环境了,可以去掉32位的glibc兼容性支持了:
代码:
pacman -Rcsn lib32-glibc

至此,一个“纯净”的64位ArchLinux系统就完成了。
可以用下面的命令检查一下是否还有残留的32位包:
代码:
LC_ALL=C pacman -Qi|egrep "Name|^$|Arch" | grep i686 -B 1 | grep Name | awk '{print $3}'

如果有,可以用pacman删除。



2. 故障排除
故障排除是个复杂的工作,在升级过程中,一旦换掉了glibc,出现故障的可能性就很大,因为此时系统的运行,用了不少`trick',比如在运行时删除替换文件,使用32位兼容的glibc来运行程序。下面来分解介绍:
i. 关于内核与libc和程序之间
内核是系统的基础的基础,64位的内核+64位的libc和64位的程序可以运行,64位内核+32位的libc和32位的程序也可以运行,还可以直接在64位内核上直接运行静态的32位或64位的程序;而32位的内核则不能运行64位的libc和64位的程序。认识了到这一点,那么第一次重启的原因就可以理解了,这也是我们可以升级的基础。
实际上,除了依赖libc,很多程序还依赖其它库。

ii. 动态链接程序与lib之间的关系
动态链接的程序需要各种动态链接库的支持,我们可以用ldd来查看,比如:
代码:
$ ldd `which pacman`
        linux-vdso.so.1 =>  (0x00007fff015be000)
        libalpm.so.4 => /usr/lib/libalpm.so.4 (0x00007f19f4097000)
        libc.so.6 => /lib/libc.so.6 (0x00007f19f3d44000)
        libfetch.so => /usr/lib/libfetch.so (0x00007f19f3b35000)
        libarchive.so.2 => /usr/lib/libarchive.so.2 (0x00007f19f38ff000)
        /lib/ld-linux-x86-64.so.2 (0x00007f19f42b8000)
        libssl.so.0.9.8 => /usr/lib/libssl.so.0.9.8 (0x00007f19f36b0000)
        libcrypto.so.0.9.8 => /usr/lib/libcrypto.so.0.9.8 (0x00007f19f3322000)
        libacl.so.1 => /lib/libacl.so.1 (0x00007f19f311b000)
        libattr.so.1 => /lib/libattr.so.1 (0x00007f19f2f17000)
        liblzma.so.0 => /usr/lib/liblzma.so.0 (0x00007f19f2cf7000)
        libbz2.so.1.0 => /lib/libbz2.so.1.0 (0x00007f19f2ae7000)
        libz.so.1 => /usr/lib/libz.so.1 (0x00007f19f28d2000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007f19f26ce000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007f19f24b3000)

通过这个,加上一些脚本处理,就可以得到`隐含‘的依赖关系:
代码:
[kangkang@kangkang ~]$ pacman -Qo $(ldd `which pacman`|awk '{print $3}'|grep "^/"|sort |uniq )
/lib/libacl.so.1 属于 acl 2.2.47-2
/lib/libattr.so.1 属于 attr 2.4.43-1
/lib/libbz2.so.1.0 属于 bzip2 1.0.5-4
/lib/libc.so.6 属于 glibc 2.10.1-4
/lib/libdl.so.2 属于 glibc 2.10.1-4
/lib/libpthread.so.0 属于 glibc 2.10.1-4
/usr/lib/libalpm.so.4 属于 pacman 3.3.2-1
/usr/lib/libarchive.so.2 属于 libarchive 2.7.1-1
/usr/lib/libcrypto.so.0.9.8 属于 openssl 0.9.8k-4
/usr/lib/libfetch.so 属于 libfetch 2.25-1
/usr/lib/liblzma.so.0 属于 xz-utils 4.999.9beta-1
/usr/lib/libssl.so.0.9.8 属于 openssl 0.9.8k-4
/usr/lib/libz.so.1 属于 zlib 1.2.3.3-3

依据这个结果,加上pacman -Qi的结果,我们就可以做出一个完整的依赖关系,这就是前面所见的。

iii. 动态程序与静态程序
之前的过程中,有若干次提到动态链接的程序和静态链接的程序,我们使用的大多数程序使用的都是动态的。使用 file命令可看出来这些信息:
代码:
[kangkang@kangkang /]$ file /usr/bin/qemu
/usr/bin/qemu: ELF [color=#FF0000]32-bit[/color] LSB executable, Intel 80386, version 1 (SYSV), [color=#FF4000]dynamically [/color]linked (uses shared libs), for GNU/Linux 2.6.18, stripped
[kangkang@kangkang /]$ file /bin/busybox
/bin/busybox: ELF [color=#FF0000]64-bit [/color]LSB executable, x86-64, version 1 (SYSV), [color=#FF4000]statically[/color] linked, for GNU/Linux 2.6.18, stripped

不仅可以看出来是动态还是静态的,还能知道是32位还是 64位的。

动态链接程序不但可以节省磁盘的空间,还可以节省内存的使用。然后还是有少量程序却是静态的,它们有个好处:在库被破坏时仍然可以运行,比如busybox,它包含了大量的程序,可以通过做所需命令的符号链接或运行 busybox 命令的方式来执行:
代码:
$ ln -s /bin/busybox ls 
$ ./ls
bin dev ...

$ busybox ls
bin dev ...

对于动态链接程序,动态调用库的过程是由ld-linux来完成的,装有32位运行库时,会有/lib/ld-linux-x86-32.so.2:
代码:
[kangkang@kangkang /]$ ls /lib/ld-* -lh
-rwxr-xr-x 1 root root 138K  8月 23 22:24 /lib/ld-2.10.1.so
lrwxrwxrwx 1 root root   20 10月 17 19:31 /lib/ld-linux.so.2 -> ld-linux-x86-32.so.2
lrwxrwxrwx 1 root root   28  8月 25 03:11 /lib/ld-linux-x86-32.so.2 -> /opt/lib32/lib/ld-linux.so.2
lrwxrwxrwx 1 root root   12  8月 23 22:24 /lib/ld-linux-x86-64.so.2 -> ld-2.10.1.so

对于ELF格式的动态链接程序,程序本身会有默认的请求的解释器:
代码:
[kangkang@kangkang /]$ readelf -a /bin/bash|grep /lib
      [Requesting program interpreter: /lib/ld-linux-x86-64.so.2]
[kangkang@kangkang /]$ readelf -a /usr/bin/qemu|grep /lib
      [Requesting program interpreter: /lib/ld-linux.so.2]

可以看到32位程序请求的解释器和我们期待的不一样,所以上面的程序可能会需要指定解释器来运行,就好比脚本语言,对于shell程序可以用 bash cmd,对于python可以使用 python -c 这样的样式来运行一样。
注意:这样运行程序需要使用绝对或相对路径,解释器不会去识别PATH参数。

iv. ArchLinux的包
ArchLinux使用的是tar.gz来做包,这就给我们提供了很大便利,在pacman坏掉的时候,可以用gzip和tar来安装软件,举例来说,如果pacman这个包坏了,可以使用下面的命令来重新安装它:
代码:
[kangkang@kangkang shm]$ busybox cp /var/cache/pacman/pkg/pacman-3.3.2-1-i686.pkg.tar.gz .
[kangkang@kangkang shm]$ busybox gzip -d pacman-3.3.2-1-i686.pkg.tar.gz
[kangkang@kangkang shm]$ busybox tar xf pacman-3.3.2-1-i686.pkg.tar -C /

用这种方法,将前述的pacman依赖的包都重安装一下,可以至少修复出一个可用的pacman来。

v. ArchLinux的命脉
对于ArchLinux本身来说,什么才是最关键的地方呢?答案是:
代码:
/var/lib/pacman/local/

这里保存了系统中所有已安装包的信息。具体的,有兴趣的可以去看看,都是以目录和文本的方式储存的。


后记
拥有了这些知识,Linux,至少是ArchLinux,对于你来说,就成了不死鸟,无论怎样,都可以恢复,所以说,没有修理不好的Linux系统。

PS:这篇文还有个姊妹篇,即把ArchLinux从64位降级到32位。
阅读(3027) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~