小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Linux啟動(dòng)分析 - linux study - 十年

 zhuziay 2011-05-24
第一部分 背景知識(shí)簡(jiǎn)介

  幾乎所有編寫(xiě)代碼的人都有這種體會(huì):如今在計(jì)算機(jī)這個(gè)行業(yè)中,許多技術(shù)不是你不懂,而是你不知道。所以,在分析之前有些背景知識(shí)是必須要知道的。

  一. 硬盤(pán)結(jié)構(gòu)簡(jiǎn)介

  1. 硬盤(pán)參數(shù)釋疑

  到目前為止, 人們常說(shuō)的硬盤(pán)參數(shù)還是古老的 CHS (Cylinder/Head/Sector)參數(shù). 那么為什么要使用這些參數(shù), 它們的意義是什么? 它們的取值范圍是什么?
  很久以前, 硬盤(pán)的容量還非常小的時(shí)候, 人們采用與軟盤(pán)類(lèi)似的結(jié)構(gòu)生產(chǎn)硬盤(pán),也就是硬盤(pán)盤(pán)片的每一條磁道都具有相同的扇區(qū)數(shù),由此產(chǎn)生了所謂的3D參數(shù) (Disk Geometry)。既磁頭數(shù)(Heads), 柱面數(shù)(Cylinders), 扇區(qū)數(shù)(Sectors),以及相應(yīng)的尋址方式。

  其中:
  磁頭數(shù)(Heads) 表示硬盤(pán)總共有幾個(gè)磁頭,也就是有幾面盤(pán)片, 最大為 255 (用 8 個(gè)二進(jìn)制位存儲(chǔ));
  柱面數(shù)(Cylinders) 表示硬盤(pán)每一面盤(pán)片上有幾條磁道, 最大為 1023(用 10 個(gè)二進(jìn)制位存儲(chǔ));
  扇區(qū)數(shù)(Sectors) 表示每一條磁道上有幾個(gè)扇區(qū), 最大為 63 (用 6個(gè)二進(jìn)制位存儲(chǔ));
  每個(gè)扇區(qū)一般是 512個(gè)字節(jié)(理論上講這不是必須的, 但好象都取此值)。

  據(jù)此,磁盤(pán)最大容量為:
  255 * 1023 * 63 * 512 / 1048576 = 8024 MB ( 1M = 1048576 Bytes )
  或硬盤(pán)廠商常用的單位:
  255 * 1023 * 63 * 512 / 1000000 = 8414 MB ( 1M = 1000000 Bytes )

  在 CHS 尋址方式中, 磁頭, 柱面, 扇區(qū)的取值范圍分別為 0 到 Heads - 1,0 到 Cylinders - 1, 1 到 Sectors (注意是從 1 開(kāi)始)。

  2. 基本 Int 13H 調(diào)用簡(jiǎn)介

  BIOS Int 13H調(diào)用是 BIOS 提供的磁盤(pán)基本輸入輸出中斷調(diào)用, 它可以完成磁盤(pán)(包括硬盤(pán)和軟盤(pán))的復(fù)位, 讀/寫(xiě), 校驗(yàn), 定位, 診斷, 格式化等功能。它使用的就是 CHS 尋址方式, 因此最大只能訪(fǎng)問(wèn) 8 GB 左右的硬盤(pán) ( 本文中如不作特殊說(shuō)明, 均以 1M = 1048576 字節(jié)為單位).
  而更不幸的是,標(biāo)準(zhǔn)的IDE接口容許256個(gè)扇區(qū)/磁道、65536個(gè)柱面及16個(gè)磁頭。它自己本身可以存取 137438953472(128 GB),但是加上BIOS方面63個(gè)扇區(qū)與1024個(gè)柱面的限制后,就只剩528482304(1024*16*63 = 504MB)可以定址得到,這就是所謂標(biāo)準(zhǔn)IDE硬盤(pán)只認(rèn)前504MB問(wèn)題。

  3. 現(xiàn)代硬盤(pán)結(jié)構(gòu)簡(jiǎn)介

  在老式硬盤(pán)中, 由于每個(gè)磁道的扇區(qū)數(shù)相等 (與軟盤(pán)一樣), 所以外道的記錄密度要遠(yuǎn)低于內(nèi)道, 因此會(huì)浪費(fèi)很多磁盤(pán)空間。為了解決這一問(wèn)題, 進(jìn)一步提高硬盤(pán)容量, 人們改用等密度結(jié)構(gòu)生產(chǎn)硬盤(pán), 也就是說(shuō), 外圈磁道的扇區(qū)比內(nèi)圈磁道多。采用這種結(jié)構(gòu)后, 硬盤(pán)不再具有實(shí)際的3D參數(shù), 尋址方式也改為線(xiàn)性尋址, 即以扇區(qū)為單位進(jìn)行尋址。
  為了與使用3D尋址的老軟件兼容 (如使用BIOS Int13H接口的軟件), 在硬盤(pán)控制器內(nèi)部安裝了一個(gè)地址翻譯器, 由它負(fù)責(zé)將老式3D參數(shù)翻譯成新的線(xiàn)性參數(shù)。這也是為什么現(xiàn)在硬盤(pán)的3D參數(shù)可以有多種選擇的原因 (不同的工作模式對(duì)應(yīng)不同的3D參數(shù), 如 LBA, LARGE, NORMAL)。

  4. 擴(kuò)展 Int 13H 簡(jiǎn)介

  雖然現(xiàn)代硬盤(pán)都已經(jīng)采用了線(xiàn)性尋址, 但是由于基本 Int 13H 的制約, 使用 BIOS Int 13H 接口的程序, 如 DOS 等還是只能訪(fǎng)問(wèn) 8 G 以?xún)?nèi)的硬盤(pán)空間。為了打破這一限制, Microsoft 等幾家公司制定了擴(kuò)展 Int 13H 標(biāo)準(zhǔn)(Extended Int13H,詳見(jiàn)附錄A), 采用線(xiàn)性尋址方式存取硬盤(pán),所以突破了 8 G 的限制,而且還加入了對(duì)可拆卸介質(zhì) (如活動(dòng)硬盤(pán)) 的支持。

  二. Boot Sector 結(jié)構(gòu)簡(jiǎn)介

  1. Boot Sector 的組成

  Boot Sector 也就是硬盤(pán)的第一個(gè)扇區(qū), 它由 MBR (Master Boot Record),DPT (Disk Partition Table) 和 Boot Record ID(Magic Number) 三部分組成。

  MBR 又稱(chēng)作主引導(dǎo)記錄,占用 Boot Sector 的前 446 個(gè)字節(jié) ( 0 to 0x1BD ),包含了硬盤(pán)的一系列參數(shù)和一段系統(tǒng)主引導(dǎo)程序。引導(dǎo)程序主要是用來(lái)在系統(tǒng)硬件自檢完后負(fù)責(zé)從活動(dòng)分區(qū)中裝載并運(yùn)行系統(tǒng)引導(dǎo)程序(引導(dǎo)操作系統(tǒng))。它的最后一條執(zhí)行語(yǔ)句是一條JMP指令,跳到操作系統(tǒng)的引導(dǎo)程序去。這里往往是引導(dǎo)型病毒的注入點(diǎn),也是各種多系統(tǒng)引導(dǎo)程序的注入點(diǎn)。但是由于引導(dǎo)程序本身完成的功能比較簡(jiǎn)單,所以我們完全可以判斷該引導(dǎo)程序的合法性(比如看JMP指令的合法性),因而也易于修復(fù)。象命令fdisk/mbr可以修復(fù)MBR和 KV300這類(lèi)軟件可以查殺任意類(lèi)型的引導(dǎo)型病毒,就是這個(gè)道理。
  DPT 即主分區(qū)表,占用 64 個(gè)字節(jié) (0x1BE to 0x1FD),記錄了磁盤(pán)的基本分區(qū)信息。主分區(qū)表分為四個(gè)分區(qū)項(xiàng), 每項(xiàng) 16 字節(jié), 分別記錄了每個(gè)主分區(qū)的信息(因此最多可以有四個(gè)主分區(qū))。
  Boot Record ID 即引導(dǎo)區(qū)標(biāo)記,占用兩個(gè)字節(jié) (0x1FE and 0x1FF), 對(duì)于合法引導(dǎo)區(qū), 它等于 0xAA55, 這是判別引導(dǎo)區(qū)是否合法的標(biāo)志.
  Boot Sector 的具體結(jié)構(gòu)如下圖所示:

  

  2. 主分區(qū)表的結(jié)構(gòu)

  主分區(qū)表由四個(gè)分區(qū)項(xiàng)構(gòu)成, 每一項(xiàng)的結(jié)構(gòu)如下:

  BYTE State : 分區(qū)狀態(tài), 0 = 未激活, 0x80 = 激活 (注意此項(xiàng))
  BYTE StartHead : 分區(qū)起始磁頭號(hào)
  WORD StartSC : 分區(qū)起始扇區(qū)和柱面號(hào), 低字節(jié)的低6位為扇區(qū)號(hào),高2位為柱面號(hào)的第 9,10 位, 高字節(jié) 為柱面號(hào)的低 8 位
  BYTE Type : 分區(qū)類(lèi)型, 如 0x0B = FAT32, 0x83 = Linux 等, 00 表示此項(xiàng)未用
  BYTE EndHead : 分區(qū)結(jié)束磁頭號(hào)
  WORD EndSC : 分區(qū)結(jié)束扇區(qū)和柱面號(hào), 定義同前
  DWORD Relative : 在線(xiàn)性尋址方式下的分區(qū)相對(duì)扇區(qū)地址 (對(duì)于基本分區(qū)即為絕對(duì)地址)
  DWORD Sectors : 分區(qū)大小 (總扇區(qū)數(shù))

  注意:在 DOS / Windows 系統(tǒng)下, 基本分區(qū)必須以柱面為單位劃分( Sectors * Heads 個(gè)扇區(qū)), 如對(duì)于 CHS 為 764/255/63 的硬盤(pán), 分區(qū)的最小尺寸為 255 * 63 * 512 / 1048576 = 7.844 MB。

  3. 擴(kuò)展分區(qū)簡(jiǎn)介

  由于主分區(qū)表中只能分四個(gè)分區(qū), 有時(shí)無(wú)法滿(mǎn)足需求, 因此設(shè)計(jì)了一種擴(kuò)展分區(qū)格式。 基本上說(shuō), 擴(kuò)展分區(qū)的信息是以鏈表形式存放的, 但也有一些特別的地方。
  首先,主分區(qū)表中要有一個(gè)基本擴(kuò)展分區(qū)項(xiàng), 所有擴(kuò)展分區(qū)都隸屬于它,也就是說(shuō)其他所有擴(kuò)展分區(qū)的空間都必須包括在這個(gè)基本擴(kuò)展分區(qū)中。 對(duì)于DOS / Windows 來(lái)說(shuō), 擴(kuò)展分區(qū)的類(lèi)型為 0x05。
  除基本擴(kuò)展分區(qū)以外的其他所有擴(kuò)展分區(qū)則以鏈表的形式級(jí)聯(lián)存放, 后一個(gè)擴(kuò)展分區(qū)的數(shù)據(jù)項(xiàng)記錄在前一個(gè)擴(kuò)展分區(qū)的分區(qū)表中, 但兩個(gè)擴(kuò)展分區(qū)的空間并不重疊。
  擴(kuò)展分區(qū)類(lèi)似于一個(gè)完整的硬盤(pán), 必須進(jìn)一步分區(qū)才能使用。但每個(gè)擴(kuò)展分區(qū)中只能存在一個(gè)其他分區(qū), 此分區(qū)在 DOS/Windows 環(huán)境中即為邏輯盤(pán)。因此每一個(gè)擴(kuò)展分區(qū)的分區(qū)表 (同樣存儲(chǔ)在擴(kuò)展分區(qū)的第一個(gè)扇區(qū)中)中最多只能有兩個(gè)分區(qū)數(shù)據(jù)項(xiàng)(包括下一個(gè)擴(kuò)展分區(qū)的數(shù)據(jù)項(xiàng))。
  擴(kuò)展分區(qū)和邏輯盤(pán)的示意圖如下:
  
  
  

  
  


  三. 系統(tǒng)啟動(dòng)過(guò)程簡(jiǎn)介

  系統(tǒng)啟動(dòng)過(guò)程主要由一下幾步組成(以硬盤(pán)啟動(dòng)為例):

  1. 開(kāi)機(jī);
  2. BIOS 加電或按reset鍵后都要進(jìn)行系統(tǒng)復(fù)位,復(fù)位后指令地址為 0ffff:fff0,這個(gè)地方只有一條JMP指令, 跳轉(zhuǎn)到系統(tǒng)自檢 ( Power On Self Test -- POST )程序處;
  3. 系統(tǒng)自檢完成后,將硬盤(pán)的第一個(gè)扇區(qū) (0頭0道1扇區(qū), 也就是Boot Sector)讀入內(nèi)存地址 0000:7c00 處;
  4. 檢查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于則轉(zhuǎn)去嘗試其他啟動(dòng)介質(zhì), 如果沒(méi)有其他啟動(dòng)介質(zhì) 則顯示 "No ROM BASIC" 然后死機(jī);
  5. 跳轉(zhuǎn)到 0000:7c00 處執(zhí)行 MBR 中的程序;
  6. MBR程序 首先將自己復(fù)制到 0000:0600 處, 然后繼續(xù)執(zhí)行;
  7. 在主分區(qū)表中搜索標(biāo)志為活動(dòng)的分區(qū),如果沒(méi)有發(fā)現(xiàn)活動(dòng)分區(qū)或有不止一個(gè)活動(dòng)分區(qū), 則轉(zhuǎn)停止;
  8. 將活動(dòng)分區(qū)的第一個(gè)扇區(qū)讀入內(nèi)存地址 0000:7c00 處;
  9. 檢查 (WORD) 0000:7dfe 是否等于 0xaa55, 若不等于則 顯示 "Missing Operating System" 然后停止, 或嘗 試軟盤(pán)啟動(dòng)或;
  10. 跳轉(zhuǎn)到 0000:7c00 處繼續(xù)執(zhí)行特定系統(tǒng)的啟動(dòng)程序;
  11. 啟動(dòng)系統(tǒng)...

  以上步驟中 2,3,4,5 步是由 BIOS 的引導(dǎo)程序完成. 6,7,8,9,10步由MBR中的引導(dǎo)程序完成.

  一般多系統(tǒng)引導(dǎo)程序 (如 SmartFDISK, BootStar, PQBoot 等)都是將標(biāo)準(zhǔn)主引導(dǎo)記錄替換成自己的引導(dǎo)程序, 在運(yùn)行系統(tǒng)啟動(dòng)程序之前讓用戶(hù)選擇要啟動(dòng)的分區(qū)。
  而某些系統(tǒng)自帶的多系統(tǒng)引導(dǎo)程序 (如 lilo, NT Loader 等)則可以將自己的引導(dǎo)程序放在系統(tǒng)所處分區(qū)的第一個(gè)扇區(qū)中, 在 Linux中即為 SuperBlock (其實(shí) SuperBlock 是兩個(gè)扇區(qū))。

  注:以上各步驟中使用的是標(biāo)準(zhǔn) MBR, 其他多系統(tǒng)引導(dǎo)程序的引導(dǎo)過(guò)程可能與此不同。

  下面簡(jiǎn)要說(shuō)明一下系統(tǒng)復(fù)位后的指令地址0ffff:fff0(物理地址0x0fffffff0):
  在實(shí)地址模式下,內(nèi)存有兩個(gè)保留區(qū)域:系統(tǒng)初始化區(qū)和中斷向量表區(qū)。地址0x00000~0x003ff 是為中斷向量保留的,256個(gè)可能的中斷,每一個(gè)保留4字節(jié)的跳轉(zhuǎn)向量;地址0xfffffff0~0xffffffff是為系統(tǒng)初始化保留的,此處一般只有一條JMP指令,跳到系統(tǒng)初始引導(dǎo)程序。
  系統(tǒng)復(fù)位后,cs = 0x0f000、eip = 0x0000fff0,而系統(tǒng)初始引導(dǎo)程序安排在 0x0ffff0000~0x0ffffffff, 一般為ROM固件,使初始引導(dǎo)程序工作于內(nèi)存實(shí)際地址空間以外的另一存儲(chǔ)段中。此區(qū)域的16~31位都應(yīng)為1,cs及eip的初值已保證地址線(xiàn)的16~19位為1,而20~31位,即地址線(xiàn)的高12位,則須由硬件強(qiáng)制置 1,這由一個(gè)標(biāo)志觸發(fā)器在系統(tǒng)每次復(fù)位時(shí)置位實(shí)現(xiàn)觸發(fā)。而由于段間轉(zhuǎn)移指令要重新裝入cs寄存器,因此,每當(dāng)執(zhí)行段間轉(zhuǎn)移指令時(shí),此標(biāo)志觸發(fā)器復(fù)位,以后,再次訪(fǎng)問(wèn)時(shí),不再向高12位地址線(xiàn)提供“1”信號(hào),程序從此正常地工作于前1MB的地址空間。


  第二部分 硬盤(pán)MBR主引導(dǎo)代碼分析

  一.程序流程

 ?。ㄒ龑?dǎo)扇區(qū)是指硬盤(pán)相應(yīng)分區(qū)的第一個(gè)扇區(qū),是和操作系統(tǒng)有關(guān)的,操作系統(tǒng)的引導(dǎo)是由它來(lái)完成的;而MBR主引導(dǎo)程序并不負(fù)責(zé)引導(dǎo)操作系統(tǒng),MBR是和操作系統(tǒng)無(wú)關(guān)的,他的任務(wù)是把控制權(quán)轉(zhuǎn)交給操作系統(tǒng)的引導(dǎo)程序.)

  1 將程序代碼由0:7C00H移動(dòng)到0:0600H(注,BIOS把MBR放在0:7C00H處)
  2 搜索可引導(dǎo)分區(qū),即80H標(biāo)志
  成功:goto 3
  失?。禾隦OM BASIC
  無(wú)效分區(qū)表:goto 5
  3 讀引導(dǎo)扇區(qū)
  失?。篻oto 5
  成功:goto 4
  4 驗(yàn)證引導(dǎo)扇區(qū)最后是否為55AAH
  失?。篻oto 5
  成功:goto 6
  5 打印錯(cuò)誤進(jìn)入無(wú)窮循環(huán)
  6 跳到0:7C00H進(jìn)行下一步啟動(dòng)工作

  二.代碼注釋

  下面將用匯編語(yǔ)言寫(xiě)出這一段代碼,并進(jìn)行說(shuō)明。

;MBR.ASM
; MASM MBR
; LINK MBR
; EXE2BIN MBR

.MODEL tiny
.CODE

  ;設(shè)置寄存器及堆棧值

org 0
Head:
Start:
cli
xor ax,ax
mov ss,ax
mov sp,7C00H ;ss:sp=0:7C00H
mov si,sp
push ax
pop es
push ax
pop ds ;es=ds=0
sti

  ;將程序代碼由0:7C00H移動(dòng)到0:0600H處

cld
mov di,600H
mov cx,100H ;100H Words=512 Bytes,即一個(gè)扇區(qū)大小
repne movsw
db 0EAH ;這個(gè)是FAR JUMP的機(jī)器碼
dw offset Continue+600H, 0000H ;這個(gè)是跳轉(zhuǎn)目的地址,即0:061DH

  ;搜索可引導(dǎo)分區(qū)

Continue:

mov si,600H+1BEH ;si指向分區(qū)表
mov bl,4 ;四個(gè)分區(qū)

FindBoot:

cmp byte ptr[si],80H
je SaveRec ;讀扇區(qū)位置
cmp byte ptr[si],0
jne Invaild ;無(wú)效分區(qū)
add si,10H
dec bl
jnz FindBoot
int 18H ;進(jìn)入ROM BASIC

  ;讀取引導(dǎo)分區(qū)的扇區(qū),柱面號(hào)

SaveRec:

mov dx,[si]
mov cx,[si+2]
mov bp,si

  ;檢查其余分區(qū)表

FindNext:

add si,10H
dec bl
jz SetRead
cmp byte ptr[si],0 ;是否存在非法分區(qū)
je FindNext

Invaild:

mov si,offset ErrMsg1+600H

  ;字符串輸出子程序

PrintStr:

lodsb
cmp al,0
je DeadLock
push si
mov bx,7
mov ah,0EH ;輸出字符
int 10H
pop si
jmp short PrintStr ;下一字符

DeadLock:

jmp short DeadLock ;無(wú)窮循環(huán),也可以寫(xiě)成jmp $

  ;讀引導(dǎo)扇區(qū)

SetRead:

mov di,5 ;讀取次數(shù)

ReadBoot:

mov bx,7C00H
mov ax,201H
push di
int 13H ;cx,dx已經(jīng)在SaveRec處得到
pop di
jnc GoBoot ;成功則啟動(dòng)
xor ax,ax
int 13H ;reset驅(qū)動(dòng)器,然后再讀取
dec di
jnz ReadBoot

mov si,offset ErrMsg2+600H
jmp short PrintStr 失敗輸出信息,并進(jìn)入無(wú)窮循環(huán)

  ;檢查讀入的引導(dǎo)扇區(qū)

GoBoot:

mov si,offsetErrMsg3+600H
mov di,7C00H+1FEH
cmp word ptr[di],0AA55H
jne PrintStr ;非AA55標(biāo)志則輸出錯(cuò)誤信息
mov si,bp ;si指向可啟動(dòng)分區(qū)
db 0EAH,0,7CH,0,0 ;跳轉(zhuǎn)至0:7C00H

ErrMsg1 db 'Invaild partition table',0
ErrMsg2 db 'Error loading operating system',0
ErrMsg3 db 'Missing operating system',0

Tail:

FillNum equ 1BEH-(Tail-Head) ;計(jì)算填0數(shù)目
db FillNum dup(0)

  ;四個(gè)分區(qū)表項(xiàng)數(shù)據(jù),跟分區(qū)情況有關(guān),詳細(xì)含義另解

PartTable db 80H,1,1,0,4,4,0D1H,2,11H,0,0,0,0FEH,0FFH,0,0
db 0,0,0C1H,3,5,4,0D1H,0FEH,0FFH,0FFH,0,0,0ACH,53H,0,0
db 20H dup(0)

ID dw 0AA55H

end start

;如果開(kāi)始試用org 600H,那么訪(fǎng)問(wèn)數(shù)據(jù)時(shí)就不必加上600H,如mov si,offset
ErrMsg2+600H
;可寫(xiě)為mov si,offset ErrMsg2,這時(shí)就不能用exe2bin得到數(shù)據(jù),必須試用debug
;debug mbr.exe
;-nmbr.bin
;-rcx 200
;-wcs:600
;-q

  在硬盤(pán)的第一個(gè)扇區(qū)上保存著分區(qū)信息,即主分區(qū)表,共有四項(xiàng),讀取分區(qū)表必須使用bios的int 13h,一般使用debug就可以了:

debug
-a
xxxx:0100 mov ax,201
mov bx,200
mov cx,1
mov dx,80 ;如果是第二個(gè)硬盤(pán)則是81...
int 13
int 20
xxxx:????
-g=100

  這時(shí)xxxx:0200開(kāi)始的512字節(jié)就是分區(qū)表所在的扇區(qū),前面一部分為MBR,在debug中用-d3be l40就可以看到64字節(jié)的分區(qū)表信息,16個(gè)字節(jié)為一項(xiàng),用-e命令就可以修改,改完后可以重新寫(xiě)回去,只要把前面代碼中的mov ax,201改為mov ax,301即可,或者直接把102處的2改成3,比如:

-e 102
xxxx:0102 02.3
-g=100

  這樣就寫(xiě)回去了,不過(guò)修改硬盤(pán)的第一個(gè)扇區(qū)須非常謹(jǐn)慎。

  下面說(shuō)一下分區(qū)表項(xiàng)的具體意義,取其中一項(xiàng)舉個(gè)例子:

  80 01 01 00 0B 3F FF 00 3F 00-00 00 81 4F 2F 00

  1 (80)引導(dǎo)標(biāo)志,80代表可引導(dǎo),00代表不可引導(dǎo),一般必須且只能有一個(gè)分區(qū)表項(xiàng)的引導(dǎo)標(biāo)志為 80,除非你自己修改MBR
  2 (01)分區(qū)開(kāi)始磁頭
  3,4 (01 00)=(0,1)分區(qū)開(kāi)始柱面和扇區(qū)(后面后詳解)
  5 (0B)分區(qū)類(lèi)型(后面有詳解)
  6 (3F)=(63)分區(qū)結(jié)束磁頭
  7,8 (FF 00)=(768,63)分區(qū)結(jié)束柱面和扇區(qū)(同上)
  9-12 (3F 00 00 00)=(63)此分區(qū)前扇區(qū)總數(shù),即相對(duì)扇區(qū)數(shù)
  13-16 (81 4F 2F 00)=(002F4F81H=3100545)此分區(qū)扇區(qū)總數(shù)

  柱面和扇區(qū)共用兩個(gè)字節(jié)表示,而柱面號(hào)為10位,最大1023,扇區(qū)號(hào)為6位,最大63,具體各位分布如下圖:
           扇區(qū)號(hào)
         _____|____
          |   |
  ( 7 6 5 4 3 2 1 0 ) ( 7 6 5 4 3 2 1 0 )
   |__|         |___________|
    |___________________|
         |
        柱面號(hào)

  關(guān)于分區(qū)類(lèi)型,常見(jiàn)的有:

  00 未用,Unused
  01 DOS-12(FAT 12)
  02 XENIX
  04 DOS-16(FAT 16)(分區(qū)<32M的,應(yīng)該已沒(méi)有了)
  05 EXTEND(DOS擴(kuò)展分區(qū))
  06 BIGDOS(>32M)(這個(gè)才是現(xiàn)在常說(shuō)的FAT 16)
  07 HPFS(OS/2)(NTFS也是這個(gè)標(biāo)記,好像是)
  0B FAT 32
  0F 這個(gè)一時(shí)不確定
  50 DM
  63 386/ix(unix)
  64 NET286(Novell)
  65 NET386(Novell)
  82 Linux swap
  83 Linux native
  FF BBT(UNIX Bad Block Table)

  下面有幾個(gè)算式用來(lái)計(jì)算分區(qū)參數(shù):

  1)第一分區(qū)參數(shù)

  扇區(qū)總數(shù)=(結(jié)束柱面+1)*磁頭數(shù)*每柱面扇區(qū)數(shù)-相對(duì)扇區(qū)數(shù),例如:3100545=(768+1)*64*63-63

  2)其它分區(qū)參數(shù)

  扇區(qū)總數(shù)=(結(jié)束柱面-起始柱面+1)*磁頭數(shù)*每柱面扇區(qū)數(shù),如下例:
  00 00 C1 01 05 3F FF FD C0 4F-2F 00 C0 90 0F 00
  000F90C0H=1020096,(FF FD)=(1021,63),(C1 01)=(769,1),1020096=(1021-769+1)*64*63

  3)第一分區(qū)相對(duì)扇區(qū)=每柱面扇區(qū)數(shù)
  其它分區(qū)相對(duì)扇區(qū)=上一分區(qū)相對(duì)扇區(qū)+上一分區(qū)扇區(qū)總數(shù)

  擴(kuò)展分區(qū)信息是一個(gè)鏈狀結(jié)構(gòu),在刪除分區(qū)時(shí),把前面的分區(qū)刪掉會(huì)導(dǎo)致后面的分區(qū)也找不到,原因就在于此,我們從主分區(qū)表中取出擴(kuò)展分區(qū)項(xiàng)進(jìn)行一下分析,如下:

  00 00 01 C0 05 FE BF 6E C0 10-2F 00 EF A6 69 00

  由此我們可以得到數(shù)據(jù):
  開(kāi)始磁頭:00 
  開(kāi)始柱面扇區(qū):01 C0=(192,1)

  用debug

  debug
  -a100
  xxxx:0100 mov ax,201
  mov bx,200
  mov cx,c001 ;開(kāi)始柱面扇區(qū)號(hào)
  mov dx,80 ;dh中為開(kāi)始磁頭號(hào),這里為0
  int 13
  int 20
  xxxx:????
  -g=100
  -d3be l10

  讀出的扇區(qū)中有兩個(gè)16字節(jié)的分區(qū)表項(xiàng)和最后的一個(gè)55AA標(biāo)志,這兩個(gè)分區(qū)表項(xiàng)為:

  00 01 01 C0 06 FE 7F 97 3F 00-00 00 99 F2 34 00
  00 00 41 98 05 FE BF 6E D8 F2-34 00 17 B4 34 00

  第一個(gè)分區(qū)類(lèi)型為6,其實(shí)這是第一個(gè)邏輯分區(qū),含義和主分區(qū)表項(xiàng)相同
  第二個(gè)分區(qū)類(lèi)型為5,這其實(shí)是指向下一個(gè)擴(kuò)展分區(qū)表的
  從這里我們可以得到:
  開(kāi)始磁頭:0
  開(kāi)始柱面扇區(qū):41 98=(408,1)

  繼續(xù)用debug讀出(mov cx,9841)得到

  00 01 41 98 06 FE BF 6E 3F 00-00 00 D8 B3 34 00

  只有一個(gè)表項(xiàng),是第二個(gè)邏輯盤(pán),而且是邏輯盤(pán)鏈的最后一個(gè)。
  可以看到,主分區(qū)表是非常重要的,所以除了小心操作外,還應(yīng)當(dāng)進(jìn)行備份,最安全的備份方式就是用筆抄下來(lái),當(dāng)然,每次重新進(jìn)行分區(qū)后還應(yīng)當(dāng)及時(shí)更新。從前面可以看出,分區(qū)表里最重要的還是柱面號(hào),其它比如磁頭號(hào)都是0或者1或者最大值,扇區(qū)號(hào)都是1或63(最大值),扇區(qū)總數(shù)什么的也都能算出來(lái),所以分區(qū)時(shí)最好把各分區(qū)的柱面號(hào)記下來(lái),這樣一旦分區(qū)信息被破壞就可以進(jìn)行恢復(fù)了。
  如果主分區(qū)表不幸丟失或者邏輯分區(qū)鏈被破壞,那么只要從硬盤(pán)上找出還存在的分區(qū)信息,就有可能部分恢復(fù)分區(qū)信息,甚至全部可以恢復(fù),不過(guò)這樣的麻煩大家還是應(yīng)盡量避免。
  在Linux里有一種方法可以恢復(fù)主引導(dǎo)扇區(qū)(包括主分區(qū)表),用如下的命令:
  dd if=/boot/boot.NNNN of=/dev/hda bs=512 count=1
  其中:boot.NNNN 是我們?cè)诎惭bLinux之前整個(gè)主引導(dǎo)扇區(qū)的備份,NNNN是分區(qū)的主次設(shè)備號(hào);bs(buffer size)是指重寫(xiě)的字節(jié)數(shù)。如只是為了修復(fù)主引導(dǎo)記錄MBR(比如,想把LILO卸載掉),而不是恢復(fù)整個(gè)主引導(dǎo)扇區(qū),則用如下的命令:
  dd if=/boot/boot.NNNN of=/dev/hda bs=446 count=1
  只把主引導(dǎo)扇區(qū)的備份文件boot.NNNN的前446個(gè)字節(jié)重寫(xiě)入主引導(dǎo)扇區(qū)。


LILO 詳解  


  一臺(tái)電腦從加電到進(jìn)入操作界面是經(jīng)過(guò)了一系列復(fù)雜的操作的。基本的工作是由BIOS完成的。當(dāng)POST(自檢)結(jié)束后,BIOS嘗試讀入 BIOS設(shè)定的第一個(gè)啟動(dòng)設(shè)備的第一個(gè)扇區(qū),把它看作引導(dǎo)扇區(qū)(原先的BIOS總是先嘗試軟盤(pán)的),然后讀入里面的信息來(lái)引導(dǎo)系統(tǒng)。
  我們先來(lái)看看DOS的系統(tǒng)引導(dǎo)區(qū):
  OFFSET
  0x000 JMP xx     ; 近距離跳轉(zhuǎn)到xx代碼段
  0x003         ; 磁盤(pán)參數(shù)
  0x03E         ; 載入DOS系統(tǒng)核心的代碼段
  0x1FE 0xAA55     ; 這是BIOS的幻數(shù)
  DOS的引導(dǎo)區(qū)總是從0開(kāi)始,以BIOS的magic number 結(jié)束,總共512字節(jié)。從軟盤(pán)啟動(dòng)比較簡(jiǎn)單,因?yàn)橹挥幸粋€(gè)引導(dǎo)扇區(qū):第一個(gè)扇區(qū)。而硬盤(pán)雖然有很多分區(qū),但是,BIOS根本不去查看分區(qū)信息,它象對(duì)待軟盤(pán)一樣對(duì)待硬盤(pán),仍讀入第一個(gè)分區(qū):master boot record (MBR).
  所以MBR也應(yīng)該從0開(kāi)始,以BIOS的magic number 結(jié)束。在MBR的最后部分保存了分區(qū)表。每個(gè)分區(qū)信息占16字節(jié),定義了硬盤(pán)可以有4個(gè)Primary Partition。如果這些不夠用,可以設(shè)置所謂的擴(kuò)展分區(qū)。擴(kuò)展分區(qū)包含至少一個(gè)邏輯分區(qū)。擴(kuò)展分區(qū)的第一個(gè)扇區(qū)結(jié)構(gòu)類(lèi)似MBR,它的分區(qū)表的第一表項(xiàng)對(duì)應(yīng)第一個(gè)邏輯分區(qū)。如果存在第二個(gè)邏輯分區(qū),那么分區(qū)表的第二個(gè)表項(xiàng)就包含了一個(gè)指針。這個(gè)指針指向第一個(gè)邏輯分區(qū)后面的一個(gè)地址。這個(gè)地址包含一個(gè)分區(qū)表。該分區(qū)表的第一表項(xiàng)對(duì)應(yīng)第二個(gè)邏輯分區(qū)。這樣就組成一個(gè)鏈表,從而擴(kuò)展分區(qū)可以有任意多的邏輯分區(qū)。
  每一個(gè)主分區(qū)和擴(kuò)展區(qū)都包含一個(gè)引導(dǎo)扇區(qū)。系統(tǒng)只能從這幾個(gè)地方之一啟動(dòng)。BOOT標(biāo)志決定哪個(gè)分區(qū)的引導(dǎo)扇區(qū)被引導(dǎo)。 MS-DOS的fdisk和大多數(shù)同類(lèi)工具只能激活主分區(qū)。
  MBR的代碼要作以下的操作:
  1:確定活動(dòng)分區(qū)(Active Partition)
  2:使用BIOS,將活躍分區(qū)的啟動(dòng)扇區(qū)讀入
  3:跳到啟動(dòng)扇區(qū)的0位置。
  MBR的空間足夠容納一個(gè)引導(dǎo)程序來(lái)動(dòng)態(tài)的決定活動(dòng)分區(qū)。LILO就是這樣一個(gè)引導(dǎo)程序。

  LILO(LInux LOader)
  LILO引導(dǎo)扇區(qū)包括一個(gè)分區(qū)表的空間,所以,LILO即可以安裝在MBR中,也可以安裝在某個(gè)分區(qū)的引導(dǎo)扇區(qū)。
  1.LILO可以占據(jù)MBR,但是會(huì)將老的MBR沖去,出于安全起見(jiàn),最好在在安裝LILO前,將老的MBR(包括分區(qū)表)做一個(gè)備份。可以通過(guò)鍵入
  # dd if=/dev/hda of=/backup/MBR bs=512 count=1
  來(lái)備份原來(lái)的MBR信息,
  如果要將MBR寫(xiě)回,可以鍵入:
  # dd if=/backup/MBR of=/dev/hda bs=446 count=1
  這樣,原來(lái)的MBR就被寫(xiě)回但不包括分區(qū)表。如果分區(qū)表也要恢復(fù),那么設(shè)置bs=512。

  2.通過(guò)MS-DOS MBR被引導(dǎo)
  LILO就可以安裝在這些分區(qū)中的一個(gè)。當(dāng) LILO對(duì)應(yīng)分區(qū)被激活后,引導(dǎo)過(guò)程如下:
   BIOS 讀入 MBR
   MBR 讀入 活躍主分區(qū):LILO所在的分區(qū);
   LILO 引導(dǎo)Linux或另外的操作系統(tǒng)。
  要引導(dǎo)其它OS且不用LILO很簡(jiǎn)單,激活那個(gè)分區(qū)。Linux分區(qū)不會(huì)有任何變化。

  3.LILO也可以被其他的系統(tǒng)引導(dǎo)程序(Boot Manager)引導(dǎo)
  1. 假如boot manager可以引導(dǎo)擴(kuò)展區(qū),Linux可以裝在擴(kuò)展區(qū)上;
  2. 假如 boot manager 可以引導(dǎo)第二硬盤(pán)分區(qū),linux可以裝在第二硬盤(pán)上;
  3. 有些 boot manager 甚至可以引導(dǎo)邏輯分區(qū),那LILO就可以裝在邏輯分區(qū)上。
  但是對(duì)于系統(tǒng)引導(dǎo)程序要特別注意的是:某些操作系統(tǒng)直接改寫(xiě)MBR,這會(huì)將原來(lái)的boot manager破壞。

  配置LILO
  與LILO有關(guān),即有關(guān)系統(tǒng)引導(dǎo)的文件通常放在/boot/下,配置文件是/etc/lilo.conf下。合理的配置lilo. conf對(duì)于系統(tǒng)的正常高效運(yùn)行有著非常重大的意義,可以通過(guò)man lilo.conf來(lái)查看配置的注意事項(xiàng)
  下面是一些重要常用的選項(xiàng):
  "boot="
    指明包含引導(dǎo)扇區(qū)的設(shè)備名(如:/dev/had),若此項(xiàng)忽略,則從當(dāng)前的根分區(qū)中讀取引導(dǎo)扇區(qū)。
  "root="
    告訴內(nèi)核啟動(dòng)時(shí)以哪個(gè)設(shè)備作為根文件系統(tǒng)使用,其設(shè)定值為構(gòu)造內(nèi)核時(shí)根文件系統(tǒng)的設(shè)備名,可用的設(shè)備名有:
    (1)/dev/hdaN~/dev/hddN:ST-506兼容硬盤(pán),a到d上的N個(gè)分區(qū)
    (2)/dev/sdaN~/dev/sdeN:SCSI兼容硬盤(pán),a到e上的N個(gè)分區(qū)
    (3)/dev/xdaN~/dev/xdbN:XT兼容硬盤(pán),a到b上的N個(gè)分區(qū)
    (4)/dev/fdN:軟盤(pán),A:(N=0)或B:(N=1)
    (5)/dev/nfs:由網(wǎng)絡(luò)取得根文件系統(tǒng)的標(biāo)志
  "nfsroot="
    若需通過(guò)NFS提供根文件系統(tǒng)來(lái)引導(dǎo)無(wú)盤(pán)工作站,此參數(shù)為內(nèi)核指定了網(wǎng)絡(luò)根文件系統(tǒng)所在的機(jī)程序、目錄及NFS,其格式為:nfsroot=(〈server_ip〉:)〈root_dir〉(,nfs_options))
  "nfsaddrs="
    設(shè)定網(wǎng)絡(luò)通訊所需的各種網(wǎng)絡(luò)界面地址,如無(wú)此參數(shù),則內(nèi)核會(huì)試圖用反向地址解析協(xié)定(RARP)或啟動(dòng)協(xié)定(BOOTP)找出這些參數(shù),其格式為:
    nfsaddrs=〈客戶(hù)端IP〉:〈服務(wù)端IP〉:〈網(wǎng)關(guān)IP〉:〈子網(wǎng)屏蔽〉:
   〈客戶(hù)端名稱(chēng)〉:〈網(wǎng)絡(luò)設(shè)備名 〉:〈auto〉
  "image="
    指定Linux的內(nèi)核文件。
  "delay="
    以10毫秒為單位,設(shè)定引導(dǎo)第一個(gè)映像前的等待時(shí)間。
  "disk="
    某一特殊的硬盤(pán)定義非標(biāo)準(zhǔn)參數(shù)。
  "append="
    為內(nèi)核傳遞一個(gè)可選的參數(shù)行,其典型的應(yīng)用是為不能完全由系統(tǒng)自動(dòng)識(shí)別的硬盤(pán)指定參數(shù),如:append = "hd=64,32,202",還有為一些無(wú)法自動(dòng)識(shí)別大內(nèi)存的低版本內(nèi)核傳遞參數(shù),方法是append="mem=128M".mem后邊是數(shù)字+單位,這個(gè)單位可以是byte/M等等

  "label="
    為每個(gè)映像指定一個(gè)名字,以供引導(dǎo)時(shí)選擇。
  "read-only"
    設(shè)定以只讀方式掛入根文件系統(tǒng),用于文件系統(tǒng)一致性檢查(fsck)
  "install="
    安裝一個(gè)指定文件作為新的引導(dǎo)扇區(qū),缺省為/boot/boot.b。
  "loader="
    說(shuō)明所使用的鏈加載程序(chain loader),缺省為/boot/chain.b,如果不是從首硬盤(pán)或軟盤(pán)啟動(dòng),那么,此選項(xiàng)必須說(shuō)明。
  "table="
    說(shuō)明包含分區(qū)表的設(shè)備名,如果此參數(shù)忽略,引導(dǎo)加載程序?qū)⒉荒軅鬟f分區(qū)信息到已引導(dǎo)的操作系統(tǒng)。當(dāng)此參數(shù)指向的分區(qū)表被修改時(shí),必須重新運(yùn)行/sbin/lilo。
  "init="
    內(nèi)核初始化時(shí)執(zhí)行的程序,通常過(guò)程為init、getty、rc和sh,版本1.3.43以來(lái)的Linux內(nèi)核能夠執(zhí)行/sbin/init說(shuō)明的命令行,若在引導(dǎo)過(guò)程中出現(xiàn)問(wèn)題,則可設(shè)置init=/bin/sh直接跳到Shell。
  "ramdisk_start="
    由于內(nèi)核不能放在壓縮的內(nèi)存文件系統(tǒng)映像內(nèi),為使內(nèi)核映像能夠和壓縮的內(nèi)存映像放在一張軟盤(pán)內(nèi),加入"ramdisk_start=〈offset〉",這樣內(nèi)核才開(kāi)始執(zhí)行。
  "vga="
    設(shè)置顯示模式,如80×50、132×44等。
  "compact"
    激活一種模式,在此模式下,LILO一次向BIOS請(qǐng)求讀入相鄰的幾個(gè)分區(qū)。這極大的縮短了裝載時(shí)間,特別是從軟盤(pán)啟動(dòng)。
  "Linear"
   使LILO生成線(xiàn)性地址,而不使用通常的Sector/Head/Cylinder機(jī)制。Linux地址機(jī)制可以不依賴(lài)磁盤(pán)的物理結(jié)構(gòu)。
  "install = boot sector"
    使用指定的boot sector寫(xiě)入引導(dǎo)扇區(qū),缺省用/boot/boot.b
  "map="
    說(shuō)明映射文件的路徑。
  "message=[File]"
    指定一個(gè)文件,該文件的內(nèi)容將會(huì)在LILO引導(dǎo)是被顯示。假如沒(méi)有說(shuō)明該文件,那么就只會(huì)出現(xiàn)"LILO"。
  "verbose=[level]"
    說(shuō)明LILO的調(diào)試級(jí)別。從0(不顯示任何信息)到5(所有的狀態(tài)信息)。
  "backup = [backup file]"
    以前引導(dǎo)扇區(qū)內(nèi)容的備份文件。缺省使用/boot/boot.device number
  "force-backup=[backup file]"
    和backup 相同,當(dāng)時(shí)假如備份文件存在,被覆蓋。
  "prompt"
    指定要用戶(hù)通過(guò)鍵盤(pán)選擇要引導(dǎo)的內(nèi)核。不會(huì)缺省選擇。
  "timeout="
    設(shè)置一個(gè)超時(shí)值,在此時(shí)間內(nèi)必須有鍵盤(pán)輸入,否則用第一個(gè)配置。類(lèi)似,假如超時(shí),就不能再輸入密碼。一般情況下,該取缺省值,無(wú)窮大。
  "serial=port, bps parity bits"
    設(shè)置串口參數(shù)。如果LILO會(huì)從該文件獲取串口參數(shù)的話(huà)。如果其中之一無(wú)效,那所有三個(gè)參數(shù)都無(wú)效。Port從四個(gè)標(biāo)準(zhǔn)串口選擇一個(gè):0 對(duì)應(yīng)COM1 或者/dev/ttyS0.。支持的波特率范圍為:100-9600。所有校驗(yàn)設(shè)置都支持(n:none,e:even,o:odd)bits為7或者 8。缺省為serial=0,2400n8.
  Ignore-table
    讓LILO忽略被破壞的分區(qū)表。
  fix-table
  允許LILO將每個(gè)分區(qū)的(sector/head/cylinder)地址轉(zhuǎn)化為線(xiàn)性地址。通常,分區(qū)地址從cylinder boudary開(kāi)始。某些操作系統(tǒng),會(huì)改變這一點(diǎn)。由于LILO只能將它的啟動(dòng)扇區(qū)寫(xiě)于兩種地址都一致的分區(qū)上,不正確的3D地址可以用fix- table來(lái)糾正。但是,這種糾正不能被保證是永遠(yuǎn)的,所以重分區(qū)以保證對(duì)齊cylinder boudary 是最好的選擇。
  "password=[password]"
    為引導(dǎo)配置設(shè)置password
  restricted
    放松對(duì)password的限制。只有用戶(hù)想傳附加的啟動(dòng)參數(shù)給內(nèi)核時(shí)才需要password
  optional
    允許配置的幾個(gè)內(nèi)核有錯(cuò)誤的,或者不存在,如果不說(shuō)明optional,LILO遇到這種情況就會(huì)打印一些錯(cuò)誤信息然后退出。

  LILO引導(dǎo)過(guò)程
  每個(gè)從LILO引導(dǎo)的配置從image行開(kāi)始。
  image = kernel
   label = name
  Image包含要引導(dǎo)的內(nèi)核。Label是給用戶(hù)選擇用的。Image行通常指向一個(gè)設(shè)備,例如/dev/fd0,可以找到內(nèi)核的范圍用range來(lái)注明。
  range = range
  range可以用start sector -end sector 或者 start sector + length 表示。例如:
  image = /dev/fd0
   label = floppy
  range = 1+512

  LILO 啟動(dòng)信息
  缺省設(shè)置的LILO啟動(dòng)過(guò)程中在啟動(dòng)過(guò)程中,LILO會(huì)顯示'LILO',如果LILO出錯(cuò)退出, 可以根據(jù)顯示來(lái)判斷系統(tǒng)的出錯(cuò)原因。
   沒(méi)有信息:LILO根本就沒(méi)有被讀入,沒(méi)安裝LILO,或LILO駐留的分區(qū)沒(méi)被激活。
   Lnumber : LILO的第一部分被讀入并開(kāi)始執(zhí)行。但第二部分不能被讀入。后面的數(shù)字表明出錯(cuò)原因。這可能是由于硬盤(pán)的物理錯(cuò)誤或不正確的物理結(jié)構(gòu)信息
   LI: LILO的第一部分可以讀入第二部分,第二部分執(zhí)行時(shí)出錯(cuò)。這可能是不正確的物理結(jié)構(gòu)信息或重裝了boot.b而沒(méi)有運(yùn)行LILO重新安裝。
   LIL:LILO的第二部分啟動(dòng)起來(lái)了,但是不能從map文件讀入descriptor tables.這說(shuō)明不正確的物理結(jié)構(gòu)信息或物理錯(cuò)誤。
   LIL?: LILO的第二部分被讀到不正確的地址。原因同LI
   LIL-: descriptor tables有錯(cuò)。這可能是不正確的物理結(jié)構(gòu)信息或重裝了map file而沒(méi)有運(yùn)行LILO重新安裝。

  LILO的卸載
  LILO裝在MBR以后,它會(huì)保留一個(gè)MBR的備份在系統(tǒng)的/boot/boot.xxyy中,其中xyy是16進(jìn)制的設(shè)備主/次號(hào)碼(major/minor numbers),利用命令"ls -l /dev/device"就可獲得硬盤(pán)或分區(qū)的主/次號(hào)碼。如果這些備份文件已經(jīng)存在,那么,當(dāng)你重新安裝LILO時(shí),它將不再生成此文件,這就保證了此備份文件是最原始的引導(dǎo)扇區(qū)。
 若要卸載LILO,你只需恢復(fù)初始的引導(dǎo)扇區(qū)就可以了。例如:LILO安裝在/dev/had,對(duì)應(yīng)的備份文件為/boot/boot.0300,使用下面的命令即可:
  # dd if=/boot/boot.0300 of=/dev/had bs=446 count=1
 
  LILO是現(xiàn)在Redhat Linux、TurboLinux等許多Linux distribution缺省的引導(dǎo)程序,正如上面所介紹的,擁有很強(qiáng)大的功能,更詳細(xì)的內(nèi)容可以在lilo安裝的README文件中發(fā)現(xiàn)。最重要的是在良好的備份意識(shí)指導(dǎo)下,多多實(shí)踐,這樣才能得到最佳的效果。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多