Archive

Posts Tagged ‘программирование’

Забыли…

March 21st, 2012 No comments

Итак, в результате долгой возни с uio и общения в списке рассылки ядра, выяснилось, что проблема не в самом ядре, а в том, что документация не соответствует текущему положению вещей.
В документации описывается, что для получения доступа к памяти устройства средствами uio необходимо пользоваться функцией mmap() примененной к /dev/uioX. Однако, теперь это не так. Теперь для этих целей надо мапировать файлы resource, расположенные в соответствующих подкаталогах /sys/. Одно из упоминаний об этом было в списке рассылки и больше никаких подсказок. Теперь упоминания два. Интересно, как быстро соответсвующие доки появлятся в интернете?

Кусок кода, который заработал в первом приближении:

 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>

 #include <sys/mman.h>
 #include <stdio.h>

 int main() {
         int fd = open("/sys/class/pci_bus/0000:03/device/0000:03:00.0/resource5", O_RDWR | O_SYNC);
         printf("fd = %d\n", fd);
         void *addr = mmap(NULL, 512, PROT_READ, MAP_SHARED, fd, 0);
         if(addr == MAP_FAILED)  {
                 perror("mmap");
         }
         else {
                 printf("addr = %p\n", addr);
         }
}

Как много линуксоидов красивых…

March 20th, 2012 6 comments

Заметил интересную вещь. В интернете существуют тысячи сайтов, посвященных линуксу. Различные форумы, сайты how-to, любительские блоги и так далее. Тысячи людей ежедневно устанавливают линукс на свои компьютеры. Линукс прочно поселился даже в телефонах…
Но почему-то, когда ты оказываешься один на один с ядром, найти полезную информацию очень сложно. Причем чем дальше, тем меньше этой информации. Ни на форумах, ни в IRC ответов не дают и даже не намекают. В исходниках ядра без поллитры уже не разберешься. Создается впечатление, что сообщество стало расти катастрофически вширь, а не качественно. А нужно ли нам такое сообщество?

Риторический вопрос по Си.

January 27th, 2012 3 comments
int main()
{
int n;
float mas[n];
mas[0] = 6.6;
}

При запуске такой код, естественно, даст Segmentation fault, но при компиляции ничего кроме варнинга(а кто на них смотрит?) не выдаст. Visual Studio ругается сразу. Пробовал на icc, gcc, pcc.
Может все-таки переходить на яву? :)

Антивирусы…

April 14th, 2011 2 comments

Каким антивирусом Вы пользуетесь? Почему?
Сам пользуюсь бесплатной версией avira . Работает хорошо, удобный. Тесты в интернете, как всегда, проплаченые, в каждом побежадет “нужный” антивирус. Кого-нибудь антивирус уже спасал в реальной ситуации? Я уже давно не сталкивался с вирусами, поэтому оценить адекватность того или иного продукта не в силах. Хотелось бы услышать посторонние мнения.

Вот, нашел интересную ссылку http://vx.netlux.org/ “Цель этого сайта – дать информацию о компьютерных вирусах (или, как предпочитают некоторые – вирях) каждому, кто в этом заинтересован.” Доки, исходники, коллекция вирусов. По внешним признакам весьма оперативно обновляется.

jni и ioctl

March 23rd, 2011 No comments

Итак, я готов показать вам еще кусочик черной магии. Сегодня мы будем с вами работать с железом при помощи Java Native Interface.

Задача для меня типовая. Есть некоторая плата АЦП(хотя это может быть любое другое устройство). Для нее есть драйвер под линукс. Обмен данными с платой происходит при помощи сообщений, передаваемых через ioctl.  Необходимо эти сообщения получать в ПО, обрабатывать и посылать что-нибудь в ответ через те же ioctl.

Итак, как вы знаете, Java предоставляет средство для работы с внешними системными библиотеками, это средство – JNI. Воспользовавшись этим мощнейшим средством, мы напишем небольшую библиотеку, которая обеспечит нам взаимодействие с ioctl, который является системным вызовом и напрямую из Java недоступен.

Подготовим класс-обертку:

public class LL {

public static native int Ioctl(int descr, int cmd, int[] data);
public static native int Open(String linkName);
public static native int Close(int fd);

}

Как описано в прошлой статье сгененируем заголовочный файл для C:

$ javac LL.java
$ javah -jni LL

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

Полученый LL.h:

/* DO NOT EDIT THIS FILE – it is machine generated */
#include
/* Header for class LL */

#ifndef _Included_LL
#define _Included_LL
#ifdef __cplusplus
extern “C” {
#endif
/*
* Class: LL
* Method: Ioctl
* Signature: (II[I)I
*/
JNIEXPORT jint JNICALL Java_LL_Ioctl
(JNIEnv *, jclass, jint, jint, jintArray);

/*
* Class: LL
* Method: Open
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_LL_Open
(JNIEnv *, jclass, jstring);

/*
* Class: LL
* Method: Close
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_LL_Close
(JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

Теперь напишем реализацию этих функций:

#include "LL.h"
#include
#include
#include

#define MAXDRVMSG 32

JNIEXPORT jint JNICALL Java_LL_Ioctl(JNIEnv *env, jclass jc, jint fd, jint cmd, jintArray data)
{
int res = -1;
if(data == NULL)
{
fprintf(stderr,"no param ioctl");
res = ioctl(fd, cmd);
}
else
{
fprintf(stderr,"with param ioctl %p\n",data);
unsigned int *x = (unsigned int *) calloc(MAXDRVMSG, sizeof(unsigned int));
res = ioctl(fd, cmd, x);
(*env)->SetIntArrayRegion(env, data, 0, MAXDRVMSG, (jint *) x);
}
fprintf(stderr,"LL_Ioctl: fd %d result %d\n",fd, res);
return res;
}

JNIEXPORT jint JNICALL Java_LL_Open(JNIEnv *env, jclass jc, jstring linkname)
{
jboolean iscopy;
const char *mfile = (*env)->GetStringUTFChars(env, linkname, &iscopy);
fprintf(stderr,"LL_Open: filename %s\n",mfile);
int fd = open(mfile, O_RDWR);
fprintf(stderr,"LL_Open: descr %d\n",fd);
return fd;
}

JNIEXPORT jint JNICALL Java_LL_Close(JNIEnv *env, jclass jc, jint fd)
{
fprintf(stderr,"LL_Close: fd %d\n",fd);
return close(fd);
}

Отличие от предыдущего эксперимента в том, что теперь мы стали получать данные из функций, описанных в нашей библиотеке. В простых случаях Close и Open проблем с возвратом не возникает, а вот в случае с Ioctl, где нам надо получать\отправлять блоки данных, а не примитивные типы без хитростей не обойтись. В данном случае хитрость в том, что для обмена с драйвером мы выделим временный буффер, в который скопируем данные из data, переданного в качестве параметра функции. После системого вызова нам надо будет скопировать данные из ответа назад в нашу виртуальную машину.

Makefile для собрки этого безобразия:

SRC=LL.c
OBJ=libll.o
LIB=libll.so

GCC=gcc

default:
$(GCC) -c $(SRC) -o $(OBJ)
$(GCC) -shared -Wl,-soname,$(LIB) -o $(LIB) $(OBJ) -lc

jni:
javac -d ../out/production/jni_hw/ ../src/LL.java
javah -jni -classpath ../out/production/jni_hw/ LL

И небольшой тестик:

public class LLtest {

public static void main(String[] args)
{
System.load(“/home/toch/src/java/jni_hw/jni/libll.so”);
int x = LL.Open(“/dev/char_dev”);
int[] msg = new int[32];
LL.Ioctl(x, 1, msg);
for(int i = 0;i<32;i++) System.out.println(String.format("0x%x",msg[i]));
LL.Close(x);
}
}

мультирум, проектирование