Standard C Libraries - PowerPoint PPT Presentation

About This Presentation
Title:

Standard C Libraries

Description:

int close( int fd ); Breaks link between file and file-descriptor ... It opens, reads, and closes /proc/jiffies' And it also uses lseek' (to rewind this file) ... – PowerPoint PPT presentation

Number of Views:24
Avg rating:3.0/5.0
Slides: 31
Provided by: ProfessorA2
Learn more at: https://www.cs.usfca.edu
Category:

less

Transcript and Presenter's Notes

Title: Standard C Libraries


1
Standard C Libraries
  • Application Programmming Interface to System-Calls

2
Important File-I/O Functions
  • int open( char pathname, int flags, )
  • int read( int fd, void buf, size_t count )
  • int write( int fd, void buf, size_t count )
  • int lseek( int fd, loff_t offset, int whence )
  • int close( int fd )

3
UNIX man pages
  • A convenient online guide to prototypes and
    semantics of the C linrary functions
  • Example of usage
  • man 2 open

4
The open function
  • include ltfcntl.hgt
  • int open( char pathname, int flags, )
  • Converts a pathname to a file-descriptor
  • File-descriptor is a nonnegative integer
  • Used as a file-ID in subsequent functions
  • flags is a symbolic constant
  • O_RDONLY, O_WRONLY, O_RDWR

5
The close function
  • include ltunistd.hgt
  • int close( int fd )
  • Breaks link between file and file-descriptor
  • Returns 0 on success, or -1 if an error

6
The write function
  • include ltunistd.hgt
  • int write( int fd, void buf, size_t count )
  • Attempts to write up to count bytes
  • Bytes are taken from buf memory-buffer
  • Returns the number of bytes written
  • Or returns -1 if some error occurred
  • Return-value 0 means no data was written

7
The read function
  • include ltunistd.hgt
  • int read( int fd, void buf, size_t count )
  • Attempts to read up to count bytes
  • Bytes are placed in buf memory-buffer
  • Returns the number of bytes read
  • Or returns -1 if some error occurred
  • Return-value 0 means end-of-file

8
Notes on read() and write()
  • These functions have (as a side-effect) the
    advancement of a file-pointer variable
  • They return a negative function-value of -1 if an
    error occurs, indicating that no actual data
    could be transferred otherwise, they return the
    number of bytes read or written
  • The read() function normally does not return 0,
    unless end-of-file is reached

9
The lseek function
  • include ltunistd.hgt
  • off_t lseek( int fd, off_t offset, int whence )
  • Modifies the file-pointer variable, based on the
    value of whence
  • enum SEEK_SET, SEEK_CUR, SEEK_END
  • Returns the new value of the file-pointer (or
    returns -1 if any error occurred)

10
Getting the size of a file
  • For normal files, your application can find out
    how many bytes belong to a file using the
    lseek() function
  • int filesize lseek( fd, 0, SEEK_END )
  • But afterward you need to rewind the file if
    you want to read its data
  • lseek( fd, 0, SEEK_SET )

11
What about pseudo files?
  • You can use standard library functions to open,
    read, and close a /proc pseudo-file
  • You can use lseek (except SEEK_END)
  • An example is our howfast.cpp program
  • It measures how fast jiffies increments
  • It opens, reads, and closes /proc/jiffies
  • And it also uses lseek (to rewind this file)

12
How these system-calls work
Operating System Kernel
C Runtime Library
Application Program
Module methods
User-space
Kernel-space
13
Special device files
  • UNIX systems treat hardware-devices as special
    files, so that familiar functions can be used by
    application programmers to access these devices
    (open, read, close)
  • But a System Administrator has to create these
    device-files (in the /dev directory)
  • There are two categories of device files
    character devices, and block devices

14
The mknod command
  • To create the device-node for a character device,
    an Administrator executes mknod
  • root mknod /dev/scull c 48 0
  • Here /dev/scull is the files pathname, c
    indicates that its a character-mode device, 48
    is its (unique) major ID-number, and 0 is its
    (unique) minor ID-number
  • Default access-privileges r w - r - - r - -
  • Can be modified using chmod command

15
Whats new in 2.6?
  • Earlier Linux kernels stored the /dev files on
    the hard disk (so they were persistent)
  • The 2.6 kernel stores them in a ram-disk
  • So they disappear during every shutdown
  • You need root privileges to re-build them!
  • (Fortunately this step can be automated if
    device-nodes are in /etc/udev/devices )

16
A useful device-driver
  • We can create a character-mode driver for the
    processors physical memory (i.e. ram)
  • (Our machines have 1-GB of physical ram)
  • But another device-file is named /dev/ram so
    ours will be /dev/dram (dynamic ram)
  • Weve picked 253 as its major ID-number
  • Our SysAdmin setup a device-node using root
    mknod /dev/dram c 253 0

17
Device knowledge
  • Before you can write a device-driver, you must
    understand how the hardware works
  • Usually this means you need to obtain the
    programmer manual (from manufacturer)
  • Nowdays this can often be an obstacle
  • But some equipment is standardized, or is well
    understood (because of its simplicity)

18
1-GB RAM has zones
ZONE_NORMAL
ZONE_HIGH
128-MB
1024-MB ( 1GB)
16-MB
ZONE_LOW
19
Legacy DMA
  • Various older devices rely on the PC/ATs DMA
    controller to perform data-transfers
  • This chip could only use 24-bit addresses
  • Only the lowest 16-megabytes of physical memory
    are visible to these devices
  • 224 0x01000000 (16-megabytes)
  • Linux tries to conserve its use of memory from
    this ZONE_LOW region for anything except DMA (so
    it will available if needed)

20
HIGH memory
  • Linux traditionally tried to map as much
    physical memory as possible into virtual
    addresses allocated to the kernel-space
  • Before the days when systems had 1-GB or more of
    installed memory, Linux could linearly map ALL of
    the physical memory into the 1-GB kernel-region
  • 0xC0000000 0xFFFFFFFF
  • But with 1GB theres not enough room!

21
The 896-MB limit
not-mapped
User space (3GB)
DRAM (1GB)
Kernel space (1GB)
HIGH MEMORY
896-MB
linearly mapped
Physical address-space
A special pair of kernel-functions named
kmap() and kunmap() can be called by
device-drivers to temporarily map pages of
physical memory into vacant areas within the
kernels virtual address-space
Virtual address-space
22
copy_to_user()
  • With kernel 2.6, it is possible to configure the
    user-space versus kernel-space split so that
    nearly 4GB of physical memory is always linearly
    mapped into kernel-space
  • The configuration-option is CONFIG_4GB
  • With this option enabled, the user-space and
    kernel-space use two different maps
  • So device-drivers need a special function to
    transfer kernel-data to a users buffer

23
Driver-module structure
  • We will need three kernel header-files
  • include ltlinux/modulegt
  • // for printk(), register_chrdev(),
    unregister_chrdev()
  • include ltlinux/highmem.hgt
  • // for kmap(), kunmap(), and num_physpages
  • include ltasm/uaccess.hgt
  • // for copy_to_user()

24
Our dram_size global
  • Our init_module() function will compute the
    size of the installed physical memory
  • It will be stored in a global variable, so it can
    be accessed by our driver methods
  • It is computed from a kernel global using the
    PAGE_SIZE constant (4096 for x86)
  • dram_size num_physpages PAGE_SIZE

25
major ID-number
  • Our major device ID-number is needed when we
    register our device-driver with the kernel
    (during initialization) and later when we
    unregister our device-driver (during the
    cleanup procedure)
  • int my_major 253 // static ID-assignment

26
Our file_operations
  • Our dram device-driver does not need to
    implement special methods for doing the
    open(), write(), or release() operations
    (the kernel default operations will suffice)
  • But we DO need to implement read() and
    llseek() methods
  • Our llseek() code here is very standard
  • But read() is specially crafted for DRAM

27
Using our driver
  • We have provided a development tool on the class
    website (named fileview.cpp) which can be used
    to display the contents of files (including
    device-files)
  • The data is shown in hex and ascii formats
  • The arrow-keys can be used for navigation
  • The enter-key allows an offset to be typed
  • Keys b, w, d and q adjust data-widths

28
In-class exercise 1
  • Install the dram.ko device-driver module then
    use fileview to browse the contents of the
    processors physical memory
  • fileview /dev/dram

29
Control Register CR3
  • Register CR3 holds the physical-address of the
    systems current page-directory
  • The page-directory is an array of 1024 entries,
    showing how virtual addresses are currently
    mapped to physical pages
  • With fileview you can find and examine this
    important kernel data-structure but you must
    know the value in register CR3

30
In-class exercise 2
  • Use the newinfo wizard to quickly create a
    pseudo-file (named /proc/cr3) that will allow
    user-programs to obtain the current value of the
    Pentiums CR3 register
  • Write a tool (named seepgdir.cpp) that will
    read /proc/cr3 to get the address of the
    page-directory, then read it from the /dev/dram
    device and print it onscreen
Write a Comment
User Comments (0)
About PowerShow.com