mirror of
https://github.com/54shady/kernel_drivers_examples.git
synced 2025-08-11 23:32:00 +00:00
Add simple dma test workflow
This commit is contained in:
@ -6,7 +6,7 @@ DEBFLAGS = -O2
|
||||
endif
|
||||
|
||||
obj-m := crypto-drv.o
|
||||
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
KERNELDIR ?= /usr/src/linux
|
||||
CC ?= gcc
|
||||
PWD := $(shell pwd)
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
参考书:How to Develop Embedded Software Using The QEMU Machine Emulator.pdf
|
||||
|
||||
## 设备和驱动对应的代码
|
||||
## 设备和驱动对应的代码(环境参考huc)
|
||||
|
||||
crypto.c : virtual device in qemu
|
||||
crypto-drv.c : driver for crypto
|
||||
@ -20,16 +20,21 @@ Compile qemu and run
|
||||
./configure --target-list=x86_64-softmmu \
|
||||
--extra-ldflags="`pkg-config --libs openssl`"
|
||||
|
||||
qemu/build/x86_64-softmmu/qemu-system-x86_64 \
|
||||
-drive file=/path/to/system.qcow2 \
|
||||
${HOME}/src/crypto-qemu/build/x86_64-softmmu/qemu-system-x86_64 \
|
||||
-drive file=/data/huc.qcow2 \
|
||||
-smp 2 -m 1024 -enable-kvm \
|
||||
-device pci-crypto,aes_cbc_256="abc" \
|
||||
-netdev tap,id=nd0,ifname=tap0,script=./nat_up.py,downscript=./nat_down.py \
|
||||
-device e1000,netdev=nd0,mac=52:54:00:12:34:27
|
||||
-device e1000,netdev=ssh \
|
||||
-display none \
|
||||
-serial mon:stdio \
|
||||
-vnc 0.0.0.0:0 \
|
||||
-netdev user,id=ssh,hostfwd=tcp::2222-:22
|
||||
|
||||
### 直接在当前目录编译对应的设备驱动模块(crypto-drv.c, Makefile)
|
||||
### 编译对应的设备驱动
|
||||
|
||||
make
|
||||
docker run --rm -it --privileged \
|
||||
-v ${PWD}:/code \
|
||||
-v ${HOME}/src/linux:/usr/src/linux bpf2004 make
|
||||
|
||||
## 调试
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#define DMA_TEST_DEMO
|
||||
/* refcode: linux/drivers/net/ethernet/intel/e1000/e1000_main.c */
|
||||
#define BAR_0 0
|
||||
char e1000_driver_name[] = "mycrypto";
|
||||
@ -276,6 +277,25 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef TEST_VIRT_TO_PHY
|
||||
struct aaaa {
|
||||
int a;
|
||||
char name[10];
|
||||
};
|
||||
|
||||
struct aaaa *virt4a;
|
||||
unsigned long phy4a;
|
||||
|
||||
virt4a = kmalloc(sizeof(struct aaaa), GFP_ATOMIC);
|
||||
if (!virt4a)
|
||||
return -1;
|
||||
virt4a->a = 911;
|
||||
strcpy(virt4a->name, "virt4a");
|
||||
phy4a = virt_to_phys(virt4a);
|
||||
printk("phy4a = 0x%lx, virt4a = 0x%lx\n", phy4a, virt4a);
|
||||
writel(phy4a, hw_addr + DmaInAddress);
|
||||
#endif
|
||||
|
||||
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
|
||||
if (err)
|
||||
{
|
||||
@ -290,6 +310,32 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
printk("Failed allocation memory for DMA\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef TEST_VIRT_TO_PHY
|
||||
//memcpy(cpu_in_addr, virt4a, 4096);
|
||||
|
||||
struct aaaa a = {
|
||||
.a = 912,
|
||||
.name = "test-dma"
|
||||
};
|
||||
memcpy(cpu_in_addr, &a, sizeof(struct aaaa));
|
||||
#endif
|
||||
|
||||
#ifdef DMA_TEST_DEMO
|
||||
struct aaaa {
|
||||
int a;
|
||||
char name[10];
|
||||
};
|
||||
/* setup data */
|
||||
struct aaaa a = {
|
||||
.a = 911,
|
||||
.name = "DmaIn"
|
||||
};
|
||||
|
||||
/* 将需要传输的数据放入dma buffer */
|
||||
memcpy(cpu_in_addr, &a, sizeof(struct aaaa));
|
||||
#endif
|
||||
|
||||
printk("DmaInAddress = 0x%llx, cpu_in = 0x%x\n", dma_in_addr, cpu_in_addr);
|
||||
writel(dma_in_addr, hw_addr + DmaInAddress);
|
||||
writel(4096, hw_addr + DmaInSizeInBytes);
|
||||
@ -306,6 +352,12 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
writel(4096, hw_addr + DmaOutSizeInBytes);
|
||||
writel(1, hw_addr + DmaOutPagesCount);
|
||||
|
||||
#ifdef DMA_TEST_DEMO
|
||||
/* 从dma buffer中取出数据 */
|
||||
struct aaaa *pa = cpu_out_addr;
|
||||
printk("Dma data: %d %s\n", pa->a, pa->name);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#define DMA_TEST_DEMO
|
||||
#define NO2STR(n) case n: return #n
|
||||
|
||||
#define PCI_CRYPTO_DEV(obj) OBJECT_CHECK(PCICryptoState, obj, "crypto")
|
||||
@ -29,7 +30,8 @@
|
||||
|
||||
|
||||
/* DMA Buf IN Address = 64bit physical address << 12 */
|
||||
#define CRYPTO_DEVICE_TO_PHYS(x) (x >> 12) //FIXME
|
||||
#define CRYPTO_DEVICE_TO_PHYS(x) (x) //FIXME
|
||||
//#define CRYPTO_DEVICE_TO_PHYS(x) (x >> 12) //FIXME
|
||||
//#define CRYPTO_DEVICE_TO_PHYS(x) (x & 0xfffffffff000) //FIXME
|
||||
|
||||
#define TYPE_PCI_CRYPTO_DEV "pci-crypto"
|
||||
@ -453,6 +455,14 @@ static void clear_interrupt(PCICryptoState *dev)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DMA_TEST_DEMO
|
||||
struct aaaa {
|
||||
int a;
|
||||
char name[10];
|
||||
};
|
||||
struct aaaa in;
|
||||
#endif
|
||||
|
||||
static void pci_crypto_memio_write(void *opaque,
|
||||
hwaddr addr,
|
||||
uint64_t val,
|
||||
@ -506,6 +516,13 @@ static void pci_crypto_memio_write(void *opaque,
|
||||
break;
|
||||
|
||||
CASE(DmaInAddress)
|
||||
|
||||
#ifdef DMA_TEST_DEMO
|
||||
/* 从驱动传入的物理地址val读取出数据到in */
|
||||
cpu_physical_memory_read(val, &in, sizeof(struct aaaa));
|
||||
printf("a = %d, name = %s\n", in.a, in.name);
|
||||
#endif
|
||||
|
||||
dev->io->DmaInAddress = (uint32_t)val;
|
||||
break;
|
||||
|
||||
@ -518,6 +535,19 @@ static void pci_crypto_memio_write(void *opaque,
|
||||
break;
|
||||
|
||||
CASE(DmaOutAddress)
|
||||
|
||||
#ifdef DMA_TEST_DEMO
|
||||
//struct aaaa out = {
|
||||
// .a = 111,
|
||||
// .name = "dmaout"
|
||||
//};
|
||||
|
||||
in.a = 119;
|
||||
strcpy(in.name, "DmaOut");
|
||||
/* 将dma in的数据修改后写入到物理地址val */
|
||||
cpu_physical_memory_write(val, &in, sizeof(struct aaaa));
|
||||
#endif
|
||||
|
||||
dev->io->DmaOutAddress = (uint32_t)val;
|
||||
break;
|
||||
|
||||
|
Reference in New Issue
Block a user