четверг, 5 ноября 2009 г.

Компиляция модуля ядра

Понадобилось перекомпилить ОДИН модуль ядра.
Заходим в каталог с модулем, правим исходники и затем:

make -C /usr/src/linux-`uname -r` SUBDIRS=$PWD modules

Правда потом надо было еще вручную подбросить их в соответствующий каталог в /lib/....

Про то как заставить работать Orient HW-504 http://novotorg.net/video-linux/13-orienthw-504
Целиком утащил с сайта автора - не для того что бы обидеть, а что бы было всегда под рукой.
===========================================================================================
Устанавливаю ее в компьютер и вижу, что моя система (Debian Etch 4.0) её увидела, но не опознала. Вернее опознала как четыре UNKNOWN/GENERIC карты с кодеками SAA7130 от Philips (хотя во всех обзорах и прайсах писали о BT878A) и предложила мне выбрать модель карты из списка, в котором ничего похожего на Orient HW-504 я не обнаружил. Ну что ж, отчаиваться рано. Несколько дней проведённых в Google привел меня к мысли, что надо самому пробовать осуществить поддержку моей карты модулем SAA7134. Собственно эта статья о том, как это сделать. Для нормальной работы карты необходимо правильно инициализировать её регистры. Выяснить параметры инициализации можно с помощью программы flytest.Работает она под Windows, как и софт, который идет в комплекте с картой. И так. Устанавливаем карту в компьютер, загружаем Windows, инсталлируем драйвера и софт. Перед рестартом системы надо удалить запуск программы DVR из автозагрузки. Рестарт. Запускаем программу flytest, я использовал версию 1.5, далее надо выбрать чип из выпадающего списка и нажать кнопку “Dump SAA713x PCI registers” из полученной информации нам потребуется следующее:

SAA7130 (0x7130, SubVenID:1131, SubDevID:0000, Rev: 01)

I2C slave devices found:
No devices

GPIO pins:
Mode: 0x00389200
Value: 0x00010000

Video input: 3
Audio input: Analog Line1

Далее необходимо проделать тоже самое для остальных чипов платы. Получится следующее:

SAA7130 (0x7130, SubVenID:1131, SubDevID:0000, Rev: 01)

I2C slave devices found:
No devices

GPIO pins:
Mode : 0x00389200
Value: 0x0001FC00

Video input: 3
Audio input: Analog Line1

Для второго чипа

SAA7130 (0x7130, SubVenID:1131, SubDevID:0000, Rev: 01)

I2C slave devices found:
No devices

GPIO pins:
Mode : 0x00389200
Value: 0x00010000

Video input: 3
Audio input: Analog Line1

Для третьего чипа

SAA7130 (0x7130, SubVenID:1131, SubDevID:0000, Rev: 01)

I2C slave devices found:
No devices

GPIO pins:
Mode : 0x00389200
Value: 0x00010000

Video input: 3
Audio input: Analog Line1

Для четвертого чипа.
Следующий шаг - это запуск родного софта, для того чтобы инициализировать плату, и повторение выше описанной процедуры, для получения параметров инициализации. Должно получиться следующее:

SAA7130 (0x7130, SubVenID:1131, SubDevID:0000, Rev: 01)

I2C slave devices found:
No devices

GPIO pins:
Mode : 0x00389C00
Value: 0x00016C00

Video input: 3
Audio input: Analog Line1

Для первого чипа

SAA7130 (0x7130, SubVenID:1131, SubDevID:0000, Rev: 01)

I2C slave devices found:
No devices

GPIO pins:
Mode : 0x00389200
Value: 0x00010000

Video input: 3
Audio input: Analog Line1

Для второго чипа

SAA7130 (0x7130, SubVenID:1131, SubDevID:0000, Rev: 01)

I2C slave devices found:
No devices

GPIO pins:
Mode : 0x00389200
Value: 0x00010000

Video input: 3
Audio input: Analog Line1

Для третьего чипа

SAA7130 (0x7130, SubVenID:1131, SubDevID:0000, Rev: 01)

I2C slave devices found:
No devices

GPIO pins:
Mode : 0x00389200
Value: 0x00010000

Video input: 3
Audio input: Analog Line1

Для четвертого чипа.
Это вся информация, которую можно получить в Windows для удачной правки модуля SAA7134. Все дальнейшие действия надо проводить в Linux, я использую Debian Etch 4.0. Для получения дополнительной информации надо выполнить команду lspci –vn (утилита v4l-info входит в состав пакета xawtv).
Интерес для нас представляет только та часть лога команды, где фигурирует Subsystem: 1131:0000 (Subsystem = SubVenID & SubDevID, которые берем из лога программы flytest).
Вот часть лога, интересная для нас:

02:0c.0 0480: 1131:7130 (rev 01)
Subsystem: 1131:0000
Flags: bus master, medium devsel, latency 64, IRQ 201
Memory at fe9ff000 (32-bit, non-prefetchable) [size=1K]
Capabilities: [40] Power Management version 1

02:0d.0 0480: 1131:7130 (rev 01)
Subsystem: 1131:0000
Flags: bus master, medium devsel, latency 64, IRQ 185
Memory at fe9ff400 (32-bit, non-prefetchable) [size=1K]
Capabilities: [40] Power Management version 1

02:0e.0 0480: 1131:7130 (rev 01)
Subsystem: 1131:0000
Flags: bus master, medium devsel, latency 64, IRQ 177
Memory at fe9ff800 (32-bit, non-prefetchable) [size=1K]
Capabilities: [40] Power Management version 1

02:0f.0 0480: 1131:7130 (rev 01)
Subsystem: 1131:0000
Flags: bus master, medium devsel, latency 64, IRQ 169
Memory at fe9ffc00 (32-bit, non-prefetchable) [size=1K]
Capabilities: [40] Power Management version 1

Поля первой строки имеют следующие значения:

PCI ID DeviceClass Vendor ID Device ID
02:0c.0 0480 1131 7130

Ну вот, теперь у нас имеются все необходимые данные, пора ковырять модуль SAA7134. Сначала надо установить исходные тексты ядра, запускаем aptitude и устанавливаем пакет linux-source-2.6.18 со всеми зависимостями. После этого в каталоге /usr/src/ появится архив с исходными текстами, распакуем их в каталог /usr/src/linux-source-2.6.18/. Я пользуюсь Midnight Commander’ом, поэтому не привожу здесь консольные команды. Переходим в каталог /usr/src/linux-source-2.6.18/drivers/media/video/ и на всякий случай делаем копию каталога ./saa7134/ в ./saa7134_orig/. Дальнейшие действия делаем в «родном» каталоге ./saa7134/.
Открываем для редактирования файл saa7134.h, находим там список карт, из которого нам в самом начале предлагалось выбрать кару. В самый конец добавляем нашу карту, назовем ее SAA7134_BOARD_ORIENT_HW_504 и присваиваем ей следующий номер 96:

#define SAA7134_BOARD_AVERMEDIA_A169_B1 92
#define SAA7134_BOARD_MD7134_BRIDGE_2 93
#define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94
#define SAA7134_BOARD_FLYVIDEO3000_NTSC 95
#define SAA7134_BOARD_ORIENT_HW_504 96

#define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8

/* ----------------------------------------------------------- */

Сохраняемся, закрываем файл.
Открываем для редактирования файл saa7134-input.c, находим там вот такой участок кода и добавляем нашу карту:

/* detect & configure */
switch (dev->board) {
case SAA7134_BOARD_FLYVIDEO2000:
case SAA7134_BOARD_FLYVIDEO3000:
case SAA7134_BOARD_ORIENT_HW_504:
case SAA7134_BOARD_FLYTVPLATINUM_FM:
case SAA7134_BOARD_FLYTVPLATINUM_MINI2:
ir_codes = ir_codes_flyvideo;
mask_keycode = 0xEC00000;
mask_keydown = 0x0040000;
break;

Больше в этом файле ничего писать не надо, т.к. пульта ДУ у карты нет. Сохраняемся, закрываем файл.
Открываем для редактирования файл saa7134-cards.c, находим там вот такой участок кода и добавляем описание нашей карты:

.radio = {
.name = name_radio,
.amux = LINE2,
.gpio = 0x2000,
},
.mute = {
.name = name_mute,
.amux = TV,
.gpio = 0x8000,
},
},
[SAA7134_BOARD_ORIENT_HW_504] = {
/* Orient HW-504 (Возможно Orient HW-508 и Hawell HW-404M7) */
/* Богословский Виктор E-mail: Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript */
.name = "Orient HW-504",
.audio_clock = 0x00200000,
.tuner_type = UNSET,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,

.gpiomask = 0x01fc00,
.inputs = {{
.name = name_comp1, /* название входа */
.vmux = 3, /* номер канала видео микшера */
.amux = LINE1, /* название канала аудио микшера */
.gpio = 0x389c00, /* битовая маска GPIO */
}
}},[ [SAA7134_BOARD_FLYVIDEO2000] = {
/* "TC Wan" < Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript > */
.name = "LifeView/Typhoon FlyVIDEO2000",
.audio_clock = 0x00200000,
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,

Думаю, будет уместно рассмотреть здесь поля структуры SAA7134_BOARD_ORIENT_HW_504

* .name – имя карты, которое будет присвоено ей после определения модулем, пишем "Orient HW-504"
* .audio_clock - аудио частота (как правило, 2 варианта 0x00200000 или 0x00187de7) и хотя аудио наша плата не поддерживает, я написал 0x00200000
* .tuner_type – тип TV тюнера у нас, его нет, пишем UNSET
* .radio_type – тип радио, и его у нас нет, пишем UNSET
* .tuner_addr – адрес TV тюнера, пишем ADDR_UNSET
* .radio_ addr – адрес радио, пишем ADDR_UNSET
* .gpiomask – битовая маска GPIO оказывает самое важное влияет на работу платы в целом. Значение маски GPIO можно получить путем побитового сложения всех его значений (берем все значения GPIO Value из программы flytest), т.е. 0x00010000 | 0x0001FC00 | 0x00016C00 = 0x01fc00, пишем 0x01fc00
* .name – название входа, пишем name_comp1
* .vmux – номер канала видео микшера, смотрим лог программы flytest - Video input: 3, пишем 3
* .amux – название канала аудио микшера, пишем LINE1 (flytest – Audio input: Analog Line1), думаю можно вообще не описывать этот параметр, т.к. аудио наша плата не поддерживает
* .gpio – Возможно надо формировать так же, как gpiomask , я полностью не разобрался и просто взял значение из первого чипа, после инициализации (flytest – GPIO Mode: 0x00389C00), тем более результат будет таким же, пишем 0x389c00

Далее в этом же файле ищем вот такой участок кода и добавляем описание нашей карты, как устройства в целом, для того, чтобы модуль смог сам опознать карту:

.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
.subvendor = 0x4e42, /* "Typhoon PCI Capture TV Card" Art.No. 50673 */
.subdevice = 0x0138,
.driver_data = SAA7134_BOARD_FLYVIDEO3000,
},{
.vendor = 0x1131,
.device = 0x7130,
.subvendor = 0x1131, .subdevice = 0x0000,
.driver_data = SAA7134_BOARD_ORIENT_HW_504,
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7130,
.subvendor = 0x5168,
.subdevice = 0x0138,
.driver_data = SAA7134_BOARD_FLYVIDEO2000,

Здесь поля структуры имеют следующие значения:

* .vendor – берем из лога команды lspci –vn Vendor ID, пишем 0x1131 (можно PCI_VENDOR_ID_PHILIPS)
* .device – берем из лога команды lspci –vn Device ID, пишем 0x7130 (можно PCI_DEVICE_ID_PHILIPS_SAA7130)
* .subvendor – берем из лога программы flytest - SubVenID, пишем 0x1131
* .subdevice – берем из лога программы flytest - SubDevID, пишем 0x0000
* .driver_data – то, как назвали карту в файле saa7134.h, пишем SAA7134_BOARD_ORIENT_HW_504

Сохраняемся, закрываем файл.
Ну вот, все необходимые исправления сделаны, пора компилировать наш новый модуль. Переходим в каталог /usr/src/linux-source-2.6.18/ и выполняем следующие команды:
make oldconfig – для сохранения текущей конфигурации и
make modules – для компиляции модулей.
Возможно, гуру поморщатся и предложат еще десяток «самых правильных» вариантов компиляции, но гуру почему-то таких статей не пишут и наверное не читают, так что все в порядке.
После завершения компиляции копируем из каталога:
/usr/src/linux-source-2.6.18/drivers/media/video/ файлы:

saa6752hs.ko,

saa7134.ko,

saa7134-alsa.ko,

saa7134-dvb.ko,

saa7134-empress.ko,

saa7134-oss.ko

в каталог: /lib/modules/2.6.18-4-686/kernel/drivers/media/video/saa7134/, предварительно сохранив оригинальные файлы. Теперь можно очистить исходные тексты, от результатов компиляции выполнив команду make clean и перезагрузить систему.
Чтобы посмотреть загрузился ли наш модуль надо выполнить команду v4l-info /dev/video0 | head -n 9 (утилита v4l-info входит в состав пакета xawtv) вот результат ее работы:

### v4l2 device info [/dev/video0] ###
general info
VIDIOC_QUERYCAP
driver : "saa7134"
card : "Orient HW-504"
bus_info : "PCI:0000:02:0c.0"
version : 0.2.14
capabilities : 0x5000015 [VIDEO_CAPTURE,VIDEO_OVERLAY,VBI_CAPTURE,READWRITE,STREAMING]

А чтобы посмотреть, как она работает надо выполнить команду:

xawtv -nodga -noxv -geometry 640x480 -c /dev/video0

воскресенье, 1 ноября 2009 г.

Программный (soft) RAID массив.

Есть два диска. Грузимся с DVD и с одним диском устанавливаем slackware как обычно.

Создаем через cfdisk или fdisk идентичные разделы, или c помощью sfdisk автоматически копируем структуру разделов первого диска /dev/sda:
sfdisk -d /dev/sda | sfdisk /dev/sdb

Затем на втором диске надо сделать тип разделов "Linux raid autodetect" c кодом 0xFD!!!

mdadm --create /dev/md0 -l 1 -n 2 /dev/sdb2 missing
мы создаем и запускаем райд с level=1 (-l 1) на двух дисках (-n 2) причем указываем только диск /dev/sdb2, а /dev/sda2 указываем отсутвующим (missing)
А когда закончим с созданием и загрузкой с райда, добавим второй диск (mdadm --add /dev/md0 /dev/sda2)

И так аналогично для всех остальных разделов райда. Проверить можно глянув в /proc/mdstat

Теперь создаем файловую систему на разделах райда
mkfs.ext4 -j /dev/md0
mkfs.ext4 -j /dev/md1
и т.д.

Создадим файлик с конфигами (хотя как говорят, смысла в этом особого нет, все и так работает)
mdadm --detail --scan > /etc/mdadm.conf
можно скопировать предварительно старый

Создадим каталог для переноса файлов на райд
mkdir /mnt/raid
и смонтируем его и прочие каталоги райда (глянте в fstab)
в моем случае все два раздела - корень и /var т.е.

mount /dev/md0 /mnt/raid
mkdir /mnt/raid/var
mount /dev/md1 /mnt/raid/var

Ну а теперь копируем (с сохранением ВСЕХ атрибутов, ключ -a) все и вся (перечень каталогов с ключиком -r) с нашей работающей системы на райд. КРОМЕ каталогов /dev /proc /sys - их система создает динамически (я их создаю руками, не забыть права 755 = dev,sys 555 = proc). Ну и с /mnt вручную перекинуть, что бы не утворить рекурсивное копирование райда в самого в себя (вряд ли получиться)

cp -ar bin home и т.д. /mnt/raid

Теперь надо на разделе с райдом (/mnt/raid/) подкрутить /etc/fstab и отредактировать его на использование для корня /dev/md0 и для /var /dev/md1

Еще один "сложный" момент загрузчик lilo
boot = /dev/md0
raid-extra-boot = /dev/sda,/dev/sdb #потом поменяем, когда полностью поднимем райд на mbr, а можем и не менять
root = /dev/md0
Что бы установить новый загрузчик придется передать ему параметр -r с новым корневым каталогом (/mnt/raid), а так же параметр -H, т.к. не оба диска включены в райд
И еще надо пробросить /dev в /mnt/raid/dev
mount /dev /mnt/raid/dev -o bind
и вот теперь
lilo -H -r /mnt/raid
лило поругается

Теперь добавим недостающие диски в райд, для этого поменяем их тип с помощью fdisk на fd, а затем
mdadm --add /dev/md0 -/dev/sda2
и так для всех остальных дисков
Можно посмотреть на процес зеркалирования в /proc/mdstat

Есть альтернативны способ с помощью raidtools http://people.redhat.com/mingo/raidtools/
В общем про установку райда все.

Теперь если случилось страшное и один из дисков "заболел"
http://meandubuntu.ru/2009/04/mdadm-%D0%B1%D0%B8%D1%82%D1%8B%D0%B9-%D0%B4%D0%B8%D1%81%D0%BA-%D0%B1%D0%B5%D0%B7-%D0%BF%D0%B0%D0%BD%D0%B8%D0%BA%D0%B8/ - это статья о том, что SMART может повлиять на монтирование софт райда и как это можно побороть. Цитата:
"Поставив пакет smartmontools, я вывел всю инфу по сбойному диску, в которой не нашел никаких отклонений. После некоторых раздумий, я запустил тест диска по команде smartctl –test=short /dev/sdb… Пришлось ждать целых 2 минут, пока закончится тестирование " После этого у автора собрался и заработал райд, а до этого падал mdadm с ошибкой "faulty spare rebuilding"

Если уж совсем все плохо с диском, то его надо пометить сбойным (он и так уже будет помечен) и отключить.
mdadm --fail /dev/md0 /dev/sdb1
mdadm --remove /dev/md0 /dev/sdb1
затем заменить диск, "разбить" его и добавить к райду
mdadm --add ........

Ну и еще такой момент: JBD: barrier-based sync failed on md1 – disabling barriers
Такое вот предупреждение выдает dmesg. Вообщем то с этим жить можно. Можно решить проблему добавив в параметры монтирования фс barrier=0. Вот здесь есть инфо (англ) http://kernelnewbies.org/Ext4