歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

嵌入式Linux下fdisk處理磁盤MBR的可選ID

在嵌入式Linux中,經常涉及到格式化硬盤,常用的工具就是fdisk,這工具功能強大,busybox裡面也實現了fdisk。當busybox實現的fdisk是簡化版,與原版的GNU的fdisk相差挺大的,主要是缺少一些細節性的功能。

本文主要是說明fdisk寫入MBR的一個磁盤可選id,這個區域可以用來唯一的標記一塊硬盤,總共有4個字節,2的32次方中情況。

以後將會詳細的介紹MBR結構。。
以下是摘自維基百科的一個表格,介紹MBR的結構:
Structure of a master boot record
Address DescriptionSize in bytes
Hex Oct Dec
0000 0000 0 code area 440(max. 446)
01B8 0670 440 disk signature (optional)4 (本文涉及到該區域)
01BC 0674 444 Usually nulls; 0x00002
01BE 0676 446 Table of primary partitions(Four 16-byte entries, IBM partition table scheme)64
01FE 0776 510 55h MBR signature 2
01FF 0777 511 AAh
MBR, total size: 446 + 64 + 2 = 512

如果要修改該區域,需要確保該區域的地址,地址是:440-443;該區域占4個字節,只需要用一個int型變量即可讀取。

源碼如下:

  1. int main(void)  
  2. {  
  3.     int fd;  
  4.     unsigned int id;  
  5.     fd = open("/dev/sda", O_RDONLY);  
  6.     if (fd < 0) {  
  7.         perror("open");  
  8.         exit(1);  
  9.     }  
  10.       
  11.     lseek(fd, 440, SEEK_SET);  
  12.     if (read(fd, &id, 4) != 4) {  
  13.         perror("read");  
  14.         close(fd);  
  15.         exit(1);  
  16.     }  
  17.     close(fd);  
  18.     return 0;  
  19. }  
上面已經說了,busybox可能沒有實現fdisk這個功能,有些時候嵌入式系統需要標志硬盤ID,所以需要隨機產生一個數字來寫入硬盤的MBR的磁盤可選id的區域,這隨便產生一個隨機數就行,可以使用time(NULL)獲取,很簡單。
在GNU的fdisk源碼中,使用以下函數來生成唯一id:
  1. static unsigned int get_random_id(void) {  
  2.     int fd;  
  3.     unsigned int v;  
  4.     ssize_t rv = -1;  
  5.       
  6.     fd = open("/dev/urandom", O_RDONLY);  
  7.     if (fd >= 0) {  
  8.         rv = read(fd, &v, sizeof v);  
  9.         close(fd);  
  10.     }  
  11.       
  12.     if (rv == sizeof v)  
  13.         return v;  
  14.       
  15.     /* Fallback: sucks, but better than nothing */  
  16.     return (unsigned int)(getpid() + time(NULL));  
  17. }  

該函數是去讀取/dev/urandom設備,該設備用於產生一個無符號的隨機數,如果讀取失敗,將會直接返回進程的pid與當前的unix時間的總和,以保證返回一個唯一的id。

以下源碼產生一個唯一id,並寫入mbr的磁盤可選id的區域:

  1. int main(void)  
  2. {  
  3.     int fd;  
  4.     unsigned int id;  
  5.     id = get_random_id();  
  6.       
  7.     fd = open("/dev/sda", O_RDONLY);  
  8.     if (fd < 0) {  
  9.         perror("open");  
  10.         exit(1);  
  11.     }  
  12.       
  13.     lseek(fd, 440, SEEK_SET);  
  14.     if (write(fd, &id, 4) != 4) {  
  15.         perror("write");  
  16.         close(fd);  
  17.         exit(1);  
  18.     }  
  19.     close(fd);  
  20.     return 0;  
  21. }  
這裡一定要指定4個字節,如果不確定,可能會造成越界,影響到其他區域。
保存在該區域,不會影響到MBR的正常使用,這區域本來就是保留著,可選使用。
Copyright © Linux教程網 All Rights Reserved