LINUX.ORG.RU
ФорумMobile

Портирование ядра. Написал драйвер UART как корректно его подключить.

 spmu8000, ,


4

2

Здравствуйте. Я пытаюсь портировать ядро линукс на процессор SPMP8000 (основан на arm926). Я написал свой драйвер ЮАРТ (пока сильно упрощенный вариант). Вот код драйвера:

#include <linux/console.h>
#include <linux/serial_core.h>
#include <asm/io.h>
#include <mach/serial.h>

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/termios.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
#include <linux/io.h>
#include <mach/platform.h>
#include <mach/hardware.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>




//запись символа в юарт0
static void putc(int c)
{
        int timeout=4000;

        if (UART0_STATUS1 & 0x1E) return;
        while (timeout > 0) {
                if ((UART0_STATUS2 & 0x10) && ((UART0_STATUS3 & 4) == 0)) {
                        UART0_DATA = c;
                        break;
                }
                timeout--;
        }
}

// функция printk в  ЮАРТ
static void sanoprintk(struct console *co, const char *s, u_int count){
    int i;
        /* Пишем каждый символ */
        for (i = 0; i < count; i++, s++) {
                if (*s == '\n'){
                        putc('\r');
                }
                putc(*s);
        }
}


static int __init sano_console_setup(struct console *co, char *options)
{
        return 0;
}


/* Заполняем структуру консоли */

static struct console sano_uart_console = {
            .name   = "ttyS",                /* Имя консоли */
            .write  = sanoprintk, /* Как делать printk в консоли */
//          .device = uart_console_device,    /* Предоставлена ядром serial */
            .setup  = sano_console_setup,
            .flags  = CON_PRINTBUFFER,        /* Флаг по умолчанию */
            .index  = -1,                     /* Инициализация в неправильное значение */
};
//register_console(&sano_uart_console);


/* Инициализация консоли */

static int __init sano_uart_console_init(void)
{
/* Регистрация этой консоли */
register_console(&sano_uart_console);
return 0;
}

console_initcall(sano_uart_console_init); /* Метка инициализации консоли */

В Makefile arch части добавил obj-y += serial.o, ядро собирается и драйвер в его добавляется, но вывод сообщений в ЮАРТ не происходит.

Однако если я в файде /init/main.c добавляю свою функцию sanoprintk , а так же заполняю и инициализирую структуру static struct console sano_uart_console прямо в начале функции start_kernel, то вывод в юарт работает так как надо. Выглядит это примерно так

#ifdef STANDALONE_DEBUG
#define putstr printf
#else

static void sanoprintk(struct console *co, const char *s, u_int count);

#include <mach/uncompress.h>
#endif

static void sanoprintk(struct console *co, const char *s, u_int count){
    int i;
        /* Пишем каждый символ */
        for (i = 0; i < count; i++, s++) {
                if (*s == '\n'){
                        putc('\r');
                }
                putc(*s);
        }
}

asmlinkage void __init start_kernel(void)
{
/* Параметры каждого из поддерживаемых портов USB_UART */
        /* Заполняем структуру консоли */

static struct console sano_uart_console = {
          .name   = "ttyS",                /* Имя консоли */
          .write  = sanoprintk, /* Как делать printk в консоли */
          .flags  = CON_PRINTBUFFER,        /* Флаг по умолчанию */
          .index  = -1,                     /* Инициализация в неправильное значение */
};
register_console(&sano_uart_console);

Однако, это крайне не верное решение. Подскажите пожалуйста как подключить драйвер вынесенный в отдельный файл arch части ядра.

Ну, это. Открываешь исходник любого tty драйвера и копипастишь (например, drivers/tty/serial/msm_serial_hs)

Добавляешь в Kconfig секцию для драйвера (там зависимости выставляются) В Makefile пишешь типа obj-$(CONFIG_TTY_FOOBAR) += tty_foobar.o

В cmdline ядра дописываешь console=ttyS0

По поводу register_console и всего такого. Вызывай это из кода драйвера, если он как platform_device, или из кода борды.

Вообще, можешь сделать функцию с сигнатурой «int __init my_func(void)», и из нее вызывать нужный код. А потом в файле с функцией пишешь, например, subsys_initcall(my_func) или device_initcall(my_func) - и после инициализации подсистем функция вызовется. Для уарта можно совсем рано сделать - в map_io или fixup архитектуры.

alexst
()
Ответ на: комментарий от alexst

спасибо за сообщение, но я впервые работаю над портом и мне не все понятно можете пояснить следующие моменты:

Добавляешь в Kconfig секцию для драйвера (там зависимости выставляются)

- вот этот момент не как не могу понять. Вообще не понимаю структуру файлов Kconfig и в гугле тоже не могу найти. Например в интернете часто встречается такое: «В файл Kconfig добавляем следующие строки: config MY_UART select SERIAL_CORE help Test UART driver Затем в Makefile добавляем следующую строку: obj-$(CONFIG_MY_UART)+= my_uart.o » я верно понимаю что CONFIG_MY_UART в строке означает, что файл компилируется только если в конфиге ядра будет стоять CONFIG_MY_UART=y или тут дело совсем не в этом? А в Kconfig нужно задавать название секции просто убрав CONFIG_ от CONFIG_MY_UART?

В cmdline ядра дописываешь console=ttyS0

это я прописал, но на данный момент хотел бы вообще игнорировать значения из этой строки и всегда отправлять сообщения в UART0. Я конечно прописал в serial.h адреса всех UART, но в функции putc, непосредственно отправляющей символы в порт, поддержку выбора UART не реализовывал.

По поводу register_console и всего такого. Вызывай это из кода драйвера, если он как platform_device, или из кода борды.

дак вроде так и делаю. В коде драйвера у меня есть :

 static int __init sano_uart_console_init(void)
{
/* Регистрация этой консоли */
register_console(&sano_uart_console);
return 0;
}

console_initcall(sano_uart_console_init); /* Метка инициализации консоли */

но не чего не получается. в том-то и дело, что драйвер не инициализируется. если добавить его инициализацию в кернель_старт, то всё работает.

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

Могу ли я написать драйвер, который будет состоять только из функции отправки байт в порт, структуры static struct console sano_uart_console и функции её инициализации вида

static int __init sano_uart_console_init(void)
{
/* Регистрация этой консоли */
register_console(&sano_uart_console);
return 0;
}

console_initcall(sano_uart_console_init); /* Метка инициализации консоли */

или же мне в любом случае придется писать целый драйвер с заданием скорости обмена, выбора порта, частоты юарт и т.д.

Вообще, можешь сделать функцию с сигнатурой «int __init my_func(void)», и из нее вызывать нужный код. А потом в файле с функцией пишешь, например, subsys_initcall(my_func) или device_initcall(my_func) - и после инициализации подсистем функция вызовется. Для уарта можно совсем рано сделать - в map_io или fixup архитектуры.

а вот это уже очень интерестно. Дело в том, что у меня есть в файле борды такая штука

 
MACHINE_START(SPMP8000, "SPMP8000 SoC")
        .boot_params  = 0,//PHYS_OFFSET + 0x00200100,
        .fixup        = spmp8000_fixup,
        .map_io       = spmp8000_map_io_sano,
        .init_irq     = spmp8000_arch_init_irq,
        .init_machine = spmp8000_arch_init,
        .timer        = &spmp8000_timer,
        /* optional ATAG list */
MACHINE_END
при этом сами вызываемые функции выглядят так
 
static void spmp8000_fixup(struct machine_desc *mdesc,
        struct tag *tags, char **from, struct meminfo *meminfo)
{
        meminfo->bank[0].start = 0x000000;
        meminfo->bank[0].size =  0x800000;
        meminfo->nr_banks = 1;
}
static void __init spmp8000_arch_init_irq(void)
{
        printk("spmp8000_arch_init_irq()\n");
}

static void __init spmp8000_arch_map_io(void)
{
        printk("spmp8000_arch_map_io()\n");
}
как я понимаю вы пишете о том, что внутри этих функций я могу так же вызвать инициализацию UART или я опять что-то не понял.

Sanoend
() автор топика
Ответ на: комментарий от Sanoend

я верно понимаю что CONFIG_MY_UART в строке означает, что файл компилируется только если в конфиге ядра будет стоять CONFIG_MY_UART=y или тут дело совсем не в этом? А в Kconfig нужно задавать название секции просто убрав CONFIG_ от CONFIG_MY_UART?

Да, все так

Могу ли я написать драйвер, который будет состоять только из функции отправки байт в порт, структуры static struct console sano_uart_console и функции её инициализации вида

Не знаю, не писал драйвер uart :). В основном, делал фигню типа clock, i2c, LED, battery. Судя по туториалу и исходникам других драйверов - надо нормальный uart делать, хотя надо смотреть, как там tty регистрируется. http://free-electrons.com/doc/serial-drivers-lab.pdf

как я понимаю вы пишете о том, что внутри этих функций я могу так же вызвать инициализацию UART или я опять что-то не понял.

Да, я думаю, можно - они выполняются сразу после настройки MMU (map_io), пока еще ничего важное не успело упасть. Вообще, на всех SoC уарты регистрируются как platform_device, а для дебага юзают какой-нибудь jtag/swd. Но, например, в mach-exynos уарт для низкоуровневой отладки как раз регистрируют из map_io, так что можно посмотреть, как там устроено

alexst
()
Ответ на: комментарий от alexst

Добавил в Kconfig

config SERIAL_SPMP8000
 select SERIAL_CORE
 help
   SPMP8k serial port support.
в конфиг ядра добавил
CONFIG_SERIAL_SPMP8000=y
в макефайл добавил
obj-y(CONFIG_SPMP8000_UART) += serial.o
и собрал ядро. Юарт по прежнему не работает, но что самое странное в арч части перестал собираться файл serial.o (а раньше он был), а само ядро стало меньше весить.

Sanoend
() автор топика
Ответ на: комментарий от Sanoend

более того, если я убираю вообще строку

obj-$(CONFIG_SPMP8000_UART) += serial.o
из Makefile, то размер собранного ядра получается 696628, а если добавляю эту строку, то размер ядра получается 696608. не как не поймы с какой стати ядро уменьшается.

Sanoend
() автор топика
Ответ на: комментарий от Sanoend

кстати а не нужно ли что-нибуль добавлять в /arch/arm/Kconfig, что бы обрабатывались Kconfig из arch части. Сейчас у меня там прописана только такая секция

config ARCH_SPMP8000
                bool "SPMP8000 SoC"
                select ARM_AMBA
                select HAVE_CLK
                select COMMON_CLKDEV
                help
                        Support for the SPMP8000

Sanoend
() автор топика

Судя по странным инклудам драйвер лежит в нестандартном месте. Зачем искать себе проблем?
Проще положить как обычно в drivers/tty/serial/. А еще лучше взять оттуда же за основу простенький драйвер и переделать под свои нужды.

В cmdline ядра дописываешь console=ttyS0

это я прописал, но на данный момент хотел бы вообще игнорировать значения из этой строки и всегда отправлять сообщения в UART0. Я конечно прописал в serial.h адреса всех UART, но в функции putc, непосредственно отправляющей символы в порт, поддержку выбора UART не реализовывал.

Так игнорировать это не мешает:) console параметр он не только передает настройки уарт драйверу, но еще и включает вывод сообщений на этот самый ttyS0.

кстати а не нужно ли что-нибуль добавлять в /arch/arm/Kconfig, что бы обрабатывались Kconfig из arch части. Сейчас у меня там прописана только такая секция

Не знаю, но зачем добавлять что-то в /arch. Это же уровень наравне с ARM, т.е. для кода, который уже и не ARM вовсе.



Добавил в Kconfig

config SERIAL_SPMP8000
select SERIAL_CORE
help
SPMP8k serial port support.

в конфиг ядра добавил

CONFIG_SERIAL_SPMP8000=y

в макефайл добавил

obj-(CONFIG_SPMP8000_UART) += serial.o


Ну здесь уже заметил что должно быть CONFIG_SERIAL_SPMP8000 в Makefile тоже?
Если драйвер не собирается все равно: проверь что CONFIG_SERIAL_SPMP8000=y не пропал из .config.

staring_frog
()
Ответ на: комментарий от staring_frog

Не знаю, но зачем добавлять что-то в /arch. Это же уровень наравне с ARM, т.е. для кода, который уже и не ARM вовсе.

Лучше так сказать: на уровне /arch добавляется новая архитектура. Но у тебя же ARM, поэтому непонятно зачем туда что-то класть.

staring_frog
()
Ответ на: комментарий от devl547

devl547

devl547 не не спрашивал, но я уже перерыл весь инет. До меня было две попытки портировать. Сырцы первой я смог скачать и взял их за основу. Однако там только самое начало порта. Я уже дописал довольно много кода. И ядро грузится значительно дальше.

Второй вариант порта описывается тут: http://lists.infradead.org/pipermail/linux-arm-kernel/2011-October/068699.html однако я так и не смог понять как скачать эти файлы. Все куски кода из этой рассылки я выдернул, но там делеко не всё. В ванильном ядре этих файлов нету. Есть только строка в arch/arm/tools/mach-types letcool MACH_LETCOOL LETCOOL 3617 и всё. Я писал этому Zoltan Devai, но он не отвечает. Может быть я что-то не понимаю и вы подскажите мне как скачать данный патч.

staring_frog я хотел все драйвера для данной платформы положить в arch часть. Т.к. по сути это порт ядра не именно на процессор, а на платформу. Судя по исходникам других платформ принято делать именно так. CONFIG_SERIAL_SPMP8000=y в конфиге есть. Я уже 10 раз проверил. В cmdline я передаю console=ttyS0,115200n8 debug mem=32M

Не знаю, но зачем добавлять что-то в /arch. Это же уровень наравне с ARM, т.е. для кода, который уже и не ARM вовсе.

дело в том, что данный ЮАРТ встроен в процессор под который я делаю порт. И следовательно драйвер этого юарт может использоваться только с этим процессором. Вот я и ложу его в mach часть этого камня.

В любом случае я попробую предложенный вами вариант. Это первый мой порт ядра, по этому возможны очень глупые ошибки с моей стороны. И я не исключаю. что это одна из них.

Sanoend
() автор топика
Ответ на: devl547 от Sanoend

Все куски кода из этой рассылки я выдернул, но там делеко не всё. В ванильном ядре этих файлов нету.

So far, these peripherals are supported, with drivers not submitted yet:
gpio, fb, cpufreq, slave-dma, mmc, ASoC (i2s, codec, pcm, card).

До драйверов похоже дело не дошло, раз первый набор патчей не приняли.


staring_frog я хотел все драйвера для данной платформы положить в arch часть. Т.к. по сути это порт ядра не именно на процессор, а на платформу. Судя по исходникам других платформ принято делать именно так. CONFIG_SERIAL_SPMP8000=y в конфиге есть. Я уже 10 раз проверил. В cmdline я передаю console=ttyS0,115200n8 debug mem=32M

А, я поначалу неправильно понял, раз имеется в виду mach-*, то я умолкаю, сам не знаю четко по какому принципу код распределяется между mach-* и drivers.


Так отделенный уарт драйвер сейчас собирается или нет?

staring_frog
()
Ответ на: комментарий от staring_frog

Драйве собирается только если в макефайле изменить obj-$(CONFIG_SPMP8000_UART) += serial.o на obj-y += serial.o а в сам драйвер несколько пообрезать, в плане изъятия из него всего что касается serial core. Однако вывода в uart не происходит даже в этом случае. Вывод происходит только если зарегистрировать структуры прямо в kernel_start

кстати не как не могу прикрепить лог загрузки на данный момент. Движок форума говорит, что сообщение слишком большое. по этому вот ссылка на лог http://www.onlinedisk.ru/file/930788/

Sanoend
() автор топика
Ответ на: комментарий от Sanoend

Да почему obj-$(CONFIG_SPMP8000_UART) += serial.o
должно быть тогда obj-$(CONFIG_SERIAL_SPMP8000) += serial.o

staring_frog
()
Ответ на: комментарий от Sanoend

Однако вывода в uart не происходит даже в этом случае. Вывод происходит только если зарегистрировать структуры прямо в kernel_start

Посмотри чтобы другие уарт драйвера кроме твоего были выключены в
-> Device Drivers
│ -> Character devices
│ -> Serial drivers

staring_frog
()

Правда может быть все-таки этого кода недостаточно, вот я смотрю драйвера еще вызывают:
494 ret = uart_register_driver(&serial21285_reg);
495 if (ret == 0)
496 uart_add_one_port(&serial21285_reg, &serial21285_port);
(из drivers/tty/serial/21285.c)
Очень похоже что здесь как раз регистрируется одно device и к нему привязывается этот driver.

staring_frog
()
Ответ на: devl547 от Sanoend

Второй вариант порта описывается тут: http://lists.infradead.org/pipermail/linux-arm-kernel/2011-October/068699.html однако я так и не смог понять как скачать эти файлы. Все куски кода из этой рассылки я выдернул, но там делеко не всё. В ванильном ядре этих файлов нету. Есть только строка в arch/arm/tools/mach-types letcool MACH_LETCOOL LETCOOL 3617 и всё. Я писал этому Zoltan Devai, но он не отвечает. Может быть я что-то не понимаю и вы подскажите мне как скачать данный патч

Не знаю поможет тебе это как-нибудь или нет http://www.digipedia.pl/usenet/thread/19011/27120/#post26991 На гитхабе есть ветка Zoltan Devai - https://github.com/zdevai. Но вход туда простым смертным закрыт...

Dennis7
()
Ответ на: комментарий от Sanoend

Я тебе могу прислать патч, который собирает и ядро, и твой драйвер. Но я перенес код драйвера в driver/serial, где, как мне кажется ему самое место.

Потестить ни ядро, ни драйвер не могу, т.к. нет такой железки.

Dennis7
()
Ответ на: комментарий от Dennis7

Я пару дней назад уже изучил этот документ. Ещё через несколько дней собираюсь перечитать (я так лучше запоминаю).

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

Sanoend
() автор топика
Ответ на: комментарий от Sanoend

Ну удачи тебе. И... это... убери вот это вот

/* Параметры каждого из поддерживаемых портов USB_UART */
/* Заполняем структуру консоли */

static struct console sano_uart_console = {
            .name   = "ttyS",                /* Имя консоли */
            .write  = sanoprintk, /* Как делать printk в консоли */
//          .device = uart_console_device,    /* Предоставлена ядром serial */
            .flags  = CON_PRINTBUFFER,        /* Флаг по умолчанию */
            .index  = -1,                     /* Инициализация в неправильное значение */
};
register_console(&sano_uart_console);
из init/main.c Смотреть больно. Тут этого быть не должно.

Dennis7
()
Ответ на: комментарий от Sanoend

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

А ядро-то что такое старое взял в образовательных целях?

Dennis7
()
Ответ на: комментарий от Dennis7

Dennis7 «из init/main.c Смотреть больно. Тут этого быть не должно.» - дак я же в самом начале темы высказывал такое же мнение, просто по другому у меня не работало.

А ядро взял старое т.к. попалась хорошая книга на русском по ядру 2.6 , я не думал , что с веткой 3.х.х будет такая большая разница. Однако я ошибся...

Sanoend
() автор топика

Еще один момент: почитай про earlyprintk. Если вкратце: даже с нормальным драйвером можно не увидеть отладки, если ядро падает очень рано - до инициализации обычной консоли.
Также бывает что вначале сообщения идут, а потом пропадают: earlyconsole как правило в процессе загрузки заменяется обычной и если та неисправна...

staring_frog
()
Ответ на: комментарий от staring_frog

Удалось запустить ядро. Прежде всего хочу поблагодарить всех кто помогал советом. Я создал проек на гулокоде и написал там пару статей по неочевидным, на мой взгляд, момментам. Вот ссылка https://code.google.com/p/linux-on-spmp8000/w/list

Сейчас мучаюсь с запуском экрана. Дисплей совместимый с PSP (пробовали перекидывать). По этому логично предположить что драйвер нужно использовать «Epson S1D13XXX FB Driver». Если верить DTS файлу, а так же данныйм в дизасемблированной родной прошивке, то адресом framebuffer должен быть 0x93000000 я пытался запустить дисплей инициализируя драйвер на этот адрес, но всегда получал сообщение

probe called: device is c01d51a8
Epson S1D13XXX FB Driver
s1d13xxxfb: unknown chip production id 0, revision 0
s1d13xxxfb: please contant maintainer

Добавил дополнительные отладочные строки в цикле сравнения увидел вот это

probe called: device is c01d51a8
Epson S1D13XXX FB Driver
s1d13xxxfb: prod_id = 0, s1d13xxxfb_prod_ids = 3
s1d13xxxfb: prod_id = 0, s1d13xxxfb_prod_ids = 4
s1d13xxxfb: prod_id = 0, s1d13xxxfb_prod_ids = 7
s1d13xxxfb: unknown chip production id 0, revision 0
s1d13xxxfb: please contant maintainer

Прот этом значение переменной prod_id берется как:

 production id is top 6 bits */
prod_id = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
revision id is lower 2 bits */
revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) & 0x3;

где S1DREG_REV_CODE имеет смещение ноль, относительно адреса начала фрейм буферра.

Я пробовал задать руками значения prod_id равные 3,4,7 в этом случае ядро пытается делить на ноль и уходит в панику. Подскажите пожалуйста в какую сторону копать дальше.

Sanoend
() автор топика
Ответ на: комментарий от Sanoend

Универсальные причины - это не включен какой-нибудь clock или не подано питание.
А полный даташит с описанием регистров нашелся?

staring_frog
()
Ответ на: комментарий от Sanoend

Новости и вопросы с полей. На контроллер ЛСД не поступают тактовые импульсы. Я обнаружил что в родной прошивке данный «клок» включается так:

EXPORT scu_set_disp_clk
scu_set_disp_clk
; CODE XREF: scu_lcm_enable+10^Yp
; scu_lcd_enable+4^Yp ...
                LDR     R2, =0x93007000 ;задать регистру Р2 адрес 0x93007000
                LDR     R3, [R2,#0x80] ;косвенно считать в регистр Р3 содержимое памяти по адресу Р2+смещение 0x80
                BIC     R3, R3, #0x100
                STR     R3, [R2,#0x80]
                BIC     R3, R3, #0xFF
                SUB     R0, R0, #1
                ORR     R0, R0, R3
                STR     R0, [R2,#0x80]
                ORR     R0, R0, #0x100
                STR     R0, [R2,#0x80]
                BX      LR
; End of function scu_set_disp_clk

Получается, что в ядре просто нужно создать таймер, который бы записывал по адресу 0x93007080 значение FF для включения и 00 для выключения. Но я не как не могу найти в поисковике как писать драйвера таймеров, я попробовал решить проблему «в лоб» и сделать записть регистра вот так writeb(0xFF, SPMP8000_SCU_A_BASE + SCU_A_LCD_CLK_CFG); и вот так __raw_writeb(0xFF, SPMP8000_SCU_A_BASE + SCU_A_LCD_CLK_CFG); Соответсвенно задав в заголовочных файлах значения

#define SPMP8000_SCU_A_BASE 0x93007000
#define SCU_A_LCD_CLK_CFG 0x80

И естественно получил ошибки типа Unable to handle kernel NULL pointer dereference at virtual address 93007080 и g request at virtual address 93007080 т.к. ядро естественно пытается обращатся к виртуальным адресам.

Подскажите пожалуйста как правильно написать драйвер clock и что можно взять за основу. За ранее спасибо.

Sanoend
() автор топика
Ответ на: комментарий от Sanoend

Подскажите пожалуйста как правильно написать драйвер clock и что можно взять за основу.

Думаю можно взять mach-*/clock* какой попроще. В том как они устроены не разбирался, темный лес для меня)

staring_frog
()
Ответ на: комментарий от Sanoend

Почитал про твои успехи. Продвинулся куда-нибудь после своих последних постов?

А вообще, тред надо было в Development'e создавать.

Dennis7
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.