Sunday, October 26, 2008

FAT series file system

在開始看以前可以先參考一下小木偶的FAT12教學FAT32教學 尤其是FAT12一定要先看一下。

右圖是我的電腦裡硬碟的MBR,從最後反白的那四行(1BE開始的64 bytes,稱為partition table)可以看出真正有作用的只有前兩個16 bytes。這邊可以得知我的硬碟上有兩個partition。以第一組16 bytes來說,第一個byte 80代表這是個開機的磁區,再來01 01 00代表是head 1, sector 1, cylinder 0。注意:第二組01的前兩個bits其實是裝在最後那組cylinder的前面,所以實際上sector是六個bit最大值為63,sector最小是從1開始,而cylinder因為有十個bits的緣故,且從零開始,所以最多有1024個cylinder。上面這個Cylinder, Head, Sector的地址方式稱為CHS。但因為他只能定址8.4G的緣故,所以現在已經不用這種方式了,用後面會說到的LBA線性方式定址。再來一個Byte 07是代表NTFS,這個byte所代表的意義可以查詢Andries E. Brouwer寫的partition type。再來FE FF FF分別為head , sector, cylinder所代表的結束位置。這邊因為超過了8.4G最大能表達的範圍所以填入最大值。00 00 00 3F代表的是第一個partition開始的位置,以sector的大小為單位也就是512 bytes,相對於零開始,所以是0x3F * 0x200 = 0x7E00 = 32256 bytes 除以1024後等於31.5k,這也就是為什麼Hexedit的start sectors會顯示31.5k。可以參考右邊的圖示。

03 C0 2E CE代表的是第一個partition的大小。可以算得他的大小為0x03C02ECE * 0x200 = 0x7805D9C00 = 32,218,389,504 bytes差不多是30G。下一個partition entry就依此類推。這個是在我電腦上的硬碟,因為是NTFS的緣故,所以只用來解釋partition table的觀念,接下來看我的隨身碟,是由FAT32所format而成的。







如右圖所示,首先先把隨身碟Format成FAT的格式,也就是FAT16。







接著,用winhex開啟我們的磁碟,並且選取Partition 1
,和上面同樣的,Partition 1 坐落在0x7E00的位置。















再來看到Boot Sector這裡面就有詳細的說明。按照Reserved sectors =4,所以從0x7E00開始,有四個sectors是保留的磁區,第五個Sector就是第一個FAT table。0x7E00 + 0x200 * 0x4 = 0x8600。Boot Sector裡頭有BPM這是FAT定義的partition基本資料。


如果你去看0x8600的位置,可以看到只有四個bytes的值。
前兩個bytes是F8 FF,所以代表是一顆硬碟。後兩個通常是FF FF沒有意義。因為我們還沒有置放檔案在這顆硬 碟,所以之後的欄位皆為零。



接著我們可以算得Root directory =( Reserved sectors + number of FATs * sectors per FAT ) x 512 + Base address
= ( 4 + 2 x 246 ) x 512 + 0x7E00 = 0x45E00













參考右邊這個圖,這就是整個MBR與file system的關係。右下角是一個partition。是代表第一個
partition entry的partition。











接下來我們新增一個文字檔,之後再觀察FAT和Root directory以
及data area的變化。






從root directory的位置,0x45E00可以
看到首先第一個32 bytes是儲存隨身碟
的名稱KINGSTON。不滿的以20填滿。在20之后有一個08,代表的是這個ENTRY儲存隨身碟的名稱。再來到下一個32 bytes的起始位置,0x45E20,可以看到接下來幾個32 bytes的FDB(file descriptor block)都是以E5為開頭,這代表的是已經被刪除的檔案。在這裡發現,我之前只是把檔名作更改而已,但是事實上,os的作法會新增一個新的FDB,並不會更改原本的FDB。我們看到最後一個FDB也就是0x45EC0,可以看到一開始的11 bytes就是檔名。然後在0x45EDA開始的兩個bytes 0002就是起始的cluster。接下來的四個bytes 00 00 00 0C代表的是檔案的大小,是以bytes為單位。所以我們的1234567.txt為12 bytes。因為裡頭有12個3。


因為這邊是FAT16的緣故所以,以16bits為單位。前面兩個word之前有說過。保留給系統使用。最後一個word就是第二個entry也就是我們1234567.txt檔的起始位置cluster,同時第二個entry也是data area開始的地方。這邊顯示為FFFF代表這個檔案沒有接續下一個cluster(在FAT的儲存方式裡,FAT entry所儲存的是下一個cluster的號碼,如果是最後一個cluster則為FFFF)。就在這個cluster結束。雖然只有12 bytes但這邊還是佔有一個cluster。一個cluster佔有32個sectors所以大小為16KB。

在Data area的開始處,也就是文字檔開始的地方可以看到12個3。

Wednesday, October 08, 2008

簡單的Gas inline assembly

簡單的gas入門嘗試如下,output field裡頭的"=r"改成"+r"之後就一帆風順了。
=是write only的意思。+是read-write。

#include

void main()
{
int x = 1;
int z = 3;
int y = 0;
printf("x = %d,y = %d, z = %d",x, y, z );

__asm__ __volatile__("movl %1, %0\n\t"
"movl %2, %0\n\t"
:"+r"(y)
:"r"(z),"r"(x)
:"0"
);

printf("\nx = %d, y = %d, z = %d", x, y, z);

}