I wrote a character driver
and an interface to interact with it
When I run ./test_my_cdev "Hello, Kernel"
the kernel crashes and the computer reboots.
the crash dump has this info :
Does anyone know why this is happening and/or how to solve it?
Code:
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/uio.h>
d_open_t open;
d_close_t close;
d_read_t read;
d_write_t write;
static struct cdevsw char_dev = {
.d_version = D_VERSION,
.d_open = open,
.d_close = close,
.d_read = read,
.d_write = write,
};
static char buf[512+1];
static size_t len;
int
open(struct cdev *dev, int flag, int otyp, struct thread *td)
{
/* Initialize character buffer */
memset(&buf, '\0', 512 + 1 );
len = 0;
return (0);
}
int close(struct cdev *dev, int flag, int otyp, struct thread *td)
{
return(0);
}
int
write(struct cdev *dev, struct uio *uio, int ioflag)
{
int error = 0;
error = copyinstr(uio->uio_iov->iov_base, &buf, 512, &len);
if (error != 0)
uprintf("Write to \"character device\" failed.\n" );
return(error);
}
int
read(struct cdev *dev, struct uio *uio, int ioflag)
{
int error = 0;
if(len <= 0)
error = -1;
else
copystr(&buf, uio->uio_iov->iov_base, 512+1, &len);
return(error);
}
static struct cdev *sdev;
static int
load(struct module *module, int cmd, void *arg)
{
int error = 0;
switch (cmd){
case MOD_LOAD:
sdev = make_dev(&char_dev, 0, UID_ROOT, GID_WHEEL,
0600, "char_dev");
uprintf("Character device loaded.\n");
break;
case MOD_UNLOAD:
destroy_dev(sdev);
uprintf("Character device unloaded.\n");
break;
default:
error = EOPNOTSUPP;
break;
}
return (error);
}
DEV_MODULE(char_dev, load, NULL);
and an interface to interact with it
Code:
#include <stdio.h>
#include <fcntl.h>
#include <paths.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
static char buf[512+1];
int
main(int argc, char *argv[])
{
int kernel_fd;
int len;
if(argc != 2){
printf("Usage:\n%s <string>\n", argv[0]);
exit(0);
}
if((kernel_fd = open("/dev/char_dev", O_RDWR)) == -1){
perror("/dev/char_dev");
exit(1);
}
if((len = strlen(argv[1])+1) > 512){
printf("ERROR: String is too long\n");
exit(0);
}
if (write(kernel_fd, argv[1], len) == -1)
perror("write()");
else
printf("Wrote \"%s\" to device /dev/char_dev""\n", argv[1]);
if(read(kernel_fd, buf, len) == -1)
perror("read()");
else
printf("Read \"%s\" from device /dev/char_dev""\n", buf);
if((close(kernel_fd)) == -1){
perror("close()");
exit(1);
}
close(kernel_fd);
exit(0);
}
When I run ./test_my_cdev "Hello, Kernel"
the kernel crashes and the computer reboots.
the crash dump has this info :
Code:
Fatal trap 12: page fault while in kernel mode
cpuid = 1; apic id = 01
fault virtual address = 0x601220
fault code = supervisor write data, protection violation
instruction pointer = 0x20:0xffffffff810722d1
stack pointer = 0x28:0xfffffe004b268860
frame pointer = 0x28:0xfffffe004b268860
code segment = base 0x0, limit 0xfffff, type 0x1b
= DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags = interrupt enabled, resume, IOPL = 0
current process = 9976 (test_my_cdev)
trap number = 12
Does anyone know why this is happening and/or how to solve it?