Чтение блока physical format information dvd-r/-rw диска☛Технология DVD ✎ |
Для чтения блока Physical Format Information из Lead-In области диска поле Format должно содержать значение 0x10 (см.
таблицу 310 «Format code definitions for READ DVD STRUCTURE command» спецификации INF-8090i [2]), поле Address не
используется. Если команда выполнена успешно, устройство выдает заголовок пакета данных размером 4 байта, и пакет
данных Layer Descriptor следующего формата
Поле Layer Descriptor можно описать при помощи следующей структуры:
typedef struct {
__u8 part_version :4;
__u8 book_type :4;
__u8 max_rate :4;
__u8 disk_size :4;
__u8 layer_type :4;
__u8 track_path :1;
__u8 num_of_layers :2;
__u8 rez1 :1;
__u8 track_dnst :4;
__u8 linear_dnst :4;
__u32 start_psn_da;
__u32 end_psn_da;
__u32 end_sect_L0;
__u8 rez2 :7;
__u8 BCA :1;
} __attribute__ ((packed)) layer_descr_t;
В поле Data Area Allocation (байты 5-15) содержатся номера физических секторов начала и окончания области данных
DVD-диска (Data Area). Содержание поля Medium Unique Data зависит от типа DVD-диска: для дисков типа DVD-R/-RW
for General Ver.2.0 в этом поле находится физический адрес зоны Extra Border Zone – значение 02FE10h, и значение
2FFA0h – координаты блока Physical format information из Extra Border Zone (см. табл.22 спецификации INF-8090i [2]).
Если поле Format содержит значение 0x00, то с диска будет прочитан блок Physical Format Information из последней
Border-in области. В этом случае в поле Medium Unique Data будет находиться адрес текущей Border-out области (по
смещению 32 байта от начала Layer Descriptor), и адрес следующей Border-in области (см. табл.21 спецификации INF-
8090i [2]).
Рассмотрим функцию, выполняющую чтение блока Physical Format Information. Входные параметры функции – значение
поля Format, которое определяет, из какой области будет считываться блок. Работоспособность всех программ была
проверена для ОС Linux, ядро 2.4.31, использовались следующие модели приводов:
- ASUS DRW-1604P 1.09.
- _NEC DVD-RW ND-3520A.
int read_PFI(__u8 ffield)
{
__u8 read_dvd_struct_cmd[12];
__u16 alloc_size = 2052; // размер запрашиваемых данных (4 байта заголовка + 2048 байт данных)
__u8 buff[2052]; // буфер для пакета данных
__u32 Start_DA = 0, End_DA = 0; // начало и конец области данных диска
__u32 u_part = 0; // значение из поля Medium Unique Data
layer_descr_t *ldesc = (void *)(buff + 4); // указатель на начало Layer Descriptor
memset(buff, 0, 2052);
memset(read_dvd_struct_cmd, 0, 12);
/* Формируем командный пакет */
read_dvd_struct_cmd[0] = 0xAD; // код команды
read_dvd_struct_cmd[7] = ffield; // значение поля Format field
/* Размер запрашиваемых у устройства данных */
read_dvd_struct_cmd[8] = *((__u8 *)&alloc_size + 1);
read_dvd_struct_cmd[9] = *((__u8 *)&alloc_size);
/* Посылаем устройству команду при помощи SCSI Generic драйвера.
* Порядок работы с ним рассмотрен в [6]
*/
test_unit_ready();
if(send_cmd(read_dvd_struct_cmd, 12, SG_DXFER_FROM_DEV, \
buff, 2052, 20) <0) return -1;
/* Отображаем полученные результаты */
printf("\nFormat field: 0x%X\n", ffield);
printf("Book type: 0x%.2X\n", ldesc->book_type);
printf("Disk size: %d\n", ldesc->disk_size);
/* Стартовые и конечные адреса области данных */
Start_DA = __swab32(ldesc->start_psn_da);
End_DA = __swab32(ldesc->end_psn_da);
printf("Starting PSN of Data Area: 0x%X (%u)\n", Start_DA, Start_DA);
printf("End PSN of Data Area: 0x%X (%u)\n", End_DA, End_DA);
/* Считываем значение из поля Medium Unique Data, находящееся по смещению 32 байта
* от начала Layer Descriptor. Если Format = 0x10, то будет считано значение 02FE10h,
* если Format = 0x00 - стартовый адрес текущей Border-out области
*/
memcpy((void *)&u_part, buff + 4 + 32, 4);
u_part = __swab32(u_part);
if(ffield == 0) printf("Start PSN of Current Border-out: ");
printf("%Xh (%u)\n", u_part, u_part);
/* Считываем значение из поля Medium Unique Data, находящееся по смещению 36 байта
* от начала пакета данных. Если Format = 0x10, то будет считано значение 2FFA0h,
* если Format = 0x00 - стартовый адрес следующей Border-in области
*/
u_part = 0;
memcpy((void *)&u_part, buff + 4 + 36, 4);
u_part = __swab32(u_part);
if(ffield == 0) printf("Start PSN of the next Border-in: ");
printf("%Xh (%u)\n", u_part, u_part);
return 0;
}
Полный текст программы чтения блока Physical Format Information находится в файле
SOURCE/DVD/READ_DVD_STRUCT/read_PFI.c.
Устанавливаем в привод чистый DVD-RW диск и запускаем программу на выполнение. Проанализируем результаты
работы программы. Вначале программа считывает данные PFI из Lead-In области. Результаты чтения:
Format field: 0x10
Book type: 0x03
Disk size: 0
Starting PSN of Data Area: 0x30000 (196608)
End PSN of Data Area: 0x26127F (2495103)
2FE10h (196112)
2FFA0h (196512)
Теперь PFI из последней Border-In:
Format field: 0x0
Book type: 0x03
Disk size: 0
Starting PSN of Data Area: 0x30000 (196608)
End PSN of Data Area: 0x0 (0)
Start PSN of Current Border-out: 0h (0)
Start PSN of the next Border-in: 0h (0)
Итак, результаты работы программы показали, что в приводе находится DVD-RW диск диаметром 120 мм, содержащий
один информационный слой. Емкость диска составляет 2298496 секторов, или 4 707 319 808 байт. Стартовые адреса
Border областей равны нулю, т.к. на диск ничего не записано.
Для следующего эксперимента нам понадобится DVD-диск, записанный в режиме Incremental. Для создания такого диска
можно воспользоваться утилитой iso2dvd_multi, текст которой находится в файле
SOURCE/DVD/WRITE/MULTI/iso2dvd_multi.c. Следует учесть один момент – для записи DVD-RW диска в режиме
Incremental необходимо предварительно выполнить его ПОЛНУЮ очистку. Эта операция достаточно длительная и
занимает ~30 минут.
Записываем на DVD-RW диск в режиме Incremental один трек размером 13 631 488 байт (6656 секторов), и смотрим на
результаты работы функции read_PFI при Format Field = 0x00:
Format field: 0x0
Book type: 0x03
Disk size: 0
Starting PSN of Data Area: 0x30000 (196608)
End PSN of Data Area: 0x319FF (203263)
Start PSN of Current Border-out: 3FF00h (261888)
Start PSN of the next Border-in: 0h (0)
Физический адрес последнего записанного сектора в области данных 203263. Всего в области данных записано 6656
секторов (203263 – 196608 + 1, отсчет секторов ведется с 0), и это соответствует размеру трека. Обратим внимание на
значение стартового сектора текущей Border-out области – 3FF00h, что в пересчете на логические сектора составляет
65280. В итоге мы потеряли 65280 – 6655 = 58625 секторов, или 120 Мбайт дискового пространства.
Теперь установим в привод DVD-RW диск, на который в режиме Incremental записан трек размером 1 417 376 Кбайт, или
708688 секторов. Результат работы функции при Format = 0x00:
Format field: 0x0
Book type: 0x03
Disk size: 0
Starting PSN of Data Area: 0x30000 (196608)
End PSN of Data Area: 0xDD04F (905295)
Start PSN of Current Border-out: DD060h (905312)
Start PSN of the next Border-in: 0h (0)
В этом случае потери на соединение составили всего 17 секторов.
таблицу 310 «Format code definitions for READ DVD STRUCTURE command» спецификации INF-8090i [2]), поле Address не
используется. Если команда выполнена успешно, устройство выдает заголовок пакета данных размером 4 байта, и пакет
данных Layer Descriptor следующего формата
Поле Layer Descriptor можно описать при помощи следующей структуры:
typedef struct {
__u8 part_version :4;
__u8 book_type :4;
__u8 max_rate :4;
__u8 disk_size :4;
__u8 layer_type :4;
__u8 track_path :1;
__u8 num_of_layers :2;
__u8 rez1 :1;
__u8 track_dnst :4;
__u8 linear_dnst :4;
__u32 start_psn_da;
__u32 end_psn_da;
__u32 end_sect_L0;
__u8 rez2 :7;
__u8 BCA :1;
} __attribute__ ((packed)) layer_descr_t;
В поле Data Area Allocation (байты 5-15) содержатся номера физических секторов начала и окончания области данных
DVD-диска (Data Area). Содержание поля Medium Unique Data зависит от типа DVD-диска: для дисков типа DVD-R/-RW
for General Ver.2.0 в этом поле находится физический адрес зоны Extra Border Zone – значение 02FE10h, и значение
2FFA0h – координаты блока Physical format information из Extra Border Zone (см. табл.22 спецификации INF-8090i [2]).
Если поле Format содержит значение 0x00, то с диска будет прочитан блок Physical Format Information из последней
Border-in области. В этом случае в поле Medium Unique Data будет находиться адрес текущей Border-out области (по
смещению 32 байта от начала Layer Descriptor), и адрес следующей Border-in области (см. табл.21 спецификации INF-
8090i [2]).
Рассмотрим функцию, выполняющую чтение блока Physical Format Information. Входные параметры функции – значение
поля Format, которое определяет, из какой области будет считываться блок. Работоспособность всех программ была
проверена для ОС Linux, ядро 2.4.31, использовались следующие модели приводов:
- ASUS DRW-1604P 1.09.
- _NEC DVD-RW ND-3520A.
int read_PFI(__u8 ffield)
{
__u8 read_dvd_struct_cmd[12];
__u16 alloc_size = 2052; // размер запрашиваемых данных (4 байта заголовка + 2048 байт данных)
__u8 buff[2052]; // буфер для пакета данных
__u32 Start_DA = 0, End_DA = 0; // начало и конец области данных диска
__u32 u_part = 0; // значение из поля Medium Unique Data
layer_descr_t *ldesc = (void *)(buff + 4); // указатель на начало Layer Descriptor
memset(buff, 0, 2052);
memset(read_dvd_struct_cmd, 0, 12);
/* Формируем командный пакет */
read_dvd_struct_cmd[0] = 0xAD; // код команды
read_dvd_struct_cmd[7] = ffield; // значение поля Format field
/* Размер запрашиваемых у устройства данных */
read_dvd_struct_cmd[8] = *((__u8 *)&alloc_size + 1);
read_dvd_struct_cmd[9] = *((__u8 *)&alloc_size);
/* Посылаем устройству команду при помощи SCSI Generic драйвера.
* Порядок работы с ним рассмотрен в [6]
*/
test_unit_ready();
if(send_cmd(read_dvd_struct_cmd, 12, SG_DXFER_FROM_DEV, \
buff, 2052, 20) <0) return -1;
/* Отображаем полученные результаты */
printf("\nFormat field: 0x%X\n", ffield);
printf("Book type: 0x%.2X\n", ldesc->book_type);
printf("Disk size: %d\n", ldesc->disk_size);
/* Стартовые и конечные адреса области данных */
Start_DA = __swab32(ldesc->start_psn_da);
End_DA = __swab32(ldesc->end_psn_da);
printf("Starting PSN of Data Area: 0x%X (%u)\n", Start_DA, Start_DA);
printf("End PSN of Data Area: 0x%X (%u)\n", End_DA, End_DA);
/* Считываем значение из поля Medium Unique Data, находящееся по смещению 32 байта
* от начала Layer Descriptor. Если Format = 0x10, то будет считано значение 02FE10h,
* если Format = 0x00 - стартовый адрес текущей Border-out области
*/
memcpy((void *)&u_part, buff + 4 + 32, 4);
u_part = __swab32(u_part);
if(ffield == 0) printf("Start PSN of Current Border-out: ");
printf("%Xh (%u)\n", u_part, u_part);
/* Считываем значение из поля Medium Unique Data, находящееся по смещению 36 байта
* от начала пакета данных. Если Format = 0x10, то будет считано значение 2FFA0h,
* если Format = 0x00 - стартовый адрес следующей Border-in области
*/
u_part = 0;
memcpy((void *)&u_part, buff + 4 + 36, 4);
u_part = __swab32(u_part);
if(ffield == 0) printf("Start PSN of the next Border-in: ");
printf("%Xh (%u)\n", u_part, u_part);
return 0;
}
Полный текст программы чтения блока Physical Format Information находится в файле
SOURCE/DVD/READ_DVD_STRUCT/read_PFI.c.
Устанавливаем в привод чистый DVD-RW диск и запускаем программу на выполнение. Проанализируем результаты
работы программы. Вначале программа считывает данные PFI из Lead-In области. Результаты чтения:
Format field: 0x10
Book type: 0x03
Disk size: 0
Starting PSN of Data Area: 0x30000 (196608)
End PSN of Data Area: 0x26127F (2495103)
2FE10h (196112)
2FFA0h (196512)
Теперь PFI из последней Border-In:
Format field: 0x0
Book type: 0x03
Disk size: 0
Starting PSN of Data Area: 0x30000 (196608)
End PSN of Data Area: 0x0 (0)
Start PSN of Current Border-out: 0h (0)
Start PSN of the next Border-in: 0h (0)
Итак, результаты работы программы показали, что в приводе находится DVD-RW диск диаметром 120 мм, содержащий
один информационный слой. Емкость диска составляет 2298496 секторов, или 4 707 319 808 байт. Стартовые адреса
Border областей равны нулю, т.к. на диск ничего не записано.
Для следующего эксперимента нам понадобится DVD-диск, записанный в режиме Incremental. Для создания такого диска
можно воспользоваться утилитой iso2dvd_multi, текст которой находится в файле
SOURCE/DVD/WRITE/MULTI/iso2dvd_multi.c. Следует учесть один момент – для записи DVD-RW диска в режиме
Incremental необходимо предварительно выполнить его ПОЛНУЮ очистку. Эта операция достаточно длительная и
занимает ~30 минут.
Записываем на DVD-RW диск в режиме Incremental один трек размером 13 631 488 байт (6656 секторов), и смотрим на
результаты работы функции read_PFI при Format Field = 0x00:
Format field: 0x0
Book type: 0x03
Disk size: 0
Starting PSN of Data Area: 0x30000 (196608)
End PSN of Data Area: 0x319FF (203263)
Start PSN of Current Border-out: 3FF00h (261888)
Start PSN of the next Border-in: 0h (0)
Физический адрес последнего записанного сектора в области данных 203263. Всего в области данных записано 6656
секторов (203263 – 196608 + 1, отсчет секторов ведется с 0), и это соответствует размеру трека. Обратим внимание на
значение стартового сектора текущей Border-out области – 3FF00h, что в пересчете на логические сектора составляет
65280. В итоге мы потеряли 65280 – 6655 = 58625 секторов, или 120 Мбайт дискового пространства.
Теперь установим в привод DVD-RW диск, на который в режиме Incremental записан трек размером 1 417 376 Кбайт, или
708688 секторов. Результат работы функции при Format = 0x00:
Format field: 0x0
Book type: 0x03
Disk size: 0
Starting PSN of Data Area: 0x30000 (196608)
End PSN of Data Area: 0xDD04F (905295)
Start PSN of Current Border-out: DD060h (905312)
Start PSN of the next Border-in: 0h (0)
В этом случае потери на соединение составили всего 17 секторов.
Еще материалы по теме:
- Dvd-r- С 1 по 3 марта в немецком городе Нюрнберге прошла ежегодная выставка-конференция embedded world 2011
- Формат физического сектора dvd-диска
- Одним из признаков развитого рынка является существенная дифференциация продуктов
- Основы устройства dvd
