Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:0
Поисковых ботовПоисковых ботов:2
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:3
Форум » starterkit.ru » Общение
Микроядро OKL4
alman
Добавлено 25.02.2011 05:34
0
Сообщение: 1
alman
2

Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
Уважаемые господа, прошу помощи. Итак, я стал счастливым обладателем SK-AT91SAM9G45.

Плата очень понравилась - её можно использовать даже не обладая навыками системного программирования. Разработчики обо всём позаботились, поэтому достаточно просто собирать в кросс-компиляции приложения, заливать их по FTP и чувствовать себя замечательно.

Но мы не ищем лёгких путей, поэтому плата была приобретена с одной целью - запуском на ней микроядра L4 и перенос системы Xameleon. А теперь я расскажу о проблемах, которые встретились на этом пути и попрошу помочь.

Исходный код микроядра был взят на этой странице: http://wiki.ok-labs.com/Microkernel файл okl4_3.0.tar.gz
Перед закачкой спрашивают некоторую информацию.

Поскольку средства разработки, которые поставляются вместе с платой, оказались несовместимы с okl4_3.0, пришлось скачать средства разработки:

* The SDK - sdk-arm926ejs-3.0.tar.gz (
http://wiki.ok-labs.com/downloads/release-3.0/sdk-arm926ejs-3.0.tar.gz)
* The NICTA tool chain - arm-linux.3.4.4.tar.gz (
http://ertos.nicta.com.au/downloads/tools/arm-linux-3.4.4.tar.gz)
* The cross compiler - arm-linux-gnueabi-4.2.4.tar.gz (
http://wiki.ok-labs.com/downloads/release-3.0/arm-linux-gnueabi-4.2.4.tar.gz
)

Если не ошибаюсь, достаточно скачать только arm-linux-3.4.4.tar.gz

После распаковки пришлось подправить файл okl4_3.0/tools/toolchains.py таким образом, чтобы он использовал кросс-компилятор версии 3.4.4

Команда сборки выглядит следующим образом:

tools/build.py project=ktest machine=versatile PYFREEZE=False \
VERBOSE_STR=True \
VERBOSE_INIT=1 VERBOSE=1 kdb_serial=True pistachio.enter_kdb=True \
TOOLCHAIN=gnu_arm_eabi_toolchain \
pistahio.TOOLCHAIN=gnu_arm_toolchain


После окончания сборки, в директории okl4_3.0/build появляются загрузочные образы. Бинарный файл, готовый для обработки командой mkimage, находится в okl4_3.0/build/images/image.boot.bin

Далее, формируется загрузочный файл для u-boot

mkimage -A arm -O linux -T kernel -C none -n "OKL4:Pistachio" \
-a 0x70008000 -e 0x70008000 \
-d okl4_3.0/build/images/image.boot.bin \
at91_sd.bin

Полученый файл скопирован на загрузочную SD карту, джампер J2 разомкнут и...

Цитата
Start SD card AT91Bootstrap...
Image size: 0xbdb10, load_addr: 0x70008000, ep: 0x70008000
relocating linux kernel to proper address, dst: 0x70008000, src: 0x72000040, len: 0xbdb10, machid: 0x8a4



... и на этом блокируется.

Какая досада! Пришлось "бить челом" на OKL4 Community Forum: http://okl4-community-forum.9692.n2.nabble.com/How-to-run-Hello-world-application-on-AT91SAM9G45-board-tp6061009p6061009.html

Ответ помог, но проблему до конца не решил. Собственно говоря, привожу фрагмент сборочного скрипта, в котором задаются параметры платы (okl4_3.0/platform/vrsatile/tools/machines.py):

Код
class versatile(arm926ejs):
device_core = "versatile"
virtual = False
platform = "versatile"
memory = arm926ejs.memory.copy()
memory['physical'] = [Region(0xc0008000L, 0xc4000000L)]
memory['rom'] = [Region(0x40000000L, 0x50000000L)]
timer_driver_v2 = "sp804_timer"
memory_timer = [Region(0x101e3000, 0x101e4000, "all", "uncached")]
interrupt_timer = [5]
serial_driver_v2 = "pl011_uart_v2"
memory_serial = [Region(0x101f1000, 0x101f2000, "all", "uncached")]
interrupt_serial = [12]
memory_eth = [Region(0x10010000, 0x10020000, "all", "uncached")]
interrupt_eth = [25]
memory_sys = [Region(0x10000000, 0x10001000, "all", "uncached")]
memory_clcd = [Region(0x10120000, 0x10121000, "all", "uncached")]
interrupt_clcd = [16]
memory_kmi0 = [Region(0x10006000, 0x10007000, "all", "uncached")]
interrupt_kmi0 = [35]
memory_kmi1 = [Region(0x10007000, 0x10008000, "all", "uncached")]
interrupt_kmi1 = [36]
v2_drivers = [
(timer_driver_v2, "vtimer", memory_timer, interrupt_timer),
(serial_driver_v2, "vserial", memory_serial, interrupt_serial),
("eth_device", "veth", memory_eth, interrupt_eth),
("versatilesys_device", "vversatilesys", memory_sys, []),
("kmi0_device", "vkmi0", memory_kmi0, interrupt_kmi0),
("kmi1_device", "vkmi1", memory_kmi1, interrupt_kmi1),
("clcd_device", "vclcd", memory_clcd, interrupt_clcd),
("test_device", "vtest", [], [6,7])
]
cpp_defines = arm926ejs.cpp_defines + ["VERSATILE_BOARD"]
zero_bss = True
copy_elf = True


Это уже правленый по моему разумению код. memory['physical'] подсмотрел в образа ядра Linux, который поставляется вместе в SK-AT91SAM9G45.

Ну и собственно вопрос-мольба-о-помощи. Как запустить OKL4 на AT91SAM9G45?

Подозрений несколько:
1. Не разобрался с memory map и гружу не туда. (неужели?)
2. Неправильно заданы прерывания/адреса портов в okl4_3.0/platform/vrsatile/tools/machines.py (очень может быть)
3. OKL4 не поддерживает UART AT91SAM9G45 (маловероятно).
4. Микоядром используется другая скорость и/или параметры порта (flow control), нежели u-boot утилита, соответственно, терминал просто "не видит" данные, идущие от платы. (как проверить?)
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 25.02.2011 11:35 Редактировалось 25.02.2011 11:49 Сообщение: 2
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Цитата

Ну и собственно вопрос-мольба-о-помощи. Как запустить OKL4 на AT91SAM9G45?


Вы похоже полностью проигнорировали то что я вам писал о портировании микроядра - versatile и at91sam9g45 это абсолютно разные платформы, простым изменением адресов io memory и векторов прерываний не обойтись, нужно переписывать минимальный BSP но по второму кругу объяснять нет желания.
Там же по вашему вопросу написали ответ
Цитата

So okl4 supports ARM926ej, and the versatile ARM926ej implementation in particular. Not AT91SAM9G45 directly.
Спуститься к концу Подняться к началу
Персональная информация
alman
Добавлено 26.02.2011 04:02 Сообщение: 3
alman
2

Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
Да, пожалуй, Вы правы. Сначала я кинулся писать длинный ответ на Ваше замечание, но, перечитав Ваши ответы и просмотрев код, пришёл к выводу, что "допиливать" OKL4 особого смысла нет - как выяснилось, трудозатраты на портирование L4Ka:Pistachio и OKL4 соизмеримы. При этом лицензия OKL4 похуже, чем у Pistachio, к тому же разработчики OKL4 потянули в ядро свои user space библиотеки, что тоже не очень хорошо.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 26.02.2011 18:05 Сообщение: 4
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Я бы на вашем месте присмотрелся к fiasco.OC - это текущий вариант L4 Дрезденского университета , насколько я начитал - это далеко не то же l4:fiasco API v2 про которое вы говорили что оно устаревшее.
http://os.inf.tu-dresden.de/pipermail/l4-hackers/2011/004636.html
Прсто закрыть исходники не получится - но это же только плюс :)
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 04.03.2011 23:27 Сообщение: 5
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Вроде что-то заработало но есть вопрос по обработчику прерываний, я не понял где правильно воткнуть acknowledge
Код

Start SD card AT91Bootstrap...
Image size: 0xacab9, load_addr: 0x70000000, ep: 0x70000000
relocating image to proper address, dst: 0x70000000, src: 0x72000040, len: 0xacab9
123
OKL4 - (provider: Open Kernel Labs) built on Mar 4 2011 23:19:50 using gcc version 3.4.4.
Initialized tracebuffer @ 70140000
Initializing kernel space @ f00252d8...
Initializing kernel debugger...
Initializing interrupts...
System running with alignment exceptions enabled
Processor Id => 41069265: v5TEJ, ARM926, rev 5
TLB lock: vectors @ ffff0000
TLB lock: utcb @ ff000000
TLB lock: kernel @ f0000000
Locked kernel into TLB
domain pairs: (0, 1)
Initialising scheduler...
Switching to idle thread
CREATE_CLIST: id=0, max_caps=1024
CREATE_SPACE: id=0, space{0:5}, clist{0:1}, mutex{0:0), max_phys_segs=6, utcb_area{0x80111000:2^0xc}, max_prio=255 has_kreso1
CREATE_SEGMENT_LIST: entries=6
CREATE_THREAD: cap_slot=0, priroity=255, ip=0x80100000, sp=0x80111000, utcb_addr=0x80111000
SETUP_SEGMENT: P:0x71000000..0x74000000, rwx:7, attrib:ff
SETUP_SEGMENT: P:0x70030000..0x70037000, rwx:5, attrib:ff
MAP_MEMORY: V:0x80100000 O:0x0 (P=70030000) S:0x7000 N:0x1 A=0x3 R=0x5
SETUP_SEGMENT: P:0x7002e000..0x7002f000, rwx:6, attrib:ff
MAP_MEMORY: V:0x8010e000 O:0x0 (P=7002e000) S:0x1000 N:0x2 A=0x3 R=0x6
SETUP_SEGMENT: P:0x70038000..0x70039000, rwx:6, attrib:ff
MAP_MEMORY: V:0x80110000 O:0x0 (P=70038000) S:0x1000 N:0x3 A=0x3 R=0x6
SETUP_SEGMENT: P:0x70a00000..0x70b00000, rwx:6, attrib:ff
MAP_MEMORY: V:0x80200000 O:0x0 (P=70a00000) S:0x100000 N:0x4 A=0x3 R=0x6
SETUP_SEGMENT: P:0x70037000..0x70038000, rwx:6, attrib:ff
MAP_MEMORY: V:0x8010f000 O:0x0 (P=70037000) S:0x1000 N:0x5 A=0x3 R=0x6
CREATE_HEAP: phys=70500000, size=400000
kmem_init (f0500400, f0900000) [3M]
CREATE_CLIST: id=1, max_caps=1024
CREATE_SPACE: id=5, space{5:240}, clist{1:256}, mutex{0:256), max_phys_segs=8, utcb_area{0x80070000:2^0x10}, max_prio=255 ha1
CREATE_SEGMENT_LIST: entries=8
ALLOW_PLATFORM_CONTROL
ASSIGN IRQ: irq=0x1
ASSIGN IRQ: irq=0x3
ASSIGN IRQ: irq=0x2
CREATE_THREAD: cap_slot=0, priroity=255, ip=0x80000000, sp=0x8006e000, utcb_addr=0x80070000
SETUP_SEGMENT: P:0x70904000..0x70a00000, rwx:7, attrib:ff
SETUP_SEGMENT: P:0x70040000..0x70082000, rwx:5, attrib:ff
MAP_MEMORY: V:0x80000000 O:0x0 (P=70040000) S:0x42000 N:0x1 A=0x3 R=0x5
SETUP_SEGMENT: P:0x70089000..0x700ac000, rwx:6, attrib:ff
MAP_MEMORY: V:0x80049000 O:0x0 (P=70089000) S:0x23000 N:0x2 A=0x3 R=0x6
SETUP_SEGMENT: P:0x700ad000..0x700ae000, rwx:6, attrib:ff
MAP_MEMORY: V:0x8006d000 O:0x0 (P=700ad000) S:0x1000 N:0x3 A=0x3 R=0x6
SETUP_SEGMENT: P:0x20000000..0x20002000, rwx:6, attrib:ff
MAP_MEMORY: V:0x8006e000 O:0x0 (P=20000000) S:0x2000 N:0x4 A=0x0 R=0x6
SETUP_SEGMENT: P:0x70c00000..0x71000000, rwx:7, attrib:ff
SETUP_SEGMENT: P:0x70b00000..0x70c00000, rwx:6, attrib:ff
MAP_MEMORY: V:0x80300000 O:0x0 (P=70b00000) S:0x100000 N:0x6 A=0x3 R=0x6
SETUP_SEGMENT: P:0x700ac000..0x700ad000, rwx:6, attrib:ff
MAP_MEMORY: V:0x8006c000 O:0x0 (P=700ac000) S:0x1000 N:0x7 A=0x3 R=0x6
CREATE IPC CAP: clist_ref=118, cap_slot=1, thread_ref=48
--- KD# System started (press 'g' to continue) ---
>
Спуститься к концу Подняться к началу
Персональная информация
alman
Добавлено 05.03.2011 11:21 Сообщение: 6
alman
2

Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
Ого! Встроенный debugger заработал! А с терминалом он через polling работает или по прерываниям?

Прерывания от таймера подтверждаются? Если да, то вроде и всё. Остальные прерывания подтверждаются посылкой ответного IPC потоку, от которого пришло прерывания.

Покопался в сырцах микроядра - не совсем понятно, как "внутри" подтверждаются прерывания для ARM, для x86 всё просто и прозрачно.

А на уровне пользователя вообще элементарно, вне зависимости от платформы:

Назначить поток, обслуживающий прерывания:

L4_AssociateInterrupt( L4_GlobalId (IRQ_NUM, 1), L4_GlobalIdOf( L4_Myself() ) );

Код из цикла обработки сообщений:

tag = L4_Wait ( L4_TimePeriod( TIMEOUT_VALUE ), &TID );
if (L4_IpcFailed (tag))
{
if( L4_ErrorCode() == 0x3 ) // Timeout?
{
//printf( "timeout\n" );
}
else
{
//printf( "IPC failed : Error code 0x%lx\n", L4_ErrorCode() );
}
continue;
}

L4_StoreMR(0, &mr);
if( mr == 0xfff00000 )
{
// вызываем обработчик прерывания
// на основе TID можно определить номер прерывания, если драйвер обслуживает несколько устройств
interrupt_handler( TID );
// -- подтверждаем прерывание --
L4_LoadMR(0, 0);
L4_Send( TID );
}
else
{
// здесь может быть обработчик системных вызовов - read, write, ioctl и так далее
}

Во всяком случае в Pistachio прерывания на уровне драйверов обслуживаются именно так.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 05.03.2011 14:24 Сообщение: 7
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Дело тут не в том как в юзерспейс подтвердить - это нужно делать в микроядре для правильной логики работы AIC
Спуститься к концу Подняться к началу
Персональная информация
alman
Добавлено 05.03.2011 19:24 Сообщение: 8
alman
2

Пункты: 740
Регистрация: 04.02.2011
Пол: Мужчина
Странно как-то. Для платформ x86 подтверждение прерываний реализовано в intctrl-pic.h и intctrl-apic.h.

class intctrl_t : public generic_intctrl_t {
private:
i8259_pic_t<0x20> master;
i8259_pic_t<0xa0> slave;
...
void ack(word_t irq) {
if (irq >= 8)
{
slave.ack(irq-8);
master.ack(2);
}
else
master.ack(irq);
};
...
}

а вот что касается платформы arm, то, похоже, метод ack не переопределён и, соответсвенно, вместо него вызывается "заглушка", которая ничего не делает.

Если я правильно понял проблему, то в используемом intctrl.h необходимо реализовать этот метод.

Удивляет лишь одно - почему он нигде не определён для архитектуры arm? Как работает l4ka, если прерывания не подтверждаются? Странно это.

UPDATE:

Пошукал в сырцах и что-то мне не очень нравится то что нашёл:

drivers/sp804_timer/src/sp804_timer.c:
...
/* ack the interrupt */
tintclr_write(0x0);
...

drivers/imx31_timer/src/imx31_timer.c:

здесь вообще непонятно что происходит


static int
device_interrupt_impl (struct device_interface *di, struct imx31_timer *device, int irq)


drivers/pxa250_timer/src/main.c:
...
/* Ack the interrupt. */
sr_write(0x2);
...

Жуть. Бедный Pistachio! OKL вдоволь поиздевалась над ним.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 05.03.2011 20:22 Редактировалось 05.03.2011 20:25 Сообщение: 9
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Цитата
Жуть. Бедный Pistachio! OKL вдоволь поиздевалась над ним.


Да ничего страшного :) Вы немного не поняли - подтвердить прерывания в контроллере прерываний это одно (это нужно делать в микроядре) а в контроллерах периферийных устроств (это делают в обработчиках прерываний этих устройств) это другое. Не для всех контроллеров прерываний нужно подтверждение. У atmel нужно, при этом порядок такой

1 The read of AIC_IVR is the entry point of the interrupt handling which allows the AIC to consider that the interrupt has been taken into account by the software.

2 The nIRQ line can be asserted only if an interrupt condition occurs on an interrupt source with a higher priority. If an interrupt condition happens (or is pending) during the interrupt treatment in progress, it is delayed until the software indicates to the AIC the end of the current service by writing the AIC_EOICR (End of Interrupt Command Register). The write of AIC_EOICR is the exit point of the interrupt handling.

В данном случае естественно переводить задачу по управлению AIC в юзерспейс чревато, если хотя бы раз не подтвердить прерывание - ни одно из них болше не появится на лини nIRQ проессора. Я посмотрел как сделано в фисташке для csb337 (плата на at91rm9200 - почти тоже самое что у нас но ядро старое 920t) и сделал так же - думаю это оптимальный вариант
static inline void mask(word_t irq)
{
ASSERT(irq < IRQS);
AIC(AIC_IDCR) = (1ul << irq);
AIC(AIC_EOICR) = 0; /* Signal that we have handled this interrupt */
}

т.е. после входа в обработчик маскируем сработавшее прерывание и "разрешаем" всем остальным появиться :) они все равно не сработают пока линия irq процессора не будет разблокирована - а об этом уже само ядро позаботится, когда сочтет нужным разрешить прерывания. Потом в фиаско отдельно ack тоже не используется хоть и реализована - там всегда используется mask+ack
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 11.03.2011 11:22 Редактировалось 11.03.2011 11:22 Сообщение: 10
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Запустил тетсы ядра, вроде бы все ок но один тест не проходит и связан он как ни странно :) с прерываниями
Код

SIGRAPH0503
IRQ0100
*** Failure: InterruptControl did not fail
IRQ0200
IRQ0300
IRQ0301


хотя в конце вроде пишет что ошибок 0 смущает меня такой результат

Код

ktest/src/interruptcontrol.c:96:F:Interrupt Control Tests:IRQ0100: InterruptControl did not fail
ktest/src/interruptcontrol.c:116:P:Interrupt Control Tests:IRQ0200: Passed
ktest/src/interruptcontrol.c:216:P:Interrupt Control Tests:IRQ0300: Passed
ktest/src/interruptcontrol.c:249:P:Interrupt Control Tests:IRQ0301: Passed
ktest/src/remotememcpy.c:391:P:Remote Memory Copy:RMC0100: Passed
ktest/src/remotememcpy.c:424:P:Remote Memory Copy:RMC0200: Passed
ktest/src/remotememcpy.c:459:P:Remote Memory Copy:RMC0300: Passed
ktest/src/remotememcpy.c:494:P:Remote Memory Copy:RMC0400: Passed
ktest/src/remotememcpy.c:527:P:Remote Memory Copy:RMC0500: Passed
ktest/src/remotememcpy.c:569:P:Remote Memory Copy:RMC0600: Passed
99%: Checks: 437, Failures: 1, Errors: 0
--- KD# User: L4Test Done ---


Нашел обсуждение проблемы обработчика прерываний для atmel в архве рассылки okl4

http://lists.okl4.org/pipermail/developer/2008-July/001528.html

Там есть кусок сообщения
Цитата

> On Tue, Jul 22, 2008 at 07:22:30PM +0200, Pierre-Antoine Bernard
wrote:
> > Hi Geoffrey,
> >
> > Many thanks for your help.
> > I can give you some kernel interrupt handling code for our ATMEL
AT91SAM9263
> platform (see attachment).


Но как я ни искал - не нашел оригинал сообщения и нужные куски кода.. такое ощущение что потерли архив причем сознательно.
Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Общение