1 / 36

rtl_posixio(module)

rtl_posixio(module). 928316 方國州 946339 陳昱廷. Outline. Introduction Code trace /dev/mem Reference. POSIX. POSIX (the ” Portable Operating System Interface ” ) is a specification which dictates how operating systems should behave.

Download Presentation

rtl_posixio(module)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. rtl_posixio(module) 928316 方國州 946339 陳昱廷

  2. Outline • Introduction • Code trace • /dev/mem • Reference

  3. POSIX • POSIX (the ”Portable Operating System Interface”) is a specification which dictates how operating systems should behave. • Among other things, it specifies basic operations involving signaling and threads, making it easier for programmers to port their applications from one operating system to the other.

  4. POSIX Interfaces • Extensions • System API Extensions • Real Time and Related API • Threads API • Real Time Extensions • Security • Additional Utilities • Protection and Control Utilities

  5. POSIX in RTLinux • RTLinux API is based on a small system POSIX “profile” that is specified in POSIX standards 1003.13 PSE51. • This profile is for a ”minimal real-time system” environment and it looks very much like a multithreaded single POSIX process.

  6. I/O device • Block Device • Allow random access • Fixed size of block • Ex: HD , CD-ROM , Floppy • Character Device • Do not need to support all functionality of regular files • Ex: most other devices • The device serviced by RTLinux device driver only can be a character device

  7. rtl_posixio • rtl_posixio supports POSIX style read/write/open interface to device drivers.

  8. rtl_posixio • Linux has difficulty on OPEN for supporting POSIXIO • Open in a file system is inherent non-real time • Opening a device file may require an unbounded time for • traversal of the namespace • following symbolic links • Resolving directories • Cross mount point

  9. Code trace • Basic operation • rtl_register_rtldev • rtl_unregister_rtldev • Function calls • open • close • read • write • mmap / munmap • ioctl

  10. Data Structure • struct device_struct { const char * name; struct rtl_file_operations * fops; }; • static struct device_struct rtldevs[MAX_CHRDEV] = { { NULL, NULL }, };

  11. Data Structure • struct rtl_file_operations { loff_t (*llseek) (struct rtl_file *, loff_t, int); ssize_t (*read) (struct rtl_file *, char *, size_t, loff_t *); ssize_t (*write) (struct rtl_file *, const char *, size_t, loff_t *); int (*ioctl) (struct rtl_file *, unsigned int, unsigned long); int (*mmap) (struct rtl_file *, void *start, size_t length, int prot , int flags, off_t offset, caddr_t *result); int (*open) (struct rtl_file *); int (*release) (struct rtl_file *); };

  12. Data Structure • struct rtl_file { struct rtl_file_operations *f_op; int f_minor; int f_flags; loff_t f_pos; }; • static struct rtl_file rtl_files [MAX_RTL_FILES] = { { NULL, 0 }, };

  13. rtl_register_rtldev • int rtl_register_rtldev(unsigned int major, const char * name, struct rtl_file_operations *fops) { if (major >= MAX_CHRDEV) return -EINVAL; if (rtldevs[major].fops && rtldevs[major].fops != fops) { return -EBUSY; } rtldevs[major].name = name; rtldevs[major].fops = fops; return 0; }

  14. rtl_unregister_rtldev • int rtl_unregister_rtldev(unsigned int major, const char * name) { if (major >= MAX_CHRDEV) return -EINVAL; if (!rtldevs[major].fops) return -EINVAL; if (strcmp(rtldevs[major].name, name)) return -EINVAL; rtldevs[major].name = NULL; rtldevs[major].fops = NULL; return 0; }

  15. open • open() will only open files named /dev/filenameNN where filename is the name provided to the register call by the driver and NN is an optional device minor number

  16. Open • /* we assume all RTLinux file names are of the form /dev/devicename<number> */ • int open(const char *pathname, int flags) • { • int i; • int minor; • int major; • char devname[200]; • char *p; • int ret; • if (strncmp(pathname, "/dev/", 5)) { • __set_errno(ENOENT); • return -1; /* here we can use some other name resolution scheme */ • } • i = 0; • while (i < sizeof(devname) - 1 && *(pathname + 5 + i) && !isdigit(*(pathname + 5 + i))) { • devname[i] = *(pathname + 5 + i); • i++; • } • devname[i] = 0;

  17. Open • if (isdigit(*(pathname + 5 + i))) { • minor = simple_strtoul (pathname + 5 + i, &p, 10); • } else if (!*(pathname + 5 + i)) { • minor = 0; /* like /dev/mem */ • } else { • __set_errno(ENOENT); • return -1; • } • for (i = 0; i < MAX_CHRDEV; i ++) { • if (rtldevs[i].name && !strcmp(rtldevs[i].name, devname)) { • goto found_major; • } • } • rtl_printf("rtl_posixio: dev entry %s not found\n", pathname); • __set_errno(ENOENT); • return -1;

  18. Open • found_major: • major = i; • for (i = 0; i < MAX_RTL_FILES; i ++) { • if (!rtl_files[i].f_op) { • goto found_free; • } • } • __set_errno(ENOMEM); • return -1;

  19. Open • found_free: • rtl_files[i].f_op = rtldevs[major].fops; • rtl_files[i].f_minor = minor; • rtl_files[i].f_flags = flags; • ret = rtl_files[i].f_op->open(&rtl_files[i]); • if (ret < 0) { • /* if open fails free the resources - Mattias • * Sjoesvaerd <mattias@syrensoftware.se> • */ • rtl_files[i].f_op = NULL; • rtl_files[i].f_minor = 0; • rtl_files[i].f_flags = 0; • __set_errno(-ret); • return -1; • } • return i;

  20. Open

  21. Close • int close(int fd) • { • CHECKFD(fd); • rtl_files[fd].f_op->release(&rtl_files[fd]); • rtl_files[fd].f_op = NULL; • return 0; • }

  22. Write • ssize_t write(int fd, const void *buf, size_t count) • { • int ret; • CHECKFD(fd); • ret = rtl_files[fd] . f_op -> write (&rtl_files[fd], buf, count, &rtl_files[fd].f_pos); • if (ret < 0) { • __set_errno(-ret); • return -1; • } • return ret; • }

  23. Read • ssize_t read(int fd, void *buf, size_t count) • { • int ret; • CHECKFD(fd); • ret = rtl_files[fd] . f_op -> read (&rtl_files[fd], buf, count, &rtl_files[fd].f_pos); • if (ret < 0) { • __set_errno(-ret); • return -1; • } • return ret; • }

  24. mmap • caddr_t mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset) • { • int ret; • caddr_t result; • if ((unsigned int) (fd) >= MAX_RTL_FILES || !rtl_files[fd].f_op) { • __set_errno(EBADF); • return (caddr_t) -1; • } • if (! rtl_files[fd] . f_op -> mmap) { • __set_errno(EINVAL); • return (caddr_t) -1; • } • ret = rtl_files[fd] . f_op -> mmap (&rtl_files[fd], start, length, prot, flags, offset, &result); • if (ret != 0) { • __set_errno(-ret); • return (caddr_t) -1; • } • return result; • }

  25. munmap • int munmap(void *start, size_t length) • { • iounmap (start); • return 0; • }

  26. ioctl • int ioctl(int fd, int request, ...) • { • int ret; • va_list list; • unsigned long arg; • va_start (list, request); • arg = va_arg(list, unsigned long); • va_end (list); • CHECKFD(fd); • ret = rtl_files[fd] . f_op -> ioctl (&rtl_files[fd], request, arg); • if (ret < 0) { • __set_errno(-ret); • return -1; • } • return 0; • }

  27. /dev/mem support • This driver allows real-time threads to access physical computer memory in the same way as Linux processes can do. • dev/mem support is optional. (CONFIG_RTL_DEVMEM_SUPPORT)

  28. /dev/mem Using /dev/mem is preferable for two reasons : • doing so will allow debugging real-time threads as Linux threads. • future implementations of realtime Linux may provide optional memory protection for real-time tasks

  29. Related functions init_module cleanup_module rtl_mem_open rtl_mem_release rtl_mem_write rtl_mem_read rtl_mem_mmap rtl_mem_llseek

  30. Init/cleanup • int init_module(void) • { • if (rtl_register_rtldev (MEM_MAJOR, "mem", &rtl_mem_fops)) { • printk ("RTLinux /dev/mem: unable to get RTLinux major %d\n", MEM_MAJOR); • return -EIO; • } • return 0; • } • void cleanup_module(void) • { • rtl_unregister_rtldev(MEM_MAJOR, "mem"); • }

  31. Open/release • static int rtl_mem_open (struct rtl_file *filp) • { • return 0; • } • static int rtl_mem_release (struct rtl_file *filp) • { • filp->f_pos = 0; • return 0; • }

  32. Read/write • static ssize_t rtl_mem_write(struct rtl_file *filp, const char *buf, size_t count, loff_t* ppos) • { • memcpy_toio ((long) *ppos, buf, count); • *ppos += count; • return count; • } • static ssize_t rtl_mem_read(struct rtl_file *filp, char *buf, size_t count, loff_t* ppos) • { • memcpy_fromio (buf, (long) *ppos, count); • *ppos += count; • return count; • }

  33. Mem_mmap • static int rtl_mem_mmap (struct rtl_file *file, void *start, size_t length, int prot , int flags, off_t offset, caddr_t *result) • { • /* TODO need to fail if MAP_FIXED was specified etc */ • if (!rtl_rt_system_is_idle()) { • return -EAGAIN; • } • *result = ioremap (offset, length); • if (!*result) { • return -EINVAL; • } • return 0; • }

  34. Mem_llseek • static loff_t rtl_mem_llseek(struct rtl_file *file, loff_t offset, int origin) • { • if (origin != SEEK_SET) { • return -EINVAL; • } • return file->f_pos = offset; • }

  35. Reference • 1. http://kernelnewbies.org/documents/kdoc/kernel-api/r817.html • 2. http://www.die.net/doc/linux/man/man2/mmap.2.html • 3. http://kernel.korea.ac.kr/lxr/linux-2.4.24/http/source/arch/sh64/lib/io.c#L182

  36. Reference • 4. http://www.linuxaid.com.cn/articles/4/6/46262537.shtml • 5. http://publib.boulder.ibm.com/infocenter/pseries/index.jsp?topic=/com.ibm.aix.doc/libs/basetrf1/lseek.htm • 6. http://rtportal.upv.es/tutorial/documentacion/design.pdf

More Related