LINUX.ORG.RU

использование float и double в модуле ядра


0

1

Всем доброго времени суток!

Просьба подсказать по следующему вопросу:

Пишу драйвер PCI устройства для arm-xscale-linux Версия ядра 2.6.20

В драйвере реализуеться некий алгоритм содержащий в том числе функции работающие с float

Например:

static const float scale=16.2688;
void cc_fd(int chan, float *Fd, float *ifd)
{
    long fd;
    float tmp;

    tmp = (*Fd) * scale + (*ifd);
    fd = (long)tmp;
    *ifd = (float)(tmp-fd);
    reg_write(WIRG_FD_CODE(chan),fd);
}

На этапе сборки ядра с модулем имею следующий вывод

drivers/built-in.o: In function `сс_fd':

bik12.c:(.text+0xac9fc): undefined reference to `__mulsf3'

bik12.c:(.text+0xaca04): undefined reference to `__addsf3'

bik12.c:(.text+0xaca0c): undefined reference to `__fixsfsi'

bik12.c:(.text+0xaca14): undefined reference to `__floatsisf'

bik12.c:(.text+0xaca20): undefined reference to `__subsf3'

make: *** [.tmp_vmlinux1] Ошибка 1

Насколько я понимаю компановщик не находит реализацию функций работающих с float. Поддержка операций с плавующей точкой в ядре включена (NWFPE Enabled)

Буду благодарен за совет в какую сторону копать чтоб с этим разобраться. Спасибо!

как минимум, вам нужно kernel_fpu_begin/kernel_fpu_end,
но вам это не поможет.

правильный ответ - не используйте fpu в kernel mode.

idle ★★★★★
()

1) Линкуйте с libgcc.a:

    LIBGCC = $(shell gcc -print-libgcc-file-name)

    mymodule-objs += libgcc.o

    libgcc.o: $(LIBGCC)
            cp $(LIBGCC) libgcc.o

2) При использовании операций с плавающей точкой в ядре нужно вручную сохранять регистры FPU. Почитайте по ссылке, как это сделать для x86:

https://www.rtai.org/index.php?module=documents&JAS_DocumentManager_op=do...

(чтобы прочитать текст по ссылке, мне пришлось скачать страницу на диск и открыть файл вручную. информация актуальная, проверено - работает)

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

>не используйте fpu в kernel mode.

О да, и инструкции выше arm v3.

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

> нужно вручную сохранять регистры FPU.

да

https://www.rtai.org/...


не надо так делать. я же написал про kernel_fpu_begin/end

про линковку с libgcc.a. ну, может и будет работать.

idle ★★★★★
()
Ответ на: комментарий от Evil_Wizard

ядро фигня мне не понравилось !!!!!!!!!!! остоётся токо ждать лутшего.Это для меня говно плохо зделана тупо.Немогли зделать всё как в нормальных аперационках!!! И флоаты и синий экран.Не рекоминдую такое ядро!!!

anonymous
()

Спасибо за советы, попытаюсь слинковать с libgcc

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

На arm'е и так нет fpu. А судя по выводу оно не может слинковаться.

Reset ★★★★★
()

почитай у Броуди про масштабирование и послушай уже умных людей - не используй float

lazyklimm ★★★★★
()

Попытка прилинковать libgcc дает следующее:

LD      drivers/bik/bik_drv.o
arm-xscale-linux-gnu-ld: ERROR: drivers/bik/libgcc.o(_modsi3.o) uses hardware FP, whereas drivers/bik/bik_drv.o uses software FP
arm-xscale-linux-gnu-ld: failed to merge target specific data of file drivers/bik/libgcc.o(_modsi3.o)
arm-xscale-linux-gnu-ld: ERROR: drivers/bik/libgcc.o(_dvmd_lnx.o) uses hardware FP, whereas drivers/bik/bik_drv.o uses software FP
arm-xscale-linux-gnu-ld: failed to merge target specific data of file drivers/bik/libgcc.o(_dvmd_lnx.o)
make[2]: *** [drivers/bik/bik_drv.o] Ошибка 1

По всей видимости либо что-то не так делаю, либо это путь неверный...

Выносить в user spaсe - проблематично ибо алгоритм выполняется внутри обработчика прерывания.

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

>Насколько помню, по ВСЕХ гайдах не рекомендуют использовать fpu в йедре. В юузер спейс никак?

Правильно делают, так как на некоторых архитектурах плавающая точка эмулируется программно

annulen ★★★★★
()

Спасибо за ответы! По всей видимости придется переписывать алгоритм чтобы float не было. Еще раз всем спасибо!

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