歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 嵌入式Linux下fdisk處理磁盤MBR的可選ID

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

日期:2017/3/1 10:44:48   编辑:Linux編程

在嵌入式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. lseek(fd, 440, SEEK_SET);
  11. if (read(fd, &id, 4) != 4) {
  12. perror("read");
  13. close(fd);
  14. exit(1);
  15. }
  16. close(fd);
  17. return 0;
  18. }
上面已經說了,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. fd = open("/dev/urandom", O_RDONLY);
  6. if (fd >= 0) {
  7. rv = read(fd, &v, sizeof v);
  8. close(fd);
  9. }
  10. if (rv == sizeof v)
  11. return v;
  12. /* Fallback: sucks, but better than nothing */
  13. return (unsigned int)(getpid() + time(NULL));
  14. }

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