0

Đăng ký mtd_info

Một phần của tài liệu THUYẾT TRÌNH LƯU CHỮ DỮ LIỆU.DOC (Trang 25-25 )

Các bước sau đây và áp dụng chung cho cả NAND và NOR nhấp nháy. Cơ sở đăng ký là add_mtd_device chức năng () chức năng,có thêm các thiết bị đến các mảng mtd_table []. Tuy nhiên trong hầu hết các trường hợp, bạn sẽ không sử dụng chức năng này trực tiếp bởi vì bạn muốn tạo phân vùng trên chip.

Phân vùng

Phân vùng cho phép nhiều phân vùng trên một đèn flash được tạo ra và được thêm vào khe khác nhau trong mảng mtd_table []. Vì vậy, các phân vùng sẽ được xuất khẩu như nhiều thiết bị để ứng dụng. Các phân vùng khác nhau chia sẻ cùng các chức năng để truy cập vào các mảng. Ví dụ, bạn sẽ

muốn chia 4-MB flash thành 1-MB và 3-MB phân vùng như trong hình 4.3. Chìa khóa để phân vùng là mtd_partition cấu trúc dữ liệu. Bạn sẽ xác định một mảng của cấu trúc dữ liệu để xuất khẩu phân vùng.

454. struct mtd_partition partition_info[] =

455. {

456. { .name=”part1”, .offset=0, .size= 1*1024*1024}, 457. Listing 4.2 Dummy Read Routines

458.

459. static inline int dummy_flash_read_one_chip(struct map_info *map, 460. struct flchip *chip, loff_t addr, size_t len, u_char *buf)

461. { 462. DECLARE_WAITQUEUE(wait, current); 463. 464. again: 465. spin_lock(chip->mutex); 466. 467. if(chip->state != FL_READY) 468. { 469. set_current_state(TASK_UNINTERRUPTIBLE); 470. add_wait_queue(&chip->wq, &wait); 471. spin_unlock(chip->mutex); 472. schedule(); 473. remove_wait_queue(&chip->wq, &wait); 474. if(signal_pending(current)) 475. return -EINTR;

476. goto again;

477. }

478.

479. addr += chip->start;

480. chip->state = FL_READY;

481. map_copy_from(map, buf, addr, len); 482. wake_up(&chip->wq);

483. spin_unlock(chip->mutex); 484. return 0;

485. }

486.

487. static int dummy_flash_read(struct mtd_info *mtd, loff_t from, 488. size_t len,size_t *retlen, u_char *buf)

489. {

490. struct map_info *map = mtd->priv;

491. struct dummy_private_info_struct *priv = map->fldrv_priv; 492. int chipnum = 0;

493. int ret = 0;

494. unsigned int ofs; 495. *retlen = 0; 496.

497. /* Find the chip number and offset for the first chip */ 498. chipnum = (from >> priv->chipshift);

499. ofs = from & ((1 << priv->chipshift) - 1); 500. while(len)

501. {

502. unsigned long to_read;

503. if(chipnum >= priv->number_of_chips) 504. break;

505.

506. /* Check whether the read spills over to the next chip */ 507. if( (len + ofs - 1) >> priv->chipshift)

508. to_read = (1 << priv->chipshift) - ofs; 509. else

510. to_read = len;

511. if( (ret = dummy_flash_read_one_chip(map, &priv->chips[chipnum], 512. ofs, to_read, buf)))

513. break;

Chip flash đầu tiên là ánh xạ tại địa chỉ 0xBFC00000 và có kích thước 4 MB.

Flash đầu tiên là đèn flash khởi động và nó có hai khu vực xóa. Việc đầu tiên xóa

khu vực có tám ngành mỗi kích thước 8 K; này diện tích 64-K được sử dụng để lưu trữ

khởi động bộ tải và khởi động lên các tham số cấu hình. Thứ hai khu vực xóa

có phần có kích thước 64 K và hoàn toàn được sử dụng để lưu trữ một hệ thống tập tin JFFS2.

Chip flash thứ hai là ánh xạ tại địa chỉ 0xBF000000 và một lần nữa của

kích thước 4 MB. Đèn flash thứ hai gồm một khu vực xóa với tất cả các ngành

có kích thước 64 K. flash này là hoàn toàn được sử dụng để lưu trữ các tập tin hệ thống JFFS2.

Yêu cầu từ đèn flash của chúng tôi lái xe là để lập bản đồ phân vùng flash đầu tiên

bắt đầu từ địa chỉ 0xBFC00000 thành hai. Các phân vùng đầu tiên có kích thước 64 K sẽ

được phân vùng khởi động. Các phân vùng thứ hai sẽ được nối với flash bắt đầu từ địa chỉ 0xBF000000 để lưu trữ các tập tin hệ thống JFFS2. Trước tiên chúng ta hãy bắt đầu với các tập tin tiêu đề và các định nghĩa. 515. /* mtd-bsp.c */ 516. #include <linux/config.h> 517. #include <linux/module.h> 518. #include <linux/types.h> 519. #include <linux/kernel.h> 520. #include <asm/io.h> 521. #include <linux/mtd/mtd.h> 522. #include <linux/mtd/map.h> 523. #include <linux/mtd/cfi.h> 524. #include <linux/mtd/partitions.h> 525. #include <linux/mtd/concat.h> 526. 527. #define WINDOW_ADDR_0 0xBFC00000 528. #define WINDOW_SIZE_0 0x00400000 529. #define WINDOW_ADDR_1 0xBF000000 530. #define WINDOW_SIZE_1 0x00400000

531. Map_info chứa các chi tiết của địa chỉ bắt đầu từ (vật lý) của

mỗi chip, kích thước, và chiều rộng xe buýt. Đây là được sử dụng bởi những thói quen thăm dò chip.

532. static struct map_info dummy_mips_map[2] = {

533. {

534. .name = "DUMMY boot flash", 535. .phys = WINDOW_ADDR_0, 536. .size = WINDOW_SIZE_0, 537. .bankwidth = 4,

538. },

539. {

540. .name = "Dummy non boot flash", 541. .phys = WINDOW_ADDR_1, 542. .size = WINDOW_SIZE_1, 543. .bankwidth = 4,

544. }

545. };

546. Cấu trúc sau đây được dùng để thiết lập các phân vùng trên flash khởi động.

547. static struct mtd_partition boot_flash_partitions [] = {

548. { 549. .name = "BOOT", 550. .offset = 0, 551. .size = 0x00010000, 552. }, 553. { 554. .name = "JFFS2", 555. .offset = 0x00010000, 556. .size = 0x003f0000, 557. }, 558. };

559. * Sau cấu trúc giữ con trỏ mtd_info cho * Phân vùng, chúng tôi sẽ được concatenating * /

static struct mtd_info * concat_partitions [2]; / *

* Sau giữ cấu trúc cơ cấu mtd_info gợi ý cho * Mỗi của các thiết bị đèn flash

static struct mtd_info * mymtd [2], * concat_mtd;

Các init_dummy_mips_mtd_bsp chức năng () là chức năng chính. Tham khảo

4,6 đến danh mục thực hiện. Những chức năng nào sau đây.

Đầu dò cho đèn flash tại địa chỉ 0xBFC00000 và populates các MTD cơ cấu cho flash trong mymtd [0]

Đầu dò cho đèn flash tại địa chỉ 0xBF000000 và populates các MTD cơ cấu cho flash trong mymtd [1]

Tạo ra hai phân vùng cho flash với địa chỉ bắt đầu từ 0xBFC00000 Concatenates phân vùng thứ hai với đèn flash địa chỉ bắt đầu mà là 0xBF000000 và sau đó tạo ra một thiết bị mới bằng cách gọi hàm add_mtd_device ()

Cuối cùng chức năng dọn dẹp là như sau.

560. static void __exit cleanup_dummy_mips_mtd_bsp(void)

561. { 562. mtd_concat_destroy(concat_mtd); 563. del_mtd_partitions(mymtd[0]); 564. map_destroy(mymtd[0]); 565. map_destroy(mymtd[1]); 566. } 567. 568. module_init (init_dummy_mips_mtd_bsp); 569. module_exit (cleanup_dummy_mips_mtd_bsp); 570. MODULE_LICENSE ("GPL");

571. MODULE_AUTHOR ("Embedded Linux book");

572. MODULE_DESCRIPTION ("Sample Mapping driver"); 573. Listing 4.6 init_dummy_mips_mtd_bsp Function

574.

575. int __init init_dummy_mips_mtd_bsp (void)

576. {

577.

578. /* First probe for the boot flash */ 579. dummy_mips_map[0].virt = 580. (unsigned long)ioremap(

581. dummy_mips_map[0].phys,dummy_mips_map[0].size); 582. simple_map_init(&dummy_mips_map[0]);

584. if(mymtd[0])

585. mymtd[0]->owner = THIS_MODULE; 586.

587. /* Repeat for the second flash */ 588. dummy_mips_map[1].virt =

589. (unsigned long)ioremap(dummy_mips_map[1].phys, 590. dummy_mips_map[1].size);

591. simple_map_init(&dummy_mips_map[1]);

592. mymtd[1] = do_map_probe("cfi_probe", &dummy_mips_map[1]); 593. if(mymtd[1]) 594. mymtd[1]->owner = THIS_MODULE; 595. if (!mymtd[0] || !mymtd[1]) 596. return -ENXIO; 597. 598. /*

599. * Bây giờ chúng tôi sẽ phân vùng khởi động đèn flash. Chúng tôi rất quan tâm đến

* Mới mtd đối tượng cho các phân vùng thứ hai kể từ khi chúng ta sẽ được

* Concatenating nó với đèn flash khác. * /.

600. boot_flash_partitions[1].mtdp = &concat_partitions[0]; 601. add_mtd_partitions(mymtd[0], boot_flash_partitions, 2); 602.

603. /*

604. * concat_partitions[1] should contain the mtd_info pointer for the 605. * 2nd partition. Do the concatenation

606. */607. concat_partitions[1] = mymtd[1]; 607. concat_partitions[1] = mymtd[1]; 608. concat_mtd = mtd_concat_create(concat_partitions, 2, 609. "JFFS2 flash concatenate"); 610. if(concat_mtd) 611. add_mtd_device(concat_mtd); 612. return 0; 613. }

II. Thiết bị đĩa:

Đĩa thiết bị điều khiển bằng tay dành sử dụng ghi vào thiết bị Linux giống nhau từ lúc bạn làm cái gì trong mạng cục bộ hoặc máy chủ Linux.

2,1Thẻ nhớ:

Một cái thẻ nhớ thì truy cập trong Linux qua 2 đường; cái này như 1 đĩa IDE (Integrated Drive Electronics), khi chặn trong 1 CF (CompactFlash) đến IDE hoặc 1 CF đến thiết bị tiếp hợp PCMCIA (Personal Computer Memory Card

International Association) hoặc 1 đĩa SCSI (Small Computer System Interface: dùng để cắm vào CD-ROM, ổ đĩa cứng, ổ đĩa, máy quét hình, máy laser) khi truy cập mặc dù 1 USB (Universal Serial Bus) CF reader. Trong thực tế, nó thuận tiện cho việc sử dụng 1 USB reader từ thẻ chương trình CF trong máy chủ trong khi sử dụng 1 CF to IDE or CFđến thiết bị tiếp hợp PCMCIA trong đích đến thiết bị truy cập. Sau đây, CF Card có thể thấy như một đĩa SCSI trong máy chủ, nhưng gần đây đích như một đĩa IDE. Đến chủ đề phức tạp hơn nữa, gần đây Kernel phải bắt đầu truy cập đến đĩa IDE(or “PATA”) vì hệ thống phụ SCSI sử dụng libata cho nên xuất hiện IDE divers như /dev/sdx như đĩa SCSI làm.

Truy cập thẻ nhớ vì đầu đọc thẻ nhớ là một USB trong máy chủ, bạn phải hỗ trợ dành cho thiết bị lưu trữ USB. Sự phân bố tốt nhất là gửi với thiết bị hỗ trợ xây dựng USB như một đơn vị đo, và có thể tải chúng tự động. Bởi vậy, tất cả chúng ta cần làm là chặn thiết bị USB trong máy chủ của bạn.

Khi thiết bị là mặc định, bạn có thể nhìn sự thích hợp nhiều mục trong /proc đến đầu đọc thẻ nhớ của bạn. Ví dụ, như thế nào hệ thống phụ SCSI thấy đầu đọc SanDisk SDDR-31 trong máy chủ :

#cat /proc/scsi/scsi Attached Devices:

Host: scsi0 Chanel: 00 Id: 00 Lun: 00

Vendor: SanDisk Model: ImageMate II Rev: 1.30

Type: Direct-Access ANSI SCSI revision: 02

#cat /proc/scsi/usb-storage-0/0 Host scsi0: usb-storage

Product: ImageMate CompactFlash USB Serial Number: None

Protocol: Transparent SCSI Transport: Bulk

GUID: 07810002 000 000 000 000 0000 Attached: Yes

Trong trường hợp này, bởi vì đầu đọc là thiết bị đầu tiên trong SCSI Bus, nó có thể bị truy cập bằng /dev/sda. Bởi vậy, tôi có thể dành riêng, định dạng, và mang thẻ nhớ cùng một đường tôi sẽ dành riêng, định dạng và mang 1 quy ước đĩa SCSI.

# fdisk /dev/sda …

# mkdir /mnt/cf # mke2fs /dev/sda1

# mount –t ext2 /dev/sda1 /mnt/cf

Tuy nhiên gần đây Linux phân bố có thể nâng cấp một cách tự động như có thể mở được thiết bị dành cho bạn, và bằng yêu cầu nếu bạn muốn nhập ảnh từ chúng, chúng đến từ một máy ảnh kỹ thuật số. Bạn có thể ngăn chặn hành động này trong những cách bố trí GNOME và KED, hoặc những thiết bị không nâng cấp điều khiển bằng tay khi chúng xuất hiện trên màn hình nền của bạn. Nếu bạn cố gắng phân chia lại thiết bị trong khi nó nâng cấp. FDISK sẽ thông báo một lỗi:

Command (m for help): w

The partition table has been altered; Calling ioctl() to re-read partition table

WARNING: Re-reading the partition table failed with error 16: Devive or Resoure busy.

The Kernel still uses the old table.

The new table will be used at the next reboot. Syncing disks.

Bạn có thể cho vào một thẻ CF và sử dụng tùy thuộc sự phân phối khác nhau ở mức độ lớn trong mục tiêu của bạn. Nếu mục tiêu của bạn bắt nguồn từ một PC x86, bạn có thể sử dụng phân phối đơn. Nếu mục tiêu của bạn là một PPC sử dụng U-Boot bootloader, bạn cần phải có một vài phân phối nhỏ đến giữ nhân của ảnh và có một phân phối lớn đến giữ gốc tập tin hệ thống của bạn. Bởi vì U-Boot có thể đọc thiết bị phân chia CF và dữ liệu trong những ngăn khác, nhưng nó không nhận ra một vài tập tin hệ thống. Do đó, nhân của những ảnh phải được viết từ phân chia thô bởi U-Boot. Chúng ta sẽ sử dụng một vài ví dụ của thẻ CF bằng thiết bị khởi động.

III.Thiết bị hỗ trợ:( MTD: memory technology devices )

Hệ thống phụ MTD với hai thiết bị lưu trữ trạng thái rắn phổ biến nhất là sử dụng trong các hệ thống nhúng Linux: nguồn gốc CFI-compliant flash và DOC thiết bị. Sự phát triển của hệ thống phụ MTD và các công cụ MTD là độc lập của hạt nhân Mainline.

III.1 MTD Cách sử dụng cơ bản : III.1.1 Các thiết bị cần thiết cho MTD.

III.1.2 MTD tùy chọn cấu hình hạt nhân cơ bản.

III.1.3 Những công cụ có sẵn để thao tác thiết bị lưu trữ MTD trong Linux. I.1.1 Các thiết bị cần thiết cho MTD:

Bảng 7-1 mô tả từng loại MTD trên 1 thiết bị nhập cảnh và người sử dụng MTD module tương ứng

Thiết bị nhập Có thể sử dụng MTD người sử dụng mô-đun Loại thiết bị Số lượng lớn

MtdN Char thiết bị char 90

mtdblockN khối thiết bị, chỉ đọc khối thiết bị, JFFS, và JFFS2

block 31

NftlLN NFTL block 93

FtlL FTL block 44

Bảng 7-2 Cung cấp phạm vi số lượng nhỏ và mô tả các đề án đặt tên được sử dụng cho từng loại thiết bị.

Thiết bị nhập Số trẻ vị thành niên phạm vi Biểu đồ tên

mtdN 0-32 cho mỗi số tăng của 2 N =định thức con / 2 mtdrN 1-33 cho mỗi số tăng của 2 N = (định thức con - 1) / 2 mtdblockN 0-16 cho mỗi số tăng của 1 N = định thức con

nftlLN 0-255 cho mỗi bộ 16 L = set;

[2] N = định thức con - (tập - 1) x 16;

N là không nối vào tên nhập cảnh nếu giá trị của nó là số không.

ftlLN 0-255 cho mỗi bộ 16 Tương tự như NFTL.

Việc sử dụng của từng loại MTD trên thiết bị như sau:

* mtdN: Mỗi mục là một MTD thiết bị hoặc phân vùng riêng biệt. Hãy nhớ rằng mỗi phân vùng MTD hoạt động như một thiết bị MTD riêng biệt.

* mtdrN: Mỗi mục là chỉ đọc tương đương với kết hợp các / dev / mtdN nhập cảnh. * mtdblockN: Mỗi mục là thiết bị khối tương đương với kết hợp các / dev / mtdN nhập cảnh.

* nftlLN: Mỗi tập là một thiết bị NFTL riêng biệt, và mỗi mục trong thiết lập một là một phân vùng trên thiết bị đó. Mục nhập đầu tiên trong thiết lập một là toàn bộ thiết bị. / dev / nftlb, ví dụ, NFTL thứ hai là thiết bị toàn bộ, trong khi / dev/nftlb3 là phân vùng thứ ba trên thiết bị NFTL thứ hai.

* ftlLN:Tương tự như NFTL.

- Cấu hình của hệ thống phụ MTD là một phần của trình đơn chính của các tùy chọn cấu hình hạt nhân. Các menu con MTD có chứa một danh sách các tùy chọn cấu hình mà bạn có thể chọn để xây dựng như một phần của hạt nhân, xây dựng là module riêng biệt, hoặc vô hiệu hóa hoàn toàn. Dưới đây là những lựa chọn chính bạn có thể cấu hình trong menu con MTD:

1/ Công nghệ bộ nhớ thiết bị (MTD) hỗ trợ, CONFIG_MTD

Kích hoạt tính năng tùy chọn này nếu bạn muốn bao gồm hỗ trợ hệ thống phụ lõi MTD. Nếu bạn vô hiệu hoá tuỳ chọn này, hạt nhân này sẽ không có bất kỳ hỗ trợ MTD. Khi tùy chọn này được thiết lập để được xây dựng như một mô-đun, các chức năng kết quả được tìm thấy trong các mtdcore.o gọi là mô-đun.

2/ MTD phân vùng, hỗ trợ, CONFIG_MTD_PARTITIONS

Kích hoạt tính năng tùy chọn này nếu bạn muốn có thể chia thiết bị MTD của bạn vào phân vùng riêng. Nếu bạn biên dịch dạng module này, module của tên tập tin là mtdpart.o. Lưu ý rằng phân vùng MTD không áp dụng cho các thiết bị DOC. Các thiết bị này được phân vùng bằng cách sử dụng công cụ phân vùng đĩa thông thường.

3/ Char trực tiếp thiết bị truy cập vào MTD thiết bị, CONFIG_MTD_CHAR

Đây là tùy chọn cấu hình cho thiết bị char MTD module người dùng đã được nhìn thấy như là / dev / mtdN và / dev / mtdrN. Nếu bạn cấu hình này dạng module, các module của tên tập tin là mtdchar.o.

4/ Caching truy cập thiết bị chặn để MTD thiết bị, CONFIG_MTD_BLOCK Đây là tùy chọn cấu hình cho đọc-ghi thiết bị khối MTD module người dùng đã được nhìn thấy như là / dev / mtdblockN. Nếu bạn cấu hình này dạng module, các module của tên tập tin là mtdblock.o.

5/ Chỉ đọc chặn truy cập thiết bị MTD thiết bị, CONFIG_MTD_BLOCK_RO Đây là tùy chọn cấu hình cho đọc chỉ chặn người sử dụng thiết bị đun MTD đó là nhìn thấy được sử dụng cùng một / dev mục như đọc-ghi khối thiết bị. Nếu bạn cấu hình chỉ đọc chặn người sử dụng thiết bị đun dạng module, các module của tên tập tin là mtdblock_ro.o.

6/ FTL (Flash Dịch Layer) hỗ trợ, CONFIG_FTL

Thiết lập tùy chọn này nếu bạn muốn bao gồm các phân hệ người dùng FTL trong kernel của bạn. Khi cấu hình dạng module, các module của tên tập tin là ftl.o. Module FTL người dùng có thể truy cập thông qua / dev / ftlLN mục thiết bị. 7/ NFTL (NAND Flash Dịch Layer) hỗ trợ, CONFIG_NFTL

Thiết lập tùy chọn này nếu bạn muốn bao gồm các phân hệ người dùng NFTL trong kernel của bạn. Khi cấu hình dạng module, các module của tên tập tin là nftl.o. Module NFTL người dùng có thể truy cập thông qua / dev / nftlLN mục

Một phần của tài liệu THUYẾT TRÌNH LƯU CHỮ DỮ LIỆU.DOC (Trang 25 -25 )