Кое-что об устройстве ядра

Взгляд изнутри

Модератор: Модераторы разделов

Аватара пользователя
Asgard
Сообщения: 215
Статус: North Valfader

Re: Кое-что об устройстве ядра

Сообщение Asgard »

А те вещи, которые я описал - я вообще нигде не встречал

в том же understending linux kernel всё это описано, другое дело что нужно ещё выловить оттуда эту информацию из кучи ненужных деталей.
sator arepo tenet opera rotas ;)
------------------------------------------------------------
LJ
Спасибо сказали:

Аватара пользователя
flook
Сообщения: 585
Статус: Просто flook

Re: Кое-что об устройстве ядра

Сообщение flook »

Asgard писал(а):
18.03.2006 12:40
А те вещи, которые я описал - я вообще нигде не встречал

в том же understending linux kernel всё это описано, другое дело что нужно ещё выловить оттуда эту информацию из кучи ненужных деталей.

:) Ну ее я не читал...
В каждом из нас спит гений... и с каждым днем все крепче...
Спасибо сказали:

Аватара пользователя
d_Sun
Сообщения: 291

Re: Кое-что об устройстве ядра

Сообщение d_Sun »

Asgard писал(а):
18.03.2006 12:19
сейчас пытаюсь асиливать Understanding Linux Kernel, но процесс, мягко говоря, идёт туго, ибо книга мегазанудная и при её чтении меня постоянно клонит в сон. честно говоря, вообще не могу понять за что её все так любят агитировать...


Ну зря вы так... Отличная книга. ИМХО - очень грамотно построена/составлена. А что на ваш взгляд в ней занудного?

З.Ы. Если б еще 3-е издание где-то найти.
Моя подпись сильно длинная :)
Спасибо сказали:

Аватара пользователя
Asgard
Сообщения: 215
Статус: North Valfader

Re: Кое-что об устройстве ядра

Сообщение Asgard »

d_Sun
как сказать... книга очень "статична". отсутствует динамический процесс. можно было засунуть туда какие-нибудь простенькие куски работающего кода, аки упражнение. уже не так плохо бы было.

p/s
а если ещё учесть тот факт, что техн. книги я читаю уже находясь на очень шаткой границе межну сном и бодрствованием....
sator arepo tenet opera rotas ;)
------------------------------------------------------------
LJ
Спасибо сказали:

silentbob
Сообщения: 5

Re: Кое-что об устройстве ядра

Сообщение silentbob »

flook
Нет, интересно конечно было почитать. Продолжение интересует. К примеру мне довольно проблематично разобраться с такими вещами, как
Драйвер звуковой и видеокарточки, что делает, собственно ? Со звуком вообще ничего не понятно. С видео - примитивный framebuffer сделать это одно, а вот связку user space + драйвер + 3D ускоритель не могу понять. Да и почитать негде. Не нашел, по крайней мере.

А еще... Может знаете где взять приличную документацию по API 2.6 ядра :ph34r: ? если она существует, конечно :)
Спасибо сказали:

Аватара пользователя
flook
Сообщения: 585
Статус: Просто flook

Re: Кое-что об устройстве ядра

Сообщение flook »

silentbob писал(а):
20.03.2006 05:32
flook
Нет, интересно конечно было почитать. Продолжение интересует. К примеру мне довольно проблематично разобраться с такими вещами, как
Драйвер звуковой и видеокарточки, что делает, собственно ? Со звуком вообще ничего не понятно. С видео - примитивный framebuffer сделать это одно, а вот связку user space + драйвер + 3D ускоритель не могу понять. Да и почитать негде. Не нашел, по крайней мере.

А еще... Может знаете где взять приличную документацию по API 2.6 ядра :ph34r: ? если она существует, конечно :)

Ну... Вообще говоря, в работе драйверов нет ничего интересного. Другое дело - "обвязка", то есть то, что ядро им предоставляет - там можно, при желании, что-то найти. А сами драйвера - это просто реализация data sheet на железку - не больше, не меньше.

Про API ядра. Это довольно размытое понятие. Есть некие общие примитивы типа операция со списками, средства синхронизации, работа со строками (об этом я след. опус делаю). Есть API для блочных устройств - там одно, есть для символьных - там другое. Сеть - вообще отдельная песня - там 90% кода это протоколы - API минимален.
В каждом из нас спит гений... и с каждым днем все крепче...
Спасибо сказали:

Аватара пользователя
flook
Сообщения: 585
Статус: Просто flook

Re: Кое-что об устройстве ядра

Сообщение flook »

Здесь я опишу то, что ядро предоставляет для любой подсистемы.

String.h

Поскольку ядро -- это автономная система, использование в ней
glibc запрещено, а поэтому все стандарные функции по работе со
строками написаеы, причем оптимизированы под конкретный камень.
strlen, memcpy, strncmp -- все это есть и работает так же как и
user-space аналоги. Интересно упомянуть об оптимизации под названием
alternative_input. Если одно и то же действие можно сделать
с разной скоростью разными инструкциями в зависимости от модели
процессора -- можно явно указать, какую инструкцию при каком
процессоре использовать. Основная и альтернативная инструкции
укладыватся друг за другом и на одну из них делается jmp.
Одно время я видел эту оптимизацию во многих местах, но потом
ее много где поубирали.

Списки и хеш таблицы
Вся работа со списками написана в include/linux/list.h.
Как они работают проще всего пояснить на примере. Итак, допустим
программист хочет подвязывать в список my_list объекты
структуры my_struct. Он делает следующее:

Код: Выделить всё

    static struct list_head my_list = LIST_HEAD_INIT(&my_list);

этим самым объявляется голова списка и инициализируется. Структура
list_head состоит из двух указателей на саму себя -- next
и prev, и LIST_HEAD_INIT инициализирует эти указатели
на голову в знак того, что в списке нет элементов. Макрос list_empty
как раз проверяет этот момент. Далее описывается структура:

Код: Выделить всё

    struct my_struct {
        ... /* fields */
        struct list_head list;
        ... /* fields */
    };

Как видим, достаточно завести два указателя внутри структуры.
Добавление и удаление из списка выглядит оченть просто:

Код: Выделить всё

    stryct my_struct *obj;
    ...
    list_add(&obj->list, &my_list);
    ...
    list_del(&obj->list);

Как видим для удаления из списка даже не надо знать из какого -- указатели
на next и prev сами указывают на те элементы, между которыми нужно
сомкнуть дырку. А теперь -- самое интересное -- как извлечь элемент из списка.

Код: Выделить всё

    struct my_struct *obj;
    struct list_head *lp;
    ...
    obj = list_entry(lp, struct my_struct, list);

Макрос list_entry устроен следующим образом. Вычисляется смещение поля
list в структуре struct my_struct и это смещение вычитается из
указателя lp. Вот вариант кода, как он выглядел в ранних версиях:

Код: Выделить всё

    #define list_entry(lp, type, mem)    \
        (type *)(((char *)lp - &(((type *)0)->mem)))


Для удобства программиста так же есть макросы прохода по списку в разных
вариантах, склеивания списков и так далее, но все они построены на описанной
идее -- вычислять элемент из struct list_head по смещению.

Про хеши два слова -- вместо struct list_head есть структуры hlist_head
и hlist_entry. В первой сидит указатель на первый элемент, а во второй --
указатель на следующий и указатель на указатель, указывающий на себя.
Хеш организуется следующим образом -- заводится массив hlist_head-ов,
и в нужную цепочку подшивается новый hlist_entry по тем же правилам, что
и в случае со списками.

Синхронизация
Синхронизация представлена в виде большого спектра примитивов. Начнем с простейших.

Атомарные переменные.

Все знают, что на SMP-системах операция inc (%eax) может привести не к тому
о чем думал программист. Именно для этого ввели специальный платформонезависимый
тип atomic_t и операции с ним -- atomic_inc, atomic_dec и так
далее. На i386 архитектуре они выполнены с помощью аппаратного префикса lock
к соответствующей инструкции. Этот префикс гарантирует эксклюзивный доступ к шине
на время операции, то есть на время чтение-операция-запись.

Защелки или spinlock

Все знают для чего они нужны, расскажу как они сделаны и о чем нужно помнить, используя
их. Устройство защелки видно из устройства (схематичного) функции spin_lock:

Код: Выделить всё

1:
    lock decl (%1); /* %1 points to lock in memory */
    js 2f
    .section LOCK_FAILED
2:
    cmp 0, (%1)
    jle 2b
    jmp 1b
    .endsection

Открытый lock содержит 1, значит если два процессора сделают decl, то один из них получит
sign бит в флаговом регистре и упрыгает в отдельную секцию ждать открытия lock.
При работе с защелками важно помнить одну простую вещь -- нельзя звать функцию schedude(),
так как защелка останется закрытой и не факт, что откроется. За это время будут
простаивать все остальные процессоры, пытаясь ее взять.

Семафоры или semaphore (в 2.6.16 ядре их заменили на mutex)

Семафор -- это тот же spinlock, но имеющий на борту список процессов, ожидающих его
открытия. При неудаче взять семафор процесс переводится в uninterruptible состояние и
зовется schedule() чтобы освободить процессор. Процессы в таком состоянии не убиваются
никаким сигналаси вообще. Таким образом отличия семафоров от lock такие: можно звать
schedule() с неотпущенным семафором и честность по отношению к процессам. Поясню -- в
случае spinlock если три процессора пытаются взять lock, то очередность прохода будет
произвольной, в случае же с семафорами -- сначала семафор достанется первому попытавшемуся,
потом второму и так далее. Функции для самостоятельной работы -- down и up,
а в новых (2.6.16 и выше) ядрах -- mutex_lock и mutex_unlock.

Защелки и семафоры на чтение

Это обычные защелки, но защелкивать их можно двумя способами -- для чтения и для записи.
Защелка, закрытая на чтение допускает защелкивание на чтение еще раз (с другого процессора).
Защелка, закрытая на запись не пропускает никого. Устроено это все так:

Код: Выделить всё

    /* read_lock - lock for reading */
    lock decl (%1)
    js 1f
    ... /* same as in lock */

    /* write_lock - lock for writing */
    lock subl 0x01000000, (%1)
    js 1f
    ... /* same as in lock */

Открытая зацелка содержит 0x01000000, что допускает ее взятие большому количеству
чтецов и всего одному писателю. Правила раблты с ними -- такие же как и в простых аналогах.

Счетчики вхождений
Эти используются в случае, когда писатель один но ему нельзя ждать ни одного тика.
Чтобы этого достичь отыгрываются на чтецах. Устроено это так:

Код: Выделить всё

    static inline void write_seqcount_begin(seqcount_t *lock)
    {
        lock->sequence++;
        smp_wmb();
    }
    static inline void write_seqcount_end(seqcount_t *lock)
    {
        smp_wmb();
        lock->sequence++;
    }
    ...
    seqcount_t lock = SEQCOUNT_ZERO;
    ...
    write_seqcount_begin(&lock);
    /* write what you want */
    write_seqcount_end(&lock);

как видим -- писатель действительно никого не ждет, а лишь увеличивает два раза счетчик.
Функция smp_wmb -- это барьер для архитектур, у которых запись в память может
менять свой порядок.
Теперь читатель:

Код: Выделить всё

    static inline int read_seqcount_begin(struct seqcount_t *lock)
    {
        int ret;
        ret = lock->sequence;
        smp_rmb();
        return ret;
    }
    static inline int read_seqcount_retry(struct seqcount_t *lock, int s)
    {
        smp_rmb();
        return (s & 1) | (lock->sequence ^ s);
    }
    ...
    int seq;
    do {
        seq = read_seqcount_begin(&lock);
        /* read data */
    } while (read_seqcount_retry(&lock, seq));

Функция read_seqcount_retry -- это оптимизированная проыверка того, что
в момент начала чтения счетчик был нечетным (писатель работал) или изменился
в процессе чтения (писатель отработал быстрее), то есть читатель повторяет
попытки чтитать данные пока не убедится в том, что в процессе чтения никто
их не попортил.

to be continued...
В каждом из нас спит гений... и с каждым днем все крепче...
Спасибо сказали:

iAm
Сообщения: 220
ОС: Gentoo

Re: Кое-что об устройстве ядра

Сообщение iAm »

Кое-что об устройстве ядра можно посмотреть еще вот здесь!
Спасибо сказали:

Аватара пользователя
Thoth
Сообщения: 432
Статус: Хорошему коту и в декабре март.
ОС: gentoo only !!!

Re: Кое-что об устройстве ядра

Сообщение Thoth »

2flook ---- пасиб ,последний пост просто класс , очень помогает. <_<
ГГГента vanilla-sources + some patchs, kde real-base only,GNU emacs
Юзаю gentoo патаму шта он рудит нипадецки, а всё астальное ацтой.
лапоть: OpenSuse-10.2
Спасибо сказали:

Аватара пользователя
AndyX
Сообщения: 116

Re: Кое-что об устройстве ядра

Сообщение AndyX »

Вот ведь, никогда низкоуровневым программированием не увлекался, а прочитал все, что называется, на одном дыхании :)
2flook: пишите еще :D
I am in shape. Round is a shape.
Спасибо сказали:

Nab
Сообщения: 257

Re: Кое-что об устройстве ядра

Сообщение Nab »

Вот ребятки, пришло в новостях, я думаю в тему картинка...
http://110mb.com/deptree/Linux_dependency_tree.png

PS: Ну вот и отмечу я седня свое 200 сообщение в этом славном форуме :)
Чтобы правильно задать вопрос, нужно знать больше половины ответа...
FREESCO in Ukraine
Спасибо сказали:

vadiml
Сообщения: 446
ОС: fc12.x86_64

Re: Кое-что об устройстве ядра

Сообщение vadiml »

Nab
[off]
Ну вот и отмечу я седня свое 200 сообщение в этом славном форуме
программисты отмечают 256-е
[off]
phenom x4 905e, asus m4a79 deluxe, 4 gb, ati x550, ati 4350, 2 x 17" LCD
Спасибо сказали:

Nab
Сообщения: 257

Re: Кое-что об устройстве ядра

Сообщение Nab »

vadiml писал(а):
03.05.2006 19:24
Nab
[off]
Ну вот и отмечу я седня свое 200 сообщение в этом славном форуме
программисты отмечают 256-е
[off]

Однозначно :), у меня к примеру на форуме ранги пользователям равны степеням 2,
На этом же форуме они кратны 10, и при 200 очках я получил ранг "Завсегдатай".
И потом, у меня вчерась еще и день варенья был, так что грех было не отметить :P

PS: ребята, если кто желает поздравить, то лучше в личку, не надо засорять этот отличный топик...
( скромный я, да? ;) )
PSS: тока заметил внизу надпись "Нашему форуму сейчас: 2 года ровно!", мы почти в один день года родились :)
Самое интересное что и моему сайту на днях год исполняется :)
Чтобы правильно задать вопрос, нужно знать больше половины ответа...
FREESCO in Ukraine
Спасибо сказали:

ward
Сообщения: 1

Re: Кое-что об устройстве ядра

Сообщение ward »

Тема класная, не спорю, но боюсь, что flook ее еще не скоро продолжит.
Спасибо сказали:

Аватара пользователя
Caesar
Сообщения: 9

Re: Кое-что об устройстве ядра

Сообщение Caesar »

serzh-z писал(а):
01.03.2006 13:12
Пожалуй, Sparky прав. Когда приходиться с этим столкнуться (например, при проблемах с vesafb довелось копать код в том место где выполняется запрос параметров из BIOS видюхи, ещё до распаковки остальной части ядра) - то возникают вопросы, и появляется необходимость в перерывании половины Сети.

Кстати, по пути и возник ещё вопрос - по ходу дела обратил внимание - на x86_64 загрузка выполняется аж в три этапа: реальный режим, защищённый 32-х разрядный, и только потом уже 64-х разрядный... Мне лично это было бы интересно почитать - чем вообще отличается процесс загрузки ядра от привычного 32-х разр.

А вообще - не было идеи писать подобные статьи, скажем на posix.ru - я думаю, что в форуме эти описания просто будут утеряны и незамечены?

В журнале Хакер была опубликована статья Криса Касперски, в котрой он разбирал переход в 64-битный режим. Вот линк на эту статью.
Scientific Linux CERN 4
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: Кое-что об устройстве ядра

Сообщение serzh-z »

Caesar писал(а):
14.06.2006 02:06
Вот линк на эту статью.
Благодарю.
Спасибо сказали:

boggard
Сообщения: 2

Re: Кое-что об устройстве ядра

Сообщение boggard »

Flook, есть сильное желание разобратся с работой драйвера vesa-tng, как говорил Черчиль "Дайте нам инструменты и мы сделаем эту работу сами", книжку уже нашел, назвается "Анализ программного кода на примере прокетов open source", а вот интсрументом еще не обзавелся, что можете посоветовать?
Спасибо сказали:

Аватара пользователя
alv
Бывший модератор
Сообщения: 7268
Статус: Пенсионер в законе
ОС: Cintu

Re: Кое-что об устройстве ядра

Сообщение alv »

Тема очень интересная даже для не программистов
И безусловно, все это обязательно нужно оформить в виде статьи - или, скорее, серии статей
Тем более, что чуть ли не единственно, что для этого (ИМХО) требуется - последовательная рубрикация
Готов оказать посильную помощь в редактировании
Спасибо сказали:

Аватара пользователя
BlackStar
Сообщения: 1338
Статус: We are all Kosh
ОС: Fedora 10

Re: Кое-что об устройстве ядра

Сообщение BlackStar »

Когда же будет продолжение? Очень хочется узнать о реализации сети в ядре. А еще внятное описание функции для работы со структурой sk_buff (я имею виду: skb_reserve, skb_put, ...).
LightLang Team
Спасибо сказали:

int_0dh
Сообщения: 20
ОС: Linux

Re: Кое-что об устройстве ядра

Сообщение int_0dh »

попытаюсь продолжить дело flook`а : )

часть 1. NETCORE

основа всего - 2 softirq :NET_RX_SOFTIRQ и NET_TX_SOFTIRQ
обработчик первого называется net_rx_action обработчик второго - net_tx_action, их исходный код находится в net/core/dev.c

ПРИЕМ ПАКЕТОВ

net_rx_action() проходит по списку устройств (poll_list, соответствующий softnet_data для данного процессора), и вызывает dev->poll, указатель который обычно указывает на process_backlog() (во всех остальных случаях используется NET POLL, и этот указатель указывает на определенную драйвером polling функцию)
net_rx_action никогда не работает дольше одного jiffies (10 мсек в стандартных ядрах на x86) и никогда не передает в стек больше чем netdev_max_backlog пакетов за один раз.

process_backlog()
получает от net_rx_action() бюджет (максимальное число пакетов для доставки)
получает приемную очередь skb из softnet_data для текущего процессора (SOFTIRQ могут выполнятся параллельно на разных процессорах. для масштабирования нагрузки существует по одной softnet_data для каждого прцессора. и так везде : ) )
и вызывает для каждой skb из очереди netif_receive_skb().
process_backlog() также не работает дольше одного jiffies и никогда не доставляет больше budget пакетов в стек за один раз.

netif_receive_skb()
у пакета выставляется skb->h.raw и skb->nh.raw
доставляет пакет PF_PACKET сокетам
вызвает bridge_handle() . если бридж активен, то пакет попадает туда и на этом выполнение функции заканчивается. (протоколам сетевого уровня пакет не достается, если бридж не отдаст его позднее)

проходит по RCU списку зарегистрированых сетевых протоколов и вызывает proto->func(), для каждого экземпляра протокола с идентификатором skb->protocol & 15 (в ранних версиях ядра 2.6 была любопытная вещь - протоколы получали пакеты в LIFO порядке. т.е если мы зарегистрируем протокол с ETH_P_IP, то мы получим пакет раньше системного IP, и если после своих грязных дел мы испортим skb, системный IP её отбросит).
после этой процедуры пакет попадает в стек, соответствующий его protocolID

c точки зрения драйвера он может доставить пакет 2 способами:
традиционным ,через netif_rx (не забыв выставить skb->dev и skb->protocol)
netif_rx ставит пакет в входную очередь skb, в соответствующей softnet_data. при этом он ведет контроль заполнености очереди и, если число пакетов превышает netdev_max_backlog, дропает пакет и возвращает NET_RX_DROP.

через NETPOLL. эта техника прекрасно описана в Documentation/networking/NAPI_HOWTO.txt
Спасибо сказали:

Аватара пользователя
BlackStar
Сообщения: 1338
Статус: We are all Kosh
ОС: Fedora 10

Re: Кое-что об устройстве ядра

Сообщение BlackStar »

Вот проблемка получается:

Регистрирую сетевое устройство ethernet типа полученое через

Код: Выделить всё

alloc_etherdev(sizeof(struct my_privatre));


Все проходит успешное, устройство работает. Но имя устройства почему то eth%d.
По чему не обрабатывается макрос %d и не подставляется реальный индекс?
LightLang Team
Спасибо сказали:

Аватара пользователя
BlackStar
Сообщения: 1338
Статус: We are all Kosh
ОС: Fedora 10

Re: Кое-что об устройстве ядра

Сообщение BlackStar »

Все решил проблемку!!! :D
Покопался в исходниках: /usr/src/linux/net/core/dev.c. Ошибка заключалась в том что я использовал register_netdevice(), а надо было register_netdev.
LightLang Team
Спасибо сказали:

Аватара пользователя
deninok
Сообщения: 585
Статус: Программист С++
ОС: Debian GNU/Linux

Re: Кое-что об устройстве ядра

Сообщение deninok »

А скажите пожалуйста, куда пропал flook? Интересные вещи писал. Единственное обсуждение, целиком посвященное ядру - и то загнулось :mellow: Жаль...
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: Кое-что об устройстве ядра

Сообщение serzh-z »

Ну ему можно написать... :-
Спасибо сказали:

gekt0r
Сообщения: 2
ОС: маздай

Re: Кое-что об устройстве ядра

Сообщение gekt0r »

Люди, а у меня нет файла entry.S :blink:
как мне заглянуть в system_call???
Спасибо сказали:

Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8255
Статус: Маньяк
ОС: Arch, CentOS, Ubuntu

Re: Кое-что об устройстве ядра

Сообщение serzh-z »

gekt0r писал(а):
12.12.2006 16:24
Люди, а у меня нет файла entry.S :blink:
как мне заглянуть в system_call???
Что бы это значило...
Спасибо сказали:

Аватара пользователя
Asgard
Сообщения: 215
Статус: North Valfader

Re: Кое-что об устройстве ядра

Сообщение Asgard »

Люди, а у меня нет файла entry.S blink.gif
как мне заглянуть в system_call???


скачайте с ftp://kernel.org нативное нормальное ядрышко. а то в какой-нибудь kernel.[rpm|deb] не потыкаешься =)
sator arepo tenet opera rotas ;)
------------------------------------------------------------
LJ
Спасибо сказали:

Аватара пользователя
halturin
Сообщения: 167
ОС: Linux

Re: Кое-что об устройстве ядра

Сообщение halturin »

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

Rocky
Сообщения: 7
ОС: Suse 10, WXP

Re: Кое-что об устройстве ядра

Сообщение Rocky »

Люди, а кто подскажет, как из модуля (из ядра) воспользоваться драйвером последовательного порта?
Как мне найтит драйвер 1-го последовательно порта (Скорее всего он один на всех, но как им правильно пользоваться).

Кратко о своей задаче =

Про написание дисциплины я понял, а вот я не хочу дисциплину, мне нужно создать группу файлов(/dev/md[00-99]). Каждый файл будет соответствовать своему устройству подключенному к последовательному(RS485 - много устройств на одной линии) порту.
Хочется, чтобы несколько программ одновременно могли получить доступ к своему устройству, незная о том, что порт один ...

П.С. Понимания Линукса мне не хватает, поэтому чтение исходников затрудненно ...

С благодарностью выслушаю ваши комментарии.
С уважением
Андрей
Спасибо сказали:

vadiml
Сообщения: 446
ОС: fc12.x86_64

Re: Кое-что об устройстве ядра

Сообщение vadiml »

вот интересная статья по начальным сведениям -- http://linuxkernel.ru/store/070416.pdf
найдено на http://www.opennet.ru/opennews/art.shtml?num=10639
phenom x4 905e, asus m4a79 deluxe, 4 gb, ati x550, ati 4350, 2 x 17" LCD
Спасибо сказали: