日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CentOS系列启动流程和内核原理(5系列,6系列,7系列)

發(fā)布時間:2023/12/10 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CentOS系列启动流程和内核原理(5系列,6系列,7系列) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言,本來讓我寫博客我是拒絕的然而看見大家都在寫,還能不能一起友好的玩耍了?

我要是不寫怎能和同大神們一起ZB呢?遂開博客!


一、Linux啟動內核文件

1.Linux系統(tǒng)組成

動態(tài)視角:內核+根文件系統(tǒng)

靜態(tài)視角:磁盤分區(qū)+相關文件

2.Kernel特點

(1)支持某塊化:.ko (kernel object)文件

centos7的ko文件:

centos6的ko文件:

注意:

????Linux內核模塊文件的命名方式通常為<模塊名稱.ko>

????centos6系統(tǒng)的內核模塊被集放在/lib/modules/'uname -r '/目錄下

????centos7系統(tǒng)的內核模塊被集放在/usr/lib/modules/'uname -r '/目錄下


(2)支持模塊運行時動態(tài)裝載或卸載;

模塊的相關命令:

a)加載模塊:insmod?? modprobe

insmod和modprobe的區(qū)別

當a模塊與b模塊有依賴關系時,假設安裝b模塊需先安裝a模塊。

如果用insmod命令那么需要先insmod? a.ko 然后再insmod? b.ko。

如果用modprobe命令那么直接可以modprobeb.ko。

其中/lib/modules/“內核版本號”/modules.dep中記錄了模塊之間的依賴關系。

通過modprobe加載的內核均在當前的計算機內有效,計算機重新啟動后需要重新加載才有效。
如果想要開機后自動掛載內核,需要將modprobe命令寫入/etc/rc.sysint文件中


b)卸載模塊:rmmod????modprobe -r

rmmod:只需要調用模塊名即可,比如安裝的時候是inmod? a.ko 安裝完畢后該模塊存在于內核中的名字為a,那么卸載該模塊只需要rmmod? a即可。

[root@openstack01 ~]# modprobe ip_vs #動態(tài)加載ip_vs模塊 [root@openstack01 ~]# lsmod |grep ip_vs #查看模塊是否加載成功 ip_vs 125220 0 libcrc32c 1246 1 ip_vs ipv6 317340 289 ip_vs [root@openstack01 ~]# modprobe -r ip_vs #卸載動態(tài)模塊 [root@openstack01 ~]# lsmod |grep ip_vs #模塊已經(jīng)卸載干凈



c)查看模塊:lsmod

輸出三列信息

分別為模塊 占用內存 是否被調用

如果第三列為0則該模塊可以隨時可以卸載。


總結:Linux kernel在單內核設計模型上,吸取了多內核設計的優(yōu)點,使用了模塊化設計

????單內核設計:把所有功能集成于同一個程序;如Linux

????微內核設計:每種功能使用一個單獨的子系統(tǒng)實現(xiàn);如Windows, Solaris


3.kernel組成

(1)核心文件

1)/boot/vmlinuz-VERSION-release

注: vmlinuz最后一一個z表示壓縮格式的kernel文件

????????

2)ramdisk(中間臨時文件根系統(tǒng),動態(tài)創(chuàng)建出來的,使用緩沖和緩存來加速對磁盤上的文件訪問)

參考:Linux內核Ramdisk(initrd)機制?

安裝操作系統(tǒng)后臨時生成的文件,能夠掃描當前操作系統(tǒng)的硬盤驅動,裝載對應的模塊

用于實現(xiàn)系統(tǒng)初始化的基于內存的磁盤設備,把內存中的一段空間當內存使用

CentOS 5:/boot/initrd-VERSION-release.img?

工具程序:mkinitrd

CentOS 6,7:/boot/initramfs-VERSION-release.img

工具程序:dracut, mkinitrd

注意:

a)不是必須的,當自編譯內核時候知道硬盤接口時候將硬盤驅動編譯進kernel,ramdisk就不用了

b)initrd,基于ramdisk的磁盤映像文件;initramfs,基于ramdisk的文件系統(tǒng)

initrd啟動該后用free查看memory時候,有一段空間被buffers和cached占用,二次緩存

從2.6內核開始,initrd.img采用cpio壓縮,不再是2.4內核使用的ext2格式,無法使用mount -o loop 掛載。需要使用gunzip解壓縮,然后再使用cpio解包

cpio命令: cpio - copy files to and from archives -i, --extract Extract files from an archive (run in copy-in mode) 將打包文件解壓或者將設備上的備份還原到系統(tǒng)。 -v, --verbose Verbosely list the files processed 顯示打包過程中的文件名稱。 -o, --create Create the archive (run in copy-out mode) 將文件拷貝打包成文件或者將文件輸出到設備上。 -d, --make-directories Create leading directories where needed 在cpio還原文件的過程中,自動的建立相應的目錄。 -m, --preserve-modification-time Retain previous file modification times when creating files 在創(chuàng)建文件時保留以前的文件修改時間



(2)img文件壓縮及解壓

centos7的initrd文件解壓流程:

centos6的initrd文件解壓流程:

修改內核后,自定義打包一個內核initrd文件:


(3)img文件掛載方法

在linux中,對于img文件(例如,虛擬機的img文件),有時候需要將其掛載,以便修改其中的內容。能不能將它像iso文件一樣掛載呢?

使用kpartx命令:

kpartx - Create device maps from partition tables -a Add partition mapping -d Delete partition mappings -l List partition mappings that would be added -a -p set device name-partition number delimiter -f force creation of mappings; overrides ’no_partitions’ feature -g force GUID partition table (GPT) -s sync mode. Don’t return until the partitions are created -v Operate verbosely



(然并卵,我在centos6和centos7失敗)

據(jù)說這樣使用: kpartx -av xxx.img mount /dev/mapper/loop0p1 /mnt


(4)模塊文件:/lib/modules/VERSION-release(與內核版本發(fā)行號相同的目錄)/*

arch :與平臺相關的特有代碼,專有的匯編級的代碼

crypto:加密解密組件

drivers:驅動程序

fs :文件系統(tǒng)

kernel :內核自己追蹤用到的文件

lib:庫文件

mm:內存管理功能,memory manage

net:網(wǎng)絡功能

sound:和聲音相關的驅動程序,單獨放出來,因為有很多與聲音相關的×××


二、CentOS系列PC架構MBR主機啟動流程

POST --> Boot Sequence(BIOS) --> Boot Loader (MBR) --> Kernel(ramdisk) --> rootfs --> switchroot --> /sbin/init -->(/etc/inittab, /etc/init/*.conf) --> 設定運行級別 --> 系統(tǒng)初始化腳本 --> 關閉或啟動對應級別下的服務 --> 啟動終端

1.POST:加電自檢,檢查硬件設備是否存在

用于實現(xiàn)POST的代碼在主板上ROM(CMOS)芯片上

BIOS:Basic Input and Output System 基本上輸入輸出系統(tǒng),固化在ROM芯片上

POST(PowerOnSelfTest)首先對每一個設備進行檢查。完成后會尋找存有引導記錄的設備,找到后讀入操作系統(tǒng)引導記錄,然后將系統(tǒng)控制權交給引導記錄,并由引導記錄來完成系統(tǒng)的順利啟動。


2.Boot Sequence:

按次序查找各引導設備,第一個有引導程序的設備即為本次啟動要用到的設備;??

3.MBR引導,bootloader:引導加載器,程序;

MBR(Master Boot Record) MBR記錄一般是在磁盤 0 磁道 1 扇區(qū),共512個字節(jié)。前446個字節(jié)是BootLoder,后 4*16 的 64 個字節(jié)是存放分區(qū)信息的,最后 2 個字節(jié)是校驗信息,一般是 55AA。

提供一個菜單,允許用戶選擇要啟動的系統(tǒng)或不同的內核版本; 把用戶選定的內核裝載到RAM中的特定空間中,解壓、展開,而后把系統(tǒng)控制權移交給內核;

(1)Windows上引導加載器:ntloader

(2)Linux上引導加載器:

1)LILO:短小精悍的linux加載器,1024柱面之后無法加載,現(xiàn)在多用于安卓手機啟動????

2)GRUB:Grand Uniform Bootloader統(tǒng)一引導加載器

GRUB 0.X(CentOS 5/6):Grub Legacy

GRUB 1.X(CentOS 7):Grub2,完全重寫,設計理念上很大改變

GRUB(GRand Unified Bootloader)加載內核,就是MBR中的前 446 個字節(jié),是BooTLoader的一種,它的作用是要選擇要啟動的內核。

1)GRUB程序的組成:

centos6:

主要是由device.map,menulst,stage1,stage2,以及一系列的stage1_5組成。對于這些部分我的理解是這樣:

device.map:存放的是內核文件的根分區(qū)

menu.lis:是grub.conf的鏈接文件,但是這個名字我覺得更與它的功能接近,就是菜單列表。里賣弄設置了可以選擇的內核菜單。存放于stage2中。

stage:用于grub引導程序過大,所以分2段引導,第一段存放在MBR中,第二段存放于內核文件系統(tǒng)中,第一段引導完成后可以找到 第二段。 但是,第二段是存放于內核文件系統(tǒng)中的,此時還沒有格式化文件系統(tǒng),如何可以訪問到第二段的 menu.lst 呢??就需要借助于中間層 stage1_5,有它來協(xié)助 stage1 段來訪問 stage2 段。stage1_5通常位于 stage1 字段后的 63 個扇區(qū)。 由于stage2 在內存中存放可以使用的文件系統(tǒng)不確定,所以這就是有多個 stage1_5 的原因了。

2)grub.conf 文件參數(shù)意義


default=0 # 默認啟動的內核title, 0 表示是第一個 timeout=5 # 默認等待時間 splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz # 指定菜單的背景圖片的路徑。為xpm格式,采用gzip壓縮,只能為14bits色 hiddenmenu # 隱藏菜單 title CentOS (2.6.32-431.el6.x86_64) # 標題名,用戶可自定義 root (hd0,0) # 指定 grub 的根位置 # 指定 kernel 文件的位置,還要指出 root(系統(tǒng)啟動后) 的位置,掛載方式 ro,這項很關鍵。 # 加載后會啟動 init 進程。 kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=17df3f60-a2a2-4de3-bdeb-b6fb4950d848 rd_NO_LUKS KEYBOARDTYPE=pc KEYTABLE=us LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 rd_NO_LVM crashkernel=auto rhgb quiet rd_NO_DM rhgb quiet# 在內核啟動過程中裝載根文件系統(tǒng)時有用initrd /initramfs-2.6.32-431.el6.x86_64.img # initramfs 是以 gzip 壓縮的 cpio 格式的文件。內核啟動時將他作為一個臨時的根文件系統(tǒng)。 # grub 的 stage2 將initrd加載到內存里,讓后將其中的內容釋放到內容中, # 內核便去執(zhí)行init腳本,這時內核將控制權交給了init文件處理。 # init 它也主要是加載各種存儲介質相關的設備驅動程序。當所需的驅動程序加載完后, # 會創(chuàng)建一個根設備,然后將根文件系統(tǒng)rootfs以只讀的方式掛載。 # 這一步結束后,釋放未使用的內存,轉換到真正的根文件系統(tǒng)上面去,同時運行/sbin/init程序, # 執(zhí)行系統(tǒng)的1號進程。此后系統(tǒng)的控制權就全權交給/sbin/init進程了。

Linux內核在初始化之后會執(zhí)行init進程,而init進程會掛載我們的根文件系統(tǒng),但由于init程序也是在根文件系統(tǒng)上的,所以這就有了悖論。

Linux采用兩步走的方法來解決這個問題。

Linux2.6 版以前的方法是:除了內核vmlinuz之外還有一個獨立的initrd.img映像文件,其實它就是一個文件系統(tǒng)映像,linux內核在初始化后會 mount initrd.img作為一個臨時的根文件系統(tǒng),而init進程就是在initrd.img里的,然后init進程會掛載真正的根文件系統(tǒng),然后 umount initrd.img。

但Linux2.6內核的實現(xiàn)方式卻不太一樣,雖然完成的功能是一樣的。Linux2.6采用initramfs。 initramfs:init ram filesystem,它是一個cpio格式的內存文件系統(tǒng),制作的方法有兩個,一個是http://blog.csdn.net/htttw/article/details/7215858介紹的,但這樣做出來的initramfs是和內核vmlinuz分開的,因此我們需要在grub里寫上initramfs的路徑。

而另 一種方法是把內核和initramfs制作在一起成為一個文件,方法是在linux源碼make menuconfig,然后General setup-->選擇Initial RAM filesystem and RAM disk (initramfs/initrd) support,然后在Initramfs source file(s)里輸入我們的initramfs目錄,然后make bzImage。這種方法做出來的內核就只有一個文件,不需要指定initramfs了。

從2.6內核以后真正的內核文件是initramfs開頭的!!initrd開頭的注意后面的結尾dump,可能是原始備份的


centos7:


3)grub的功能

(1)提供菜單,并提供交互式接口

(2)選擇要啟動的內核或系統(tǒng)

允許傳遞引導參數(shù)給內核

選擇界面可隱藏

# 可以自啟動是通過 grub 像內核傳遞參數(shù)。 # 應用之一是:修改 root 密碼(忘記密碼),使用 e 選項,傳遞單用戶指令。

centos7:

centos6:

(3)為編輯功能提供保護機制

啟用內核文件

選擇運行指定的內核得先輸入密碼

傳遞參數(shù)

使用e命令得先輸入密碼

[root@openstack01 ~]# grub-md5-crypt Password: Retype password: $1$32hfn$HcmdhoMIJvGir.2hNKz8W0 # 上面是生成的加密字符串 # 然后將信息加入到 grub.conf 文件中,格式如下: password --md5 $1$32hfn$HcmdhoMIJvGir.2hNKz8W0 # 當然加入 grub.conf 文件的位置不同,加密效果也不一樣。 # 加入到 title 之前的話,會加密整個菜單。 # 加入到 title 指內的話,會加密對應的操作系統(tǒng)的入口。

?

4.Kernel實現(xiàn)功能

kernel自身初始化,實現(xiàn)功能

?---> 探測可識別到的所有硬件設備;

---> 加載硬件驅動程序;(有可能會借助于ramdisk加載驅動)

---> 以只讀方式掛載根文件系統(tǒng);

?---> 運行用戶空間的第一個應用程序:/sbin/init

??????

5./sbin/init管理用戶空間服務進程

init程序的在不同CentOS版本上類型:

CentOS 5及以前:SysV init???? 配置文件:/etc/inittab

CentOS 6:Ubantu研發(fā)的Upstart???????配置文件:/etc/inittab???/etc/init/*.conf

CentOS 7:Systemd????? 配置文件:/usr/lib/systemd/system/, /etc/systemd/system/


(1)CentOS 5:

SysV init配置文件:/etc/inittab

[root@openstack01 ~]# cat /etc/inittab id:3:initdefault: 此處 表示默認啟動級別為3文本界面,不能為0級別 /etc/inittab文件:每行定義一種action 以及與之對應的process 格式:id:runlevels:action:process id:一個任務的標識符; runlevels:在哪些級別啟動此任務;#,###,若此處為空則表示所有級別; action:在什么條件下啟動此任務; wait:等待切換至此任務所在的級別時執(zhí)行一次; respawn:再次發(fā)起;此任務終止,就自動重新啟動; initdefault:設定默認運行級別;此時process會省略,不是設定任務,而是默認啟動級別; sysinit:設定系統(tǒng)初始化方式,此處一般為指定/etc/rc.d/rc.sysinit腳本(CentOS5和6用到,7無); process:任務;


(2)CentOS 6:
init程序:upstart,但依然為/sbin/init,
其配置文件: /etc/init/*.conf, /etc/inittab(僅用于定義默認運行級別)
注意:*.conf為upstart風格的配置文件;各功能切割成片段

init-system-dbus.conf:主要在哪兒啟動服務的配置文件

rcS.conf:? 系統(tǒng)初始化腳本

start-ttys.conf:啟動時的終端數(shù)量

rc.conf:啟動服務的配置文件


系統(tǒng)初始化首先從/etc/init/rcS.conf開始

end script exec /etc/rc.d/rc.sysinit

rcS.conf里面有這樣行,表明這個rcS.conf執(zhí)行完后才開始執(zhí)行rc.sysinit配置文件


更改默認tty數(shù)量文件:


(3)CentOS 7:不需要任何啟動腳本

init程序:systemd,配置文件:/usr/lib/systemd/system/*,? /etc/systemd/system/*

完全兼容SysV腳本機制;因此,service命令依然可用;不過,建議使用systemctl命令來控制服務;

?# systemctl? {start|stop|restart|status}? name[.service]


6.啟動運行級別初始化控制:/etc/rc.d/rc#.d
(1)系統(tǒng)運行級別:為了系統(tǒng)的運行或維護等目的而設定的機制;
0-6:共7個級別;
0:關機, shutdown
1:單用戶模式(single user),root用戶,無須認證;維護模式;
2:多用戶模式(multi user),會啟動網(wǎng)絡功能,但不會啟動NFS;維護模式;
3:多用戶模式(mutli user),完全功能模式;文本界面;
4:預留級別:目前無特別使用目的,但習慣以同3級別功能使用;
5:多用戶模式(multi user), 完全功能模式,圖形界面;
6:重啟,reboot
1) 默認級別:3, 5
2) 級別切換:init #
3) 級別查看命令:who -r ;? runlevel
(2)/etc/rc.d目錄
1)rc #腳本:接受一個運行級別數(shù)字為參數(shù);當級別切換時啟動或關閉服務
K*:要停止的服務;
K##*,優(yōu)先級,數(shù)字越小,越是優(yōu)先關閉;依賴的服務先關閉,而后關閉被依賴的;
S*:要啟動的服務;
S##*,優(yōu)先級,數(shù)字越小,越是優(yōu)先啟動;被依賴的服務先啟動,而依賴的服務后啟動;
注意:按照glob通配,數(shù)字越小排在前面

注意:開機時啟動的服務,越早開啟,關閉的時候越靠后

2)/etc/rc.d/rc腳本框架(vim /etc/rc.d/rc)

關閉服務腳本:

for i in /etc/rc$runlevel.d/K* ; do# Check if the subsystem is already up.subsys=${i#/etc/rc$runlevel.d/K??}[ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] || continuecheck_runlevel "$i" || continue# Bring the subsystem down.[ -n "$UPSTART" ] && initctl emit --quiet stopping JOB=$subsys$i stop[ -n "$UPSTART" ] && initctl emit --quiet stopped JOB=$subsys done

開啟服務腳本:

for i in /etc/rc$runlevel.d/S* ; do# Check if the subsystem is already up.subsys=${i#/etc/rc$runlevel.d/S??}[ -f /var/lock/subsys/$subsys ] && continue[ -f /var/lock/subsys/$subsys.init ] && continuecheck_runlevel "$i" || continue# If we're in confirmation mode, get user confirmationif [ "$do_confirm" = "yes" ]; thenconfirm $subsysrc=$?if [ "$rc" = "1" ]; thencontinueelif [ "$rc" = "2" ]; thendo_confirm="no"fifiupdate_boot_stage "$subsys"# Bring the subsystem up.[ -n "$UPSTART" ] && initctl emit --quiet starting JOB=$subsysif [ "$subsys" = "halt" -o "$subsys" = "reboot" ]; thenexport LC_ALL=Cexec $i startfi$i start[ -n "$UPSTART" ] && initctl emit --quiet started JOB=$subsys done

開啟的時候執(zhí)行最后一個啟動腳本時,執(zhí)行/etc/rc.d/rc.local腳本,此腳本是啟動過程中最后啟動的一個腳本。

S99local做了一個軟鏈接給rc.local


(3)/etc/init.d/* (/etc/rc.d/init.d/*)腳本執(zhí)行方式:

# /etc/init.d/SRV_SCRIPT? {start|stop|restart|status}

# service? SRV_SCRIPT?? {start|stop|restart|status}


1.CentOS 6:

chkconfig命令:

管理控制/etc/init.d/每個服務腳本在各級別下的啟動或關閉狀態(tài);

1) 查看:chkconfig? --list?? [name]

2) 添加:chkconfig? --add? name

3) 刪除:chkconfig? --del? name

4) 修改指定的鏈接類型:

chkconfig? [--level? LEVELS]? name? <on|off|reset>

--level LEVELS:指定要控制的級別;默認為2345;

5) 能被添加的服務的腳本定義格式:

#!/bin/bash # # chkconfig: ### ## ## ======注釋:運行級別、啟動優(yōu)先級、關閉優(yōu)先級====== # description:



2.CentOS 7:(待續(xù))


(4)/etc/rc.d/rc.local腳本:開機自動讀取此文件中命令

正常級別下,最后啟動的一個服務S99local沒有鏈接至/etc/init.d下的某腳本

而是鏈接至了/etc/rc.d/rc.local (/etc/rc.local)腳本;

因此,不便或不需寫為服務腳本的程序期望能開機自動運行時,直接放置于此腳本文件中即可。


7.系統(tǒng)初始化腳本:/etc/rc.d/rc.sysinit

(1) 設置主機名;

(2) 設置歡迎信息;

(3) 激活udev和selinux;

(4) 掛載/etc/fstab文件中定義的所有文件系統(tǒng);

(5) 檢測根文件系統(tǒng),并以讀寫方式重新掛載根文件系統(tǒng);

(6) 設置系統(tǒng)時鐘;

(7) 根據(jù)/etc/sysctl.conf文件來設置內核參數(shù);

(8) 激活lvm及軟raid設備;

(9) 激活swap設備;

(10) 加載額外設備的驅動程序;

(11) 清理操作;


8.啟動終端

tty1:2345:respawn:/usr/sbin/mingetty tty1

... ...

tty6:2345:respawn:/usr/sbin/mingetty tty6

(1)mingetty會調用login程序;

(2)打開虛擬終端的程序除了mingetty之外,還有諸如getty等;



啟動開機流程總結:

內核級別:

1.POST做開機啟動時候的硬件檢測功能

2.BootSequence(BIOS)啟動加載主引導分區(qū)MBR中的引導加載器程序BootLoader

?? 在LInux現(xiàn)行的BootLoader是三段劃分(打破446字節(jié)限制)的GRUB程序,

????第1段寫在BootLoader中

????第1.5段在其后扇區(qū)用于文件系統(tǒng)的引導

????第2段在boot/grub中提供國土部接口和調用系統(tǒng)內核kernel

3.Kernel識別硬件、加載驅動、只讀掛載根文件系統(tǒng)、同時交付給用戶空間第一個程序/sbin/init

此處特別要注意,系統(tǒng)發(fā)行商為了適應多種硬件接口驅動調用,會在第一次安裝系統(tǒng)時候,自動識別硬件接口,并調用唯一驅動程序來生成ramdisk文件,以內存當磁盤做虛根,驅動接口后會切換到真實的根文件系統(tǒng)上

CentOS 5系列是initrd,當磁盤映像文件會造成二次緩存緩沖

CentOS 6/7系列改進為initramfs,以文件系統(tǒng)形式可以不二次占用緩存和緩沖

?

用戶空間級別

4./sbin/init接管后更具其配置文件來初始化

5.根據(jù)/sbin/init中的配置會設置默認運行級別,以及一些在/etc/init.d/設置的開機服務

6./etc/rc.d/rc.sysinit運行系統(tǒng)初始化腳本,完成系統(tǒng)初始化

7.關閉對應級別下需要停止的服務,啟動對應級別下需要開啟的服務

8.設置登錄終端 [--> 啟動圖形終端]






轉載于:https://blog.51cto.com/renjunjie622/1775749

總結

以上是生活随笔為你收集整理的CentOS系列启动流程和内核原理(5系列,6系列,7系列)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。