20.构建LFS系统──配置系统启动脚本(二)
时间:2006-11-17 来源:anima
二十、构建LFS系统──配置系统启动脚本(二 )
9.Bash Shell启动文件
使用 /bin/login 读取 /etc/passwd 文件成功登录后,启动了一个交互登录 shell 。用命令行可以启动一个交互非登录 shell(例如 [prompt]$/bin/bash)。非交互 shell 通常出现在 shell 脚本运行的时候,之所以称为非交互的,因为它正在运行一个脚本,而且命令与命令之间并不等待用户的输入。
要获得更多信息,请运行 info bash 以参考 Bash Startup Files and Interactive Shells 小节。
当以交互登录方式运行 shell 的时候,会读取 /etc/profile 和 ~/.bash_profile 文件。
下面是一个基本的 /etc/profile 文件,设置了本地语言支持所必需的环境变量,适当设置这些变量会导致:
-
程序将产生翻译成本地语言的输出
-
正确的将字符分类为字母、数字和其它类,这样做是必要的,可以让 bash 在非英语 locale 下正确接收命令行输入的非 ASCII 字符。
-
为指定的国家设置正确的字母排序
-
适当的默认页面大小
-
为货币、时间和日期值设置正确的格式
这个脚本还设置了 INPUTRC 环境变量,让 Bash 和 Readline 使用我们先前创建的 /etc/inputrc 文件。
把下面的 [ll] 换成您想要设置的两个字母的语言代码(例如"en"),把 [CC] 换成适当的两个字母的国家代码(例如"GB"),把 [charmap] 换成规范的字符映射表。
Glibc 支持的所有 locales 列表可以使用下列命令获得:
locale -a
很多 locale 有许多别名,比如"ISO-8859-1"也被称为"iso8859-1"和"iso88591"。一些应用程序不能正确的处理这些别名,所以安全的做法是使用 locale 的规范名称。要确定正确的规范名称,运行下面的命令,并把其中的 [locale name] 替换成 locale -a 命令的输出中你感兴趣的 locale (在这个例子中是"en_GB.iso88591")。
LC_ALL=[locale name] locale charmap
对于"en_GB.iso88591" locale ,上面的命令将会打印:
ISO-8859-1
这样你就得到了正确的 locale 设置是"en_GB.ISO-8859-1"。将使用上述试探方法得到的 locale 在添加进 Bash 启动文件前做充分的测试是很重要的。
LC_ALL=[locale name] locale country
LC_ALL=[locale name] locale language
LC_ALL=[locale name] locale charmap
LC_ALL=[locale name] locale int_curr_symbol
LC_ALL=[locale name] locale int_prefix
上述命令将会打印与 [locale name] 对应的国家和语言名称、使用的字符编码、货币符号、国际长途电话号码前缀。如果上述命令中的任意一个出现了类似下面的错误信息,则表明你该 locale 要么在 安装系统基础软件 中没有安装,要么不被 Glibc 的默认安装支持。
locale: Cannot set LC_* to default locale: No such file or directory
在这种情况下,你应当要么使用 localedef 命令安装相应的 locale ,要么选择一个其他的 locale 。接下来的指令都将假定 Glibc 没有出现上述错误信息。
一些 LFS 基本系统之外的软件包可能并不支持你选择的 locale 。一个例子就是 X 库(X Window System 的一部分),它会输出如下信息:
Warning: locale not supported by Xlib, locale set to C
有时可以通过移除该 locale 的字符映射(charmap)定义部分来解决这个问题——只要这样做不会改变 Glibc 中与该 locale 关联的字符映射关系(这个可以通过对两个 locale 运行 locale charmap 命令来检查)。例如将"de_DE.ISO-8859-15@euro"修改为"de_DE@euro"即可让这个 locale 被 Xlib 正确识别。
其他一些软件包在你选择的 locale 出乎其意料的情况下可能即使运行异常也不会显示错误信息。在这种情况下,研究一下其他 Linux 发行版是如何支持你选择的 locale 可能会得到更加有用的信息。
一旦确定了正确的 locale 设置,创建 /etc/profile 文件:
cat > /etc/profile << "EOF"
# Begin /etc/profile
export LANG=<ll>_<CC>.<charmap><@modifiers>
export INPUTRC=/etc/inputrc
# End /etc/profile
EOF
"C"(默认)和"en_US"(美国英语用户的推荐值)这两个 locale 是不同的。
设 置键盘布局、屏幕字体和 locale 相关的环境变量,是使用一般的单字节编码和从左至右书写方式地区所需的国际化步骤。更复杂的情况(包括基于 UTF-8 的 locale)需要更多的步骤和补丁,因为这种情况下许多程序可能工作不正常。这些步骤和补丁没有包含在本书里,因此 LFS 无法支持这些 locale 。
显示Glibc支持的所有locales:
root:/sources/lfs-bootscripts-6.2# locale -a
C
POSIX
aa_DJ
aa_DJ.iso88591
aa_DJ.utf8
aa_ER
aa_ER.utf8
aa_ER.utf8@saaho
aa_ER@saaho
aa_ET
aa_ET.utf8
af_ZA
af_ZA.iso88591
af_ZA.utf8
am_ET
am_ET.utf8
an_ES
an_ES.iso885915
an_ES.utf8
ar_AE
ar_AE.iso88596
ar_AE.utf8
ar_BH
ar_BH.iso88596
ar_BH.utf8
ar_DZ
ar_DZ.iso88596
ar_DZ.utf8
ar_EG
ar_EG.iso88596
ar_EG.utf8
ar_IN
ar_IN.utf8
ar_IQ
ar_IQ.iso88596
ar_IQ.utf8
ar_JO
ar_JO.iso88596
ar_JO.utf8
ar_KW
ar_KW.iso88596
ar_KW.utf8
ar_LB
ar_LB.iso88596
ar_LB.utf8
ar_LY
ar_LY.iso88596
ar_LY.utf8
ar_MA
ar_MA.iso88596
ar_MA.utf8
ar_OM
ar_OM.iso88596
ar_OM.utf8
ar_QA
ar_QA.iso88596
ar_QA.utf8
ar_SA
ar_SA.iso88596
ar_SA.utf8
ar_SD
ar_SD.iso88596
ar_SD.utf8
ar_SY
ar_SY.iso88596
ar_SY.utf8
ar_TN
ar_TN.iso88596
ar_TN.utf8
ar_YE
ar_YE.iso88596
ar_YE.utf8
az_AZ.utf8
be_BY
be_BY.cp1251
be_BY.utf8
bg_BG
bg_BG.cp1251
bg_BG.utf8
bn_BD
bn_BD.utf8
bn_IN
bn_IN.utf8
bokmal
bokm錶
br_FR
br_FR.iso88591
br_FR.iso885915@euro
br_FR.utf8
br_FR@euro
bs_BA
bs_BA.iso88592
bs_BA.utf8
byn_ER
byn_ER.utf8
ca_ES
ca_ES.iso88591
ca_ES.iso885915@euro
ca_ES.utf8
ca_ES@euro
catalan
croatian
cs_CZ
cs_CZ.iso88592
cs_CZ.utf8
cy_GB
cy_GB.iso885914
cy_GB.utf8
czech
da_DK
da_DK.iso88591
da_DK.utf8
danish
dansk
de_AT
de_AT.iso88591
de_AT.iso885915@euro
de_AT.utf8
de_AT@euro
de_BE
de_BE.iso88591
de_BE.iso885915@euro
de_BE.utf8
de_BE@euro
de_CH
de_CH.iso88591
de_CH.utf8
de_DE
de_DE.iso88591
de_DE.iso885915@euro
de_DE.utf8
de_DE@euro
de_LU
de_LU.iso88591
de_LU.iso885915@euro
de_LU.utf8
de_LU@euro
deutsch
dutch
eesti
el_GR
el_GR.iso88597
el_GR.utf8
en_AU
en_AU.iso88591
en_AU.utf8
en_BW
en_BW.iso88591
en_BW.utf8
en_CA
en_CA.iso88591
en_CA.utf8
en_DK
en_DK.iso88591
en_DK.utf8
en_GB
en_GB.iso88591
en_GB.utf8
en_HK
en_HK.iso88591
en_HK.utf8
en_IE
en_IE.iso88591
en_IE.iso885915@euro
en_IE.utf8
en_IE@euro
en_IN
en_IN.utf8
en_NZ
en_NZ.iso88591
en_NZ.utf8
en_PH
en_PH.iso88591
en_PH.utf8
en_SG
en_SG.iso88591
en_SG.utf8
en_US
en_US.iso88591
en_US.utf8
en_ZA
en_ZA.iso88591
en_ZA.utf8
en_ZW
en_ZW.iso88591
en_ZW.utf8
es_AR
es_AR.iso88591
es_AR.utf8
es_BO
es_BO.iso88591
es_BO.utf8
es_CL
es_CL.iso88591
es_CL.utf8
es_CO
es_CO.iso88591
es_CO.utf8
es_CR
es_CR.iso88591
es_CR.utf8
es_DO
es_DO.iso88591
es_DO.utf8
es_EC
es_EC.iso88591
es_EC.utf8
es_ES
es_ES.iso88591
es_ES.iso885915@euro
es_ES.utf8
es_ES@euro
es_GT
es_GT.iso88591
es_GT.utf8
es_HN
es_HN.iso88591
es_HN.utf8
es_MX
es_MX.iso88591
es_MX.utf8
es_NI
es_NI.iso88591
es_NI.utf8
es_PA
es_PA.iso88591
es_PA.utf8
es_PE
es_PE.iso88591
es_PE.utf8
es_PR
es_PR.iso88591
es_PR.utf8
es_PY
es_PY.iso88591
es_PY.utf8
es_SV
es_SV.iso88591
es_SV.utf8
es_US
es_US.iso88591
es_US.utf8
es_UY
es_UY.iso88591
es_UY.utf8
es_VE
es_VE.iso88591
es_VE.utf8
estonian
et_EE
et_EE.iso88591
et_EE.iso885915
et_EE.utf8
eu_ES
eu_ES.iso88591
eu_ES.iso885915@euro
eu_ES.utf8
eu_ES@euro
fa_IR
fa_IR.utf8
fi_FI
fi_FI.iso88591
fi_FI.iso885915@euro
fi_FI.utf8
fi_FI@euro
finnish
fo_FO
fo_FO.iso88591
fo_FO.utf8
fr_BE
fr_BE.iso88591
fr_BE.iso885915@euro
fr_BE.utf8
fr_BE@euro
fr_CA
fr_CA.iso88591
fr_CA.utf8
fr_CH
fr_CH.iso88591
fr_CH.utf8
fr_FR
fr_FR.iso88591
fr_FR.iso885915@euro
fr_FR.utf8
fr_FR@euro
fr_LU
fr_LU.iso88591
fr_LU.iso885915@euro
fr_LU.utf8
fr_LU@euro
fran鏰is
french
ga_IE
ga_IE.iso88591
ga_IE.iso885915@euro
ga_IE.utf8
ga_IE@euro
galego
galician
gd_GB
gd_GB.iso885915
gd_GB.utf8
german
gez_ER
gez_ER.utf8
gez_ER.utf8@abegede
gez_ER@abegede
gez_ET
gez_ET.utf8
gez_ET.utf8@abegede
gez_ET@abegede
gl_ES
gl_ES.iso88591
gl_ES.iso885915@euro
gl_ES.utf8
gl_ES@euro
greek
gu_IN
gu_IN.utf8
gv_GB
gv_GB.iso88591
gv_GB.utf8
he_IL
he_IL.iso88598
he_IL.utf8
hebrew
hi_IN
hi_IN.utf8
hr_HR
hr_HR.iso88592
hr_HR.utf8
hrvatski
hu_HU
hu_HU.iso88592
hu_HU.utf8
hungarian
icelandic
id_ID
id_ID.iso88591
id_ID.utf8
is_IS
is_IS.iso88591
is_IS.utf8
it_CH
it_CH.iso88591
it_CH.utf8
it_IT
it_IT.iso88591
it_IT.iso885915@euro
it_IT.utf8
it_IT@euro
italian
iw_IL
iw_IL.iso88598
iw_IL.utf8
ja_JP
ja_JP.eucjp
ja_JP.ujis
ja_JP.utf8
japanese
japanese.euc
ka_GE
ka_GE.georgianps
ka_GE.utf8
kk_KZ
kk_KZ.pt154
kk_KZ.utf8
kl_GL
kl_GL.iso88591
kl_GL.utf8
kn_IN
kn_IN.utf8
ko_KR
ko_KR.euckr
ko_KR.utf8
korean
korean.euc
kw_GB
kw_GB.iso88591
kw_GB.utf8
lg_UG
lg_UG.iso885910
lg_UG.utf8
lithuanian
lo_LA
lo_LA.utf8
lt_LT
lt_LT.iso885913
lt_LT.utf8
lv_LV
lv_LV.iso885913
lv_LV.utf8
mi_NZ
mi_NZ.iso885913
mi_NZ.utf8
mk_MK
mk_MK.iso88595
mk_MK.utf8
ml_IN
ml_IN.utf8
mn_MN
mn_MN.utf8
mr_IN
mr_IN.utf8
ms_MY
ms_MY.iso88591
ms_MY.utf8
mt_MT
mt_MT.iso88593
mt_MT.utf8
nb_NO
nb_NO.iso88591
nb_NO.utf8
ne_NP
ne_NP.utf8
nl_BE
nl_BE.iso88591
nl_BE.iso885915@euro
nl_BE.utf8
nl_BE@euro
nl_NL
nl_NL.iso88591
nl_NL.iso885915@euro
nl_NL.utf8
nl_NL@euro
nn_NO
nn_NO.iso88591
nn_NO.utf8
no_NO
no_NO.ISO-8859-1
norwegian
nynorsk
oc_FR
oc_FR.iso88591
oc_FR.utf8
om_ET
om_ET.utf8
om_KE
om_KE.iso88591
om_KE.utf8
pa_IN
pa_IN.utf8
pl_PL
pl_PL.iso88592
pl_PL.utf8
polish
portuguese
pt_BR
pt_BR.iso88591
pt_BR.utf8
pt_PT
pt_PT.iso88591
pt_PT.iso885915@euro
pt_PT.utf8
pt_PT@euro
ro_RO
ro_RO.iso88592
ro_RO.utf8
romanian
ru_RU
ru_RU.iso88595
ru_RU.koi8r
ru_RU.utf8
ru_UA
ru_UA.koi8u
ru_UA.utf8
russian
se_NO
se_NO.utf8
sid_ET
sid_ET.utf8
sk_SK
sk_SK.iso88592
sk_SK.utf8
sl_SI
sl_SI.iso88592
sl_SI.utf8
slovak
slovene
slovenian
so_DJ
so_DJ.iso88591
so_DJ.utf8
so_ET
so_ET.utf8
so_KE
so_KE.iso88591
so_KE.utf8
so_SO
so_SO.iso88591
so_SO.utf8
spanish
sq_AL
sq_AL.iso88591
sq_AL.utf8
sr_CS
sr_CS.iso88595
sr_CS.utf8
st_ZA
st_ZA.iso88591
st_ZA.utf8
sv_FI
sv_FI.iso88591
sv_FI.iso885915@euro
sv_FI.utf8
sv_FI@euro
sv_SE
sv_SE.iso88591
sv_SE.utf8
swedish
ta_IN
ta_IN.utf8
te_IN
te_IN.utf8
tg_TJ
tg_TJ.koi8t
tg_TJ.utf8
th_TH
th_TH.tis620
th_TH.utf8
thai
ti_ER
ti_ER.utf8
ti_ET
ti_ET.utf8
tig_ER
tig_ER.utf8
tl_PH
tl_PH.iso88591
tl_PH.utf8
tr_TR
tr_TR.iso88599
tr_TR.utf8
tt_RU.utf8
turkish
uk_UA
uk_UA.koi8u
uk_UA.utf8
ur_PK
ur_PK.utf8
uz_UZ
uz_UZ.iso88591
uz_UZ.utf8@cyrillic
uz_UZ@cyrillic
vi_VN
vi_VN.utf8
wa_BE
wa_BE.iso88591
wa_BE.iso885915@euro
wa_BE.utf8
wa_BE@euro
xh_ZA
xh_ZA.iso88591
xh_ZA.utf8
yi_US
yi_US.cp1255
yi_US.utf8
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
zh_HK
zh_HK.big5hkscs
zh_HK.utf8
zh_SG
zh_SG.gb2312
zh_SG.gbk
zh_SG.utf8
zh_TW
zh_TW.big5
zh_TW.euctw
zh_TW.utf8
zu_ZA
zu_ZA.iso88591
zu_ZA.utf8
设置locale:
root:/sources/lfs-bootscripts-6.2# LC_ALL=zh_CN.utf8 locale charmap
UTF-8
root:/sources/lfs-bootscripts-6.2#
测试locale:
root:/sources/lfs-bootscripts-6.2# LC_ALL=zh_CN.utf8 locale country
root:/sources/lfs-bootscripts-6.2# LC_ALL=zh_CN.utf8 locale language
Chinese
root:/sources/lfs-bootscripts-6.2# LC_ALL=zh_CN.utf8 locale charmap
UTF-8
root:/sources/lfs-bootscripts-6.2# LC_ALL=zh_CN.utf8 locale int_curr_symbol
CNY
root:/sources/lfs-bootscripts-6.2# LC_ALL=zh_CN.utf8 locale int_prefix
86
root:/sources/lfs-bootscripts-6.2#
用正确的locale设置,创建/etc/profile文件:
root:/sources/lfs-bootscripts-6.2# cat > /etc/profile << "EOF"
> # Begin /etc/profile
>
> export LANG=zh_CN.UTF-8@anima
> export INPUTRC=/etc/inputrc
>
> # End /etc/profile
> EOF
root:/sources/lfs-bootscripts-6.2#
10.配置localnet脚本
localnet脚本的一部分工作是设置系统的主机名,这需要在 /etc/sysconfig/network 文件里配置。
运行下面的命令创建 /etc/sysconfig/network 文件并设置主机名:
echo "HOSTNAME=<lfs>" > /etc/sysconfig/network
<lfs> 请用您的计算机名替换 [lfs] ,不要在这里输入全限定域名(Fully Qualified Domain Name),FQDN 的信息稍后将放在 /etc/hosts 文件里。
root:/sources/lfs-bootscripts-6.2# echo "HOSTNAME=fish" > /etc/sysconfig/network
11.定制/etc/hosts文件
要在 /etc/hosts 文件里配置网卡的 IP 地址、FQDN 和可能会用的别名,语法如下:
<IP address> myhost.example.org aliases
除非您的计算机在 Internet 上是可访问的(例如,有一个注册的域名并分配到了一个合法的 IP 地址(块)(大多数用户没有)),请确保 IP 地址在私有网络 IP 地址范围内,正确的范围是:
类别 网络
A 10.0.0.0
B 172.16.0.0 到 172.31.0.255
C 192.168.0.0 到 192.168.255.255
一个合法的 IP 地址可能是 192.168.1.1 ,这个 IP 的合法 FQDN 可能是 www.linuxfromscratch.org(不推荐,因为这是个已合法注册的域名,这样做可能会造成域名服务器的问题)。
即使您没有网卡,仍然需要一个 FQDN,某些程序需要这个才能正常工作。
运行下面的命令创建 /etc/hosts 文件:
cat > /etc/hosts << "EOF"
# Begin /etc/hosts (network card version)
127.0.0.1 localhost
<192.168.1.1> <HOSTNAME.example.org> [alias1] [alias2 ...]
# End /etc/hosts (network card version)
EOF
把 [192.168.1.1] 和 [<HOSTNAME>.example.org] 更改为特定用户或特别要求所需要的值(如果这台机器要连入一个已存在的网络,并且网络/系统管理员已经给您分配了一个 IP 地址)。
如果您不打算配置网卡,运行下面的命令创建 /etc/hosts 文件:
cat > /etc/hosts << "EOF"
# Begin /etc/hosts (no network card version)
127.0.0.1 <HOSTNAME.example.org> <HOSTNAME> localhost
# End /etc/hosts (no network card version)
EOF
创建/etc/hosts文件:
root:/sources/lfs-bootscripts-6.2# cat > /etc/hosts << "EOF"
> # Begin /etc/hosts (network card version)
>
> 127.0.0.1 localhost
> 192.168.1.101 fish.anima.org fish anima
>
> # End /etc/hosts (network card version)
> EOF
root:/sources/lfs-bootscripts-6.2#
12.为设备创建惯用符号链接
CD-ROM Symlinks
我们可能装一些软件用到 cdrom dvd 等,因此我们会需要把 /dev/cdrom /dev/dvd 的符号链接加在/etc/fstab中。对于每一个CD-ROM 设备,在 /sys 下找到相应的目录(例如, /sys/block/hdd) ,然后运行如下命令:
udevtest /block/hdd
观察一下包含很多 *_id 输出的程序的行。
有两种方法可以创建symlinks,可以用model名及序号,或是用设备在总线上的位置。 以第一种方法,可以创建如下文件:
cat >/etc/udev/rules.d/82-cdrom.rules << EOF
# Custom CD-ROM symlinks
SUBSYSTEM=="block", ENV{ID_MODEL}=="SAMSUNG_CD-ROM_SC-148F", \
ENV{ID_REVISION}=="PS05", SYMLINK+="cdrom"
SUBSYSTEM=="block", ENV{ID_MODEL}=="PHILIPS_CDD5301", \
ENV{ID_SERIAL}=="5VO1306DM00190", SYMLINK+="cdrom1 dvd"
EOF
注意
这个例子能正常工作,但 udev 不能识别 \ 的继续上一行功能,所以若要用编辑器来编辑 udev 的规则时,一定要保证每行只有一个命令。
做完这些symlinks就会保持正常工作状态,即使把cdrom移到 IDE 总线的其他位置上也能正常工作。但是如果使用新的驱动器来替换原来的 SAMSUNG CD-ROM,/dev/cdrom 符号链接将不会被创建。
SUBSYSTEM=="block" 关键字是为了避免匹配一般的 SCSI 设备。 在没有这个关键字的情况下,若同时存在两个 SCSI CD-ROM, 这个符号链接有时会指向 /dev/srX 设备 ,但有时会错误的指向 /dev/sgX。
第二种方法的步骤:
cat >/etc/udev/rules.d/82-cdrom.rules << EOF
# Custom CD-ROM symlinks
SUBSYSTEM=="block", ENV{ID_TYPE}=="cd", \
ENV{ID_PATH}=="pci-0000:00:07.1-ide-0:1", SYMLINK+="cdrom"
SUBSYSTEM=="block", ENV{ID_TYPE}=="cd", \
ENV{ID_PATH}=="pci-0000:00:07.1-ide-1:1", SYMLINK+="cdrom1 dvd"
EOF
这样,即使你使用不同的 model 来替换原来的设备,符号链接仍然是正确的,它指向在 IDE 总线上旧的位置。 ENV{ID_TYPE}=="cd" 关键字是为了确保符号链接在总线上的那个位置放的不是 CD-ROM 时,能够消失。
当然把两种方法混合使用也是可以的。
查看 /sys/block/目录:
root:/sources/lfs-bootscripts-6.2# ls /sys/block/*
/sys/block/dm-0:
dev range removable size stat
/sys/block/dm-1:
dev range removable size stat
/sys/block/hda:
dev hda1 hda2 hda5 hda7 hda9 range size
device hda10 hda3 hda6 hda8 queue removable stat
/sys/block/hdc:
dev device queue range removable size stat
/sys/block/hdd:
dev hdd1 hdd5 hdd7 queue removable stat
device hdd2 hdd6 hdd8 range size
/sys/block/md0:
dev range removable size stat
/sys/block/ram0:
dev range removable size stat
/sys/block/ram1:
dev range removable size stat
/sys/block/ram10:
dev range removable size stat
/sys/block/ram11:
dev range removable size stat
/sys/block/ram12:
dev range removable size stat
/sys/block/ram13:
dev range removable size stat
/sys/block/ram14:
dev range removable size stat
/sys/block/ram15:
dev range removable size stat
/sys/block/ram2:
dev range removable size stat
/sys/block/ram3:
dev range removable size stat
/sys/block/ram4:
dev range removable size stat
/sys/block/ram5:
dev range removable size stat
/sys/block/ram6:
dev range removable size stat
/sys/block/ram7:
dev range removable size stat
/sys/block/ram8:
dev range removable size stat
/sys/block/ram9:
dev range removable size stat
root:/sources/lfs-bootscripts-6.2#
查看宿主系统 /sys/block/目录:
[lwg@fish ~]$ ls /sys/block/*
/sys/block/dm-0:
dev range removable size stat
/sys/block/dm-1:
dev range removable size stat
/sys/block/hda:
dev hda1 hda2 hda5 hda7 hda9 range size
device hda10 hda3 hda6 hda8 queue removable stat
/sys/block/hdc:
dev device queue range removable size stat
/sys/block/hdd:
dev hdd1 hdd5 hdd7 queue removable stat
device hdd2 hdd6 hdd8 range size
/sys/block/md0:
dev range removable size stat
/sys/block/ram0:
dev range removable size stat
/sys/block/ram1:
dev range removable size stat
/sys/block/ram10:
dev range removable size stat
/sys/block/ram11:
dev range removable size stat
/sys/block/ram12:
dev range removable size stat
/sys/block/ram13:
dev range removable size stat
/sys/block/ram14:
dev range removable size stat
/sys/block/ram15:
dev range removable size stat
/sys/block/ram2:
dev range removable size stat
/sys/block/ram3:
dev range removable size stat
/sys/block/ram4:
dev range removable size stat
/sys/block/ram5:
dev range removable size stat
/sys/block/ram6:
dev range removable size stat
/sys/block/ram7:
dev range removable size stat
/sys/block/ram8:
dev range removable size stat
/sys/block/ram9:
dev range removable size stat
[lwg@fish ~]$
udevtest:
root:/sources/lfs-bootscripts-6.2# udevtest /block/hda
main: looking at device '/block/hda' from subsystem 'block'
run_program: 'ata_id --export /dev/.tmp-3-0'
run_program: '/lib/udev/ata_id' (stdout) 'ID_TYPE=disk'
run_program: '/lib/udev/ata_id' (stdout) 'ID_MODEL=Maxtor_6Y080L0'
run_program: '/lib/udev/ata_id' (stdout) 'ID_SERIAL=Y2NCM7GE'
run_program: '/lib/udev/ata_id' (stdout) 'ID_REVISION=YAR41BW0'
run_program: '/lib/udev/ata_id' (stdout) 'ID_BUS=ata'
run_program: '/lib/udev/ata_id' returned with status 0
udev_rules_get_name: add symlink 'disk/by-id/ata-Maxtor_6Y080L0_Y2NCM7GE'
run_program: 'path_id /block/hda'
run_program: '/lib/udev/path_id' (stdout) 'ID_PATH=pci-0000:00:1f.1-ide-0:0'
run_program: '/lib/udev/path_id' returned with status 0
udev_rules_get_name: add symlink 'disk/by-path/pci-0000:00:1f.1-ide-0:0'
run_program: 'vol_id --export /dev/.tmp-3-0'
run_program: '/lib/udev/vol_id' returned with status 4
run_program: 'edd_id --export /dev/.tmp-3-0'
run_program: '/lib/udev/edd_id' (stderr) 'no kernel EDD support'
run_program: '/lib/udev/edd_id' returned with status 2
udev_rules_get_name: no node name set, will use kernel name 'hda'
udev_db_get_device: no db file to read /dev/.udev/db/block@hda: No such file or directory
udev_node_add: creating device node '/dev/hda', major = '3', minor = '0', mode = '0660', uid = '0', gid = '8'
udev_node_add: creating symlink '/dev/disk/by-id/ata-Maxtor_6Y080L0_Y2NCM7GE' to '../../hda'
udev_node_add: creating symlink '/dev/disk/by-path/pci-0000:00:1f.1-ide-0:0' to '../../hda'
root:/sources/lfs-bootscripts-6.2# udevtest /block/hdd
main: looking at device '/block/hdd' from subsystem 'block'
run_program: 'ata_id --export /dev/.tmp-22-64'
run_program: '/lib/udev/ata_id' (stdout) 'ID_TYPE=disk'
run_program: '/lib/udev/ata_id' (stdout) 'ID_MODEL=Maxtor_6Y060L0'
run_program: '/lib/udev/ata_id' (stdout) 'ID_SERIAL=Y2N48WXE'
run_program: '/lib/udev/ata_id' (stdout) 'ID_REVISION=YAR41BW0'
run_program: '/lib/udev/ata_id' (stdout) 'ID_BUS=ata'
run_program: '/lib/udev/ata_id' returned with status 0
udev_rules_get_name: add symlink 'disk/by-id/ata-Maxtor_6Y060L0_Y2N48WXE'
run_program: 'path_id /block/hdd'
run_program: '/lib/udev/path_id' (stdout) 'ID_PATH=pci-0000:00:1f.1-ide-1:1'
run_program: '/lib/udev/path_id' returned with status 0
udev_rules_get_name: add symlink 'disk/by-path/pci-0000:00:1f.1-ide-1:1'
run_program: 'vol_id --export /dev/.tmp-22-64'
run_program: '/lib/udev/vol_id' returned with status 4
run_program: 'edd_id --export /dev/.tmp-22-64'
run_program: '/lib/udev/edd_id' (stderr) 'no kernel EDD support'
run_program: '/lib/udev/edd_id' returned with status 2
udev_rules_get_name: no node name set, will use kernel name 'hdd'
udev_db_get_device: no db file to read /dev/.udev/db/block@hdd: No such file or directory
udev_node_add: creating device node '/dev/hdd', major = '22', minor = '64', mode = '0660', uid = '0', gid = '8'
udev_node_add: creating symlink '/dev/disk/by-id/ata-Maxtor_6Y060L0_Y2N48WXE' to '../../hdd'
udev_node_add: creating symlink '/dev/disk/by-path/pci-0000:00:1f.1-ide-1:1' to '../../hdd'
root:/sources/lfs-bootscripts-6.2# udevtest /block/hdc
main: looking at device '/block/hdc' from subsystem 'block'
run_program: 'ata_id --export /dev/.tmp-22-0'
run_program: '/lib/udev/ata_id' (stdout) 'ID_TYPE=cd'
run_program: '/lib/udev/ata_id' (stdout) 'ID_MODEL=ATAPI-CD_ROM-DRIVE-52MAX'
run_program: '/lib/udev/ata_id' (stdout) 'ID_SERIAL='
run_program: '/lib/udev/ata_id' (stdout) 'ID_REVISION=Ver_52E4'
run_program: '/lib/udev/ata_id' (stdout) 'ID_BUS=ata'
run_program: '/lib/udev/ata_id' returned with status 0
run_program: 'path_id /block/hdc'
run_program: '/lib/udev/path_id' (stdout) 'ID_PATH=pci-0000:00:1f.1-ide-1:0'
run_program: '/lib/udev/path_id' returned with status 0
udev_rules_get_name: add symlink 'disk/by-path/pci-0000:00:1f.1-ide-1:0'
udev_rules_get_name: no node name set, will use kernel name 'hdc'
udev_db_get_device: no db file to read /dev/.udev/db/block@hdc: No such file or directory
udev_node_add: creating device node '/dev/hdc', major = '22', minor = '0', mode = '0660', uid = '0', gid = '15'
udev_node_add: creating symlink '/dev/disk/by-path/pci-0000:00:1f.1-ide-1:0' to '../../hdc'
root:/sources/lfs-bootscripts-6.2#
宿主系统 udevtest:
[lwg@fish ~]$ udevtest /block/hda
version 039
looking at '/block/hda'
configured rule in '/etc/udev/rules.d/51-by-id.rules' at line 6 applied, added symlink 'disk/by-path/%c'
creating device node '/dev/hda', major = '3', minor = '0', mode = '060660', uid = '0', gid = '6'
[lwg@fish ~]$ udevtest /block/hdd
version 039
looking at '/block/hdd'
configured rule in '/etc/udev/rules.d/51-by-id.rules' at line 6 applied, added symlink 'disk/by-path/%c'
creating device node '/dev/hdd', major = '22', minor = '64', mode = '060660', uid = '0', gid = '6'
[lwg@fish ~]$ udevtest /block/hdc
version 039
looking at '/block/hdc'
configured rule in '/etc/udev/rules.d/50-udev.rules' at line 79 applied, added symlink 'cdrom%e'
configured rule in '/etc/udev/rules.d/51-by-id.rules' at line 6 applied, added symlink 'disk/by-path/%c'
creating device node '/dev/hdc', major = '22', minor = '0', mode = '060660', uid = '0', gid = '6'
[lwg@fish ~]$
创建symlinks:
root:/sources/lfs-bootscripts-6.2# cat >/etc/udev/rules.d/82-cdrom.rules << EOF
> # Custom CD-ROM symlinks
> SUBSYSTEM=="block", ENV{ID_MODEL}=="ATAPI-CD_ROM-DRIVE-52MAX", \
> ENV{ID_REVISION}=="Ver_52E4", SYMLINK+="cdrom"
> EOF
root:/sources/lfs-bootscripts-6.2#
Dealing with duplicate devices:
在“LFS系统的设备和模块处理”提到过, /dev 下相同功能设备的顺序是随机的。例如,你有一个 USB 的网络摄像头和一个 TV 的调谐器,有时 /dev/video0 指向网络摄像头,/dev/video1 指向调谐器,但是在重启之后可能就会改变。除了网卡和声卡之外的其他设备,都可以通过创建 udev 的规则来定制固定的符号链接。网卡的解决 方法请见“配置网络脚本”,声卡解决方法请见 BLFS。
每一个设备都可能有这个问题(即使这个问题在你现在的发行版中不存在),在 /sys/class 或 /sys/block 下找到相应的目录。 对于视频设备,可能是 /sys/class/video4linux/videoX。 找出标记设备唯一性的属性(通常是 设备提供商、产品 ID 以及序列号):
udevinfo -a -p /sys/class/video4linux/video0
接下来,写一个创建符号链接的规则,例如:
cat >/etc/udev/rules.d/83-duplicate_devs.rules << EOF
# Persistent symlinks for webcam and tuner
KERNEL=="video*", SYSFS{idProduct}=="1910", SYSFS{idVendor}=="0d81", \
SYMLINK+="webcam"
KERNEL=="video*", SYSFS{device}=="0x036f", SYSFS{vendor}=="0x109e", \
SYMLINK+="tvtuner"
EOF
结果 /dev/video0 和 /dev/video1 设备仍然随机指向调谐器和网络摄像头(因此不应当直接使用),但是符号链接 /dev/tvtuner 和 /dev/webcam 总是指向正确的设备。
关于书写 Udev 规则的更多信息,可以查看 /usr/share/doc/udev-096/index.html。
13.配置网络脚本
本节仅适用于需要配置网卡的情况。
如果不使用网卡,就不需要创建关联网卡的配置文件,这样的话,在所有运行级目录(/etc/rc.d/rc*.d) 下删除 network 符号链接。
13.1.创建网络接口的稳定名称
这一段的说明对于单网卡是可选的。
由于 Udev 和 网络驱动的模块化,网络设备的接口的加载顺序在每次reboot后可能会不同,因为驱动是并行加载的,所以顺序会变成随机。例如,在一台计算机上有两块网 卡Intel 和 Realtek。Intel 制造的网卡可能是 eth0,Realtelk 的网卡是 eth1;但是重启后网卡的顺序可能反过来。为避免这种情况,我们应该 根据网卡的MAC地址或总线位置来为他们命名。
如果想要根据MAC地址来识别网卡,可以使用如下命令:
root:/sources/lfs-bootscripts-6.2# grep -H . /sys/class/net/*/address
/sys/class/net/eth0/address:00:50:8d:4c:b0:22
/sys/class/net/lo/address:00:00:00:00:00:00
/sys/class/net/sit0/address:00:00:00:00
/sys/class/net/vmnet1/address:00:50:56:c0:00:01
/sys/class/net/vmnet8/address:00:50:56:c0:00:08
root:/sources/lfs-bootscripts-6.2#
为每个网卡(除loopback),设计一个描述性的名字,比方 “realtek”, 然后参照如下建立Udev规则:
root:/sources/lfs-bootscripts-6.2# cat > /etc/udev/rules.d/26-network.rules << EOF
> ACTION=="add", SUBSYSTEM=="net", SYSFS{address}=="00:50:8d:4c:b0:22", \
> NAME="realtek8139"
>
> EOF
root:/sources/lfs-bootscripts-6.2#
注意
虽然这个例子可以正常工作,但要注意 udev 不能识别 \ 的继续上一行的功能。所以如果用文本编辑器来编辑就一定要保证每个规则占一行。
如果要以总线位置作为标准,可以创建如下的Udev规则:
cat > /etc/udev/rules.d/26-network.rules << EOF
ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:00:0c.0", \
NAME="realtek"
ACTION=="add", SUBSYSTEM=="net", BUS=="pci", ID=="0000:00:0d.0", \
NAME="intel"
EOF
这个规则会把网卡名字每次都定为 “realtek” 和 “intel”, 以替代eth0和eth1 (即:原来的eth0和eth1接口不存在了 除非把他们加到 NAME 下)。在下面的文件中我们使用描述性的名字来替代eth0 等。
需注明以上规则并不永远适用。例如, 当VLAN 和 网桥 使用时,以MAC为基准的命名就会出问题。由于 VLAN 和 网桥 在网卡上有相同的MAC地址。 如果只想重新命名网卡接口,而不是brige和VLAN接口,但是规则都会匹配它们。如果使用虚拟接口,我们会有两种解决办法。其一是把 DRIVER=="?*" 关键字加在 SUBSYSTEM=="net" 后。但这种方法对于一些老型号的网卡不起作用,因为这些网卡的 uevent 中没有 DRIVER 变量,因此 按规则就不可能匹配到这些卡。 另外一种就是以总线位置命名。
另外一种已知的不能工作的情况存在于无线网络中,当应用MadWifi 或 HostAP 驱动时, 他们会以相同的MAC地址和总线位置创建至少两个接口。例如,Madwifi 驱动会创建一个 athX 和 wifiX 接口(X是一个数字)。为区别 这些接口,可以把 KERNEL 参数,比如 KERNEL=="ath*" 加到 SUBSYSTEM=="net"后。
可能还有很多情况会导致不能正常工作,现在这方面的 bug 仍然不断的报告给 Linux 的各个发布版,没有一个解决方法可以解决所有的情况。
13.2.创建网络接口配置文件
network 脚本启用或关闭哪个接口由 /etc/sysconfig/network-devices 目录下的文件决定,这个目录下的文件应该是类似于 ifconfig.xyz 的形式,这里"xyz"是网络接口名(例如 eth0 或者 eth0:1)。这个目录中的文件将定义接口的属性,比如IP地址、子网掩码等等。
在这个目录下新建文件,下面是一个为 eth0 设备创建 ipv4 文件的示例:
cd /etc/sysconfig/network-devices &&
mkdir -v ifconfig.eth0 &&
cat > ifconfig.eth0/ipv4 << "EOF"
ONBOOT=yes
SERVICE=ipv4-static
IP=192.168.1.1
GATEWAY=192.168.1.2
PREFIX=24
BROADCAST=192.168.1.255
EOF
每个文件中的这些变量的值都要改成您的设置,如果 ONBOOT 变量设置为"yes",network 脚本会在系统启动的时候启动 NIC(Network Interface Card 网络接口卡,简称网卡),如果设置为"yes"以外的值,网卡会被 network 脚本忽略而没有启动。
SERVICE 变量定义获取 IP 地址的方式,LFS-Bootscripts 有一套模块化的 IP 地址分配格式,并在 /etc/sysconfig/network-devices/services 目录下为其它的 IP 分配方式创建了附加的文件,这通常用作 DHCP(Dynamic Host Configuration Protocol 动态主机配置协议)方式,在 BLFS 里有详细介绍。
GATEWAY 变量应该设置为默认网关的 IP 地址,如果没有默认网关,就把这个变量完全注释掉。
PREFIX 变量设置为子网使用的位数,IP 地址的每个字节是 8 bit ,如果子网掩码是 255.255.255.0 ,那么它使用前三个字节(24 bit)指定网络号;如果网络掩码是 255.255.255.240 ,它用前 28 bit 来指定网络号。长于 24 bit 的前缀一般由 DSL 和 cable 的 ISP(Internet Service Providers 因特网服务提供商)使用,我们的例子里(PREFIX=24),子网掩码是 255.255.255.0 ,请根据您的网络情况调整 PREFIX 变量。
root:/sources/lfs-bootscripts-6.2# cd /etc/sysconfig/network-devices &&
> mkdir -v ifconfig.eth0 &&
> cat > ifconfig.eth0/ipv4 << "EOF"
> ONBOOT=yes
> SERVICE=ipv4-static
> IP=192.168.1.101
> GATEWAY=192.168.1.1
> PREFIX=24
> BROADCAST=192.168.1.255
>
> EOF
mkdir: created directory `ifconfig.eth0'
root:/etc/sysconfig/network-devices#
宿主系统ifcfg-eth0:
[lwg@fish ~]$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
BROADCAST=192.168.1.255
HWADDR=00:50:8D:4C:B0:22
IPADDR=192.168.1.100
NETMASK=255.255.255.0
NETWORK=192.168.1.0
ONBOOT=yes
TYPE=Ethernet
MTU=1492
#MTU=1500
USERCTL=no
IPV6INIT=no
PEERDNS=yes
GATEWAY=192.168.1.1
[lwg@fish ~]$
13.3.创建 /etc/resolv.conf 文件
如果系统要连接到 Internet 上,就需要 DNS(Domain Name Service 域名服务)名称解析的手段,来把 Internet 域名解析为 IP 地址,反之亦然。在 /etc/resolv.conf 文件里设置 ISP 或网络管理员提供的域名服务器的 IP 地址就可以达到这个目的了,运行下面的命令创建这个文件:
cat > /etc/resolv.conf << "EOF"
# Begin /etc/resolv.conf
domain {<域名>}
nameserver <主域名服务器IP地址>
nameserver <副域名服务器IP地址>
# End /etc/resolv.conf
EOF
把 [域名服务器IP地址] 替换为您的域名服务器的 IP 地址。域名服务器常常不止一项(作为备份用途),如果您只需要一个域名服务器,把文件里的第二行 nameserver 删除就可以了。在局域网里这个 IP 地址还可能是路由器。
创建 /etc/resolv.conf 文件:
root:/etc/sysconfig/network-devices# cat > /etc/resolv.conf << "EOF"
> # Begin /etc/resolv.conf
>
> nameserver 202.96.128.68
> nameserver 202.96.128.143
>
> # End /etc/resolv.conf
> EOF
root:/etc/sysconfig/network-devices#
查看宿主系统 /etc/resolv.conf 文件:
[lwg@fish ~]$ cat /etc/resolv.conf
nameserver 202.96.128.68
nameserver 202.96.128.143
[lwg@fish ~]$