Я хочу использовать sycall для копирования структуры из пользовательского пространства в ядро.
В обоих пользователей и пространстве ядра, то структура определяется какcopy_from_user извлекает непредвиденные данные
struct packet{
unsigned char packet[256];
int length;
}__attribute__ ((packed));
пространства пользователя использует локальную переменную типа структуры пакета и передает его в записи системного вызова.
сторона
struct packet p;
/* ... (fill in data) */
printf("packet.length: %d\n",packet.length); /* looks correct */
result = write(uartFD, &p, sizeof(struct packet));
Ядро выглядит следующим образом, проверка правильной длины делается, просто удалены из примера.
/* write syscall */
ssize_t packet_write(
struct file *file_ptr,
const char __user *user_buffer,
size_t count, loff_t *position)
{
struct packet p;
int retval;
if (copy_from_user((void*)&p, user_buffer, sizeof(struct packet))){
retval = -EACCES;
goto err;
}
/* looks wrong - different numbers like 96373062 or 96373958 */
printk("packet length: %d\n",p.length);
Противоположное направление с помощью чтения sycall работает, как ожидалось:
/* read syscall */
struct packet p;
/* ... (fill in data) */
copy_to_user(user_buffer, (void*)&p, sizeof(struct packet));
/* userspace */
read(uartFD, (void*)&packet, sizeof(struct packet));
Что я делаю неправильно с записью системного вызова?
Есть еще несколько отладки: Что делать, если вы напишете 256-байтовый буфер, заполненный с отсчетом (0,1,2, 3 и т. Д.)? Что делать, если вы отправляете только длину в виде 4-байтового целого? Это проблема форматирования или выравнивания или фундаментальная проблема с получением данных через границу пользователя/ядра? – Peter