Presentation is loading. Please wait.

Presentation is loading. Please wait.

Using our device-drivers How can an application display the data in a device special file?

Similar presentations


Presentation on theme: "Using our device-drivers How can an application display the data in a device special file?"— Presentation transcript:

1 Using our device-drivers How can an application display the data in a device special file?

2 The ‘fileview.cpp’ application Purpose: a tool for viewing arbitrary files Some files have ascii text Other files have binary data So display in both hexadecimal and ascii Some ascii characters are ‘control codes’ Some bytes are not ascii characters at all So show a substitute mark as necessary

3 Easy file navigation Files may be quite large Can only fit small pieces on one screen And only some parts may be of interest Also some hex formats can be confusing Need a way to find what we want to see Need it to remain visible while we read it Need flexibility to adjust display format

4 The ‘curses’ library Offers users an ‘interactive’ interface Allows use of normal keyboard input Allows use of a mouse Allows use of ‘windows’ and ‘colors’ Allows use cursor-keys for navigation Allows use of ‘unbuffered’ keystrokes Offers instant refresh of display screen

5 Concept behind ‘curses’ Works on screens, windows, subwindows Maintains several internal data-structures Two of these are ‘stdscr’ and ‘curscr’ Both are ‘maps’ of your physical screen Drawing is done to the ‘stdscr’ window But it doesn’t show up immediately ‘refresh()’: compares ‘stdscr’ to ‘curscr’ and then only copies the parts that are ‘new’

6 Using ‘ncurses’ with Linux #include ‘initscr()’ initializes library data-structures ‘noecho()’ turns off keystroke echoing ‘raw()’ and ‘cbreak()’ set special behaviors ‘refresh()’ updates the display screen ‘endwin()’ restores normal tty-behavior

7 The typical ‘curses’ program #include int main( int argc, char **argv ) { initscr(); … endwin(); }

8 Compiling ‘ncurses’ programs Must use the ‘-l’ command-line switch: Example: $ g++ fileview.cpp –lncurses –o fileview This is lowercase ‘L’ (not uppercase ‘i’) It means link with ‘libncurses.so’ library Object libraries are in directory: ‘/usr/lib’

9 Some frequent functions ‘clear()’ ‘move()’ ‘printw()’ ‘mvprintw()’ ‘refresh()’ ‘newwin()’ ‘box()’

10 Reference Good introductory tutorial appears in: Richard Stones and Neil Matthew, “Beginning Linux Programming (2 nd Ed.)” (WROX Press Ltd, 1999), Chapter 6.

11 Unusual goal of ‘fileview.cpp’ Wanted to look at VERY large device-files Eample:/dev/hda This device file represents the hard disk Size of today’s hard disk could be 180GB! So file-positions could not be of type ‘long’ Linux introduces a 64-bit type: loff_t Kernel offers ‘sys_llseek()’ system-call

12 Linux uses ‘glibc’ C-library The Gnu version of Standard C Library ‘glibc’ implements system-call interfaces for the standard UNIX C functions, like open(), close(), read(), write(), and lseek() But Gnu C Library omitted ‘llseek()’ So can’t do seek-operations on big files!

13 Calling ‘llseek()’ anyway Programmers can call the kernel directly Can bypass the ‘glibc’ Standard C Library But need to obey system-call conventions Transition from user-mode to kernel-mode Requires use of a special CPU instruction This instruction is ‘architecture-specific’ For Pentium CPU: asm(“ int $0x80 “);

14 Some ‘macros’ make it easier #include Calling ‘sys_llseek()’ requires 5 arguments Arguments must go into CPU registers ‘sys_call_table[ ]’ array-index goes in EAX The macro to use is named ‘_syscall5’

15 A programming ‘bug’ Standard C ‘read()’ function returns ‘int’ Meaning of the ‘read()’ return-value: retval > 0: ‘retval’ bytes successfully read retval = 0 : end-of-file reached, so no data retval < 0: some error prevented reading Return-value wasn’t checked in ‘fileview’!

16 Why wasn’t ‘bug’ found? ‘fileview’ always tried to read 256 bytes Never tried to read beyond ‘end-of-file’ Never tried to read data that ‘wasn’t there’ So no reason why retval wouldn’t be 256

17 But project #3 is different ‘ram.c’ must read ALL physical pages ‘high memory’ pages not always ‘mapped’ And pages are not ‘mapped’ contiguously 256 bytes could cross a page-boundary –Starting address: 0x00000F80 –Ending address:0x00001080 So some ‘read()’ errors could easily occur

18 How can ‘bug’ be fixed? Several solutions are possible Best to try minimizing the code-changes Should focus on correct ‘fix’ for all drivers Obey rules for driver ‘read()’ functions

19 Some pseudo-code int my_read( int fd, char *cp, int count ) { intmore = count; while ( more ) { intn = read( fd, cp, more ); if ( n <= 0 ) return n; cp += n; more -= n; } returncount; }

20 Recommendations Consult “Linux Device Drivers” text ‘read()’ method is described on page 80 Do everything that’s actually necessary But keep your code as simple as possible During development: use ‘printk()’ output For ‘release version’: omit ‘printk()’ output

21 Exercise Write a ‘hello world’ program in C But don’t use ANY header-files!! (i.e., bypass the Standard C Library) How? 1) setup static message-string 2) setup registers with parameters 3) use ‘int 0x80’ to enter the kernel

22 ‘sys_write( int fd, void *msg, int n)’ The system-call number is 4 The STDOUT file-descriptor is 1 The message-string address is $msg The message-length (you count the bytes) These 4 arguments go in CPU registers: EAX, EBX, ECX, EDX (in that order) So your ‘main()’ needs only 5 instructions!


Download ppt "Using our device-drivers How can an application display the data in a device special file?"

Similar presentations


Ads by Google