Академический Документы
Профессиональный Документы
Культура Документы
EX.NO:
1
Available for Motorola 68000-series processors, Sun Sparc systems, and for PC
and PowerMac systems
2.4 and 2.6 increased SMP support, added journaling file system, preemptive
kernel, 64-bit memory support
3.0 released in 2011, 20th anniversary of Linux, improved virtualization support,
new page write-back facility, improved memory management, new Completely
Fair Scheduler
The Linux System
Linux uses many tools developed as part of Berkeleys BSD operating system,
MITs X Window System, and the Free Software Foundation's GNU project
The main system libraries were started by the GNU project, with improvements
provided by the Linux community
Linux networking-administration tools were derived from 4.3BSD code; recent
BSD derivatives such as Free BSD have borrowed code from Linux in return
The Linux system is maintained by a loose network of developers collaborating
over the Internet, with a small number of public ftp sites acting as de facto
standard repositories
File System Hierarchy Standard document maintained by the Linux community
to ensure compatibility across the various system components
o Specifies overall layout of a standard Linux file system, determines under
which directory names configuration files, libraries, system binaries, and
run-time data files should be stored
Linux Distributions
Standard, precompiled sets of packages, or distributions, include the basic Linux
system, system installation and management utilities, and ready-to-install
packages of common UNIX tools
The first distributions managed these packages by simply providing a means of
unpacking all the files into the appropriate places; modern distributions include
advanced package management
Early distributions included SLS and Slackware
o Red Hat and Debian are popular distributions from commercial and
noncommercial sources, respectively, others include Canonical and SuSE
The RPM Package file format permits compatibility among the various Linux
distributions
Linux Licensing
The Linux kernel is distributed under the GNU General Public License (GPL), the
terms of which are set out by the Free Software Foundation
o Not public domain, in that not all rights are waived
2
Anyone using Linux, or creating their own derivative of Linux, may not make the
derived product proprietary; software released under the GPL may not be
redistributed as a binary-only product
o Can sell distributions, but must offer the source code too
Design Principles
Linux is a multiuser, multitasking system with a full set of UNIX-compatible tools
Its file system adheres to traditional UNIX semantics, and it fully implements the
standard UNIX networking model
Main design goals are speed, efficiency, and standardization
Linux is designed to be compliant with the relevant POSIX documents; at least two
Linux distributions have achieved official POSIX certification
o Supports Pthreads and a subset of POSIX real-time process control
The Linux programming interface adheres to the SVR4 UNIX semantics, rather
than to BSD behavior
Components of a Linux System
3
A kernel module may typically implement a device driver, a file system, or a
networking protocol
The module interface allows third parties to write and distribute, on their own
terms, device drivers or file systems that could not be distributed under the GPL.
Kernel modules allow a Linux system to be set up with a standard, minimal kernel,
without any extra device drivers built in.
Four components to Linux module support:
o module-management system
o module loader and unloader
o driver-registration system
o conflict-resolution mechanism
Module Management
Supports loading modules into memory and letting them talk to the rest of the
kernel
Module loading is split into two separate sections:
o Managing sections of module code in kernel memory
o Handling symbols that modules are allowed to reference
The module requestor manages loading requested, but currently unloaded, modules;
it also regularly queries the kernel to see whether a dynamically loaded module is
still in use, and will unload it when it is no longer actively needed
Driver Registration
Allows modules to tell the rest of the kernel that a new driver has become available
The kernel maintains dynamic tables of all known drivers, and provides a set of
routines to allow drivers to be added to or removed from these tables at any time
Registration tables include the following items:
o Device drivers
o File systems
o Network protocols
o Binary format
Conflict Resolution
A mechanism that allows different device drivers to reserve hardware resources and
to protect those resources from accidental use by another driver.
The conflict resolution module aims to:
o Prevent modules from clashing over access to hardware resources
o Prevent autoprobes from interfering with existing device drivers
o Resolve conflicts with multiple drivers trying to access the same hardware:
1. Kernel maintains list of allocated HW resources
2. Driver reserves resources with kernel database first
3. Reservation request rejected if resource not available
4
Process Management
UNIX process management separates the creation of processes and the running of a
new program into two distinct operations.
o The fork() system call creates a new process
o A new program is run after a call to exec()
Under UNIX, a process encompasses all the information that the operating system
must maintain to track the context of a single execution of a single program
Under Linux, process properties fall into three groups: the processs identity,
environment, and context
Process Identity
Process ID (PID) - The unique identifier for the process; used to specify processes
to the operating system when an application makes a system call to signal,
modify, or wait for another process
Credentials - Each process must have an associated user ID and one or more
group IDs that determine the processs rights to access system resources and files
Personality - Not traditionally found on UNIX systems, but under Linux each
process has an associated personality identifier that can slightly modify the
semantics of certain system calls
o Used primarily by emulation libraries to request that system calls be
compatible with certain specific flavors of UNIX
Namespace Specific view of file system hierarchy
o Most processes share common namespace and operate on a shared file-
system hierarchy
o But each can have unique file-system hierarchy with its own root directory
and set of mounted file systems
Process Environment
The processs environment is inherited from its parent, and is composed of two
null-terminated vectors:
o The argument vector lists the command-line arguments used to invoke the
running program; conventionally starts with the name of the program
itself.
o The environment vector is a list of NAME=VALUE pairs that associates
named environment variables with arbitrary textual values.
Passing environment variables among processes and inheriting variables by a
processs children are flexible means of passing information to components of the
user-mode system software.
The environment-variable mechanism provides a customization of the operating
system that can be set on a per-process basis, rather than being configured for the
system as a whole.
5
Process Context
The (constantly changing) state of a running program at any point in time
The scheduling context is the most important part of the process context; it is the
information that the scheduler needs to suspend and restart the process
The kernel maintains accounting information about the resources currently being
consumed by each process, and the total resources consumed by the process in its
lifetime so far
The file table is an array of pointers to kernel file structures
o When making file I/O system calls, processes refer to files by their
index into this table, the file descriptor (fd)
Whereas the file table lists the existing open files, the
file-system context applies to requests to open new files
The current root and default directories to be used for new file searches are stored
here
The signal-handler table defines the routine in the processs address space to be
called when specific signals arrive
The virtual-memory context of a process describes the full contents of the its
private address space
Processes and Threads
Linux uses the same internal representation for processes and threads; a thread is
simply a new process that happens to share the same address space as its parent
o Both are called tasks by Linux
A distinction is only made when a new thread is created by the clone() system call
o fork() creates a new task with its own entirely new task context
o clone() creates a new task with its own identity, but that is allowed to share
the data structures of its parent
Using clone() gives an application fine-grained control over exactly what is shared
between two threads
Scheduling
The job of allocating CPU time to different tasks within an operating system
While scheduling is normally thought of as the running and interrupting of
processes, in Linux, scheduling also includes the running of the various kernel
tasks
6
Running kernel tasks encompasses both tasks that are requested by a running
process and tasks that execute internally on behalf of a device driver
As of 2.5, new scheduling algorithm preemptive, priority-based, known as O(1)
o Real-time range
o nice value
o Had challenges with interactive performance
2.6 introduced Completely Fair Scheduler (CFS)
CFS
Eliminates traditional, common idea of time slice
Instead all tasks allocated portion of processors time
CFS calculates how long a process should run as a function of total number of tasks
N runnable tasks means each gets 1/N of processors time
Then weights each task with its nice value
o Smaller nice value -> higher weight (higher priority)
Then each task run with for time proportional to tasks weight divided by total
weight of all runnable tasks
Configurable variable target latency is desired interval during which each task
should run at least once
o Consider simple case of 2 runnable tasks with equal weight and target
latency of 10ms each then runs for 5ms
If 10 runnable tasks, each runs for 1ms
Minimum granularity ensures each run has reasonable amount of
time (which actually violates fairness idea)
Kernel Synchronization
A request for kernel-mode execution can occur in two ways:
o A running program may request an operating system service, either
explicitly via a system call, or implicitly, for example, when a page fault
occurs
o A device driver may deliver a hardware interrupt that causes the CPU to
start executing a kernel-defined handler for that interrupt
Kernel synchronization requires a framework that will allow the kernels critical
sections to run without interruption by another critical section
Linux uses two techniques to protect critical sections:
1. Normal kernel code is non preemptible (until 2.6) when a time interrupt is received
while a process is executing a kernel system service routine, the kernels need_resched
flag is set so that the scheduler will run once the system call has completed and control
is about to be returned to user mode
7
2. The second technique applies to critical sections that occur in interrupt service
routines By using the processors interrupt control hardware to disable interrupts during
a critical section, the kernel guarantees that it can proceed without the risk of concurrent
access of shared data structures
o Provides spin locks, semaphores, and reader-writer versions of both
Behavior modified if on single processor or multi:
Each level may be interrupted by code running at a higher level, but will never be
interrupted by code running at the same or a lower level
User processes can always be preempted by another process when a time-sharing
scheduling interrupt occurs
Symmetric Multiprocessing
Linux 2.0 was the first Linux kernel to support SMP hardware; separate processes
or threads can execute in parallel on separate processors
Until version 2.2, to preserve the kernels nonpreemptible synchronization
requirements, SMP imposes the restriction, via a single kernel spinlock, that only
one processor at a time may execute kernel-mode code
8
Later releases implement more scalability by splitting single spinlock into
multiple locks, each protecting a small subset of kernel data structures
Version 3.0 adds even more fine-grained locking, processor affinity, and load-
balancing
Memory Management
Linuxs physical memory-management system deals with allocating and freeing
pages, groups of pages, and small blocks of memory
It has additional mechanisms for handling virtual memory, memory mapped into
the address space of running processes
Splits memory into four different zones due to hardware characteristics
o Architecture specific, for example on x86:
9
Splitting of Memory in a Buddy Heap
Virtual Memory
The VM system maintains the address space visible to each process: It creates
pages of virtual memory on demand, and manages the loading of those pages
from disk or their swapping back out to disk as required.
The VM manager maintains two separate views of a processs address space:
o A logical view describing instructions concerning the layout of the address
space
The address space consists of a set of non-overlapping regions, each
representing a continuous, page-aligned subset of the address space
o A physical view of each address space which is stored in the hardware page
tables for the process
Virtual memory regions are characterized by:
o The backing store, which describes from where the pages for a region come;
regions are usually backed by a file or by nothing (demand-zero
memory)
o The regions reaction to writes (page sharing or copy-on-write
The kernel creates a new virtual address space
When a process runs a new program with the exec() system call
Upon creation of a new process by the fork() system call
On executing a new program, the process is given a new, completely empty virtual-
address space; the program-loading routines populate the address space with
virtual-memory regions
10
Creating a new process with fork() involves creating a complete copy of the
existing processs virtual address space
o The kernel copies the parent processs VMA descriptors, then creates a new
set of page tables for the child
o The parents page tables are copied directly into the childs, with the
reference count of each page covered being incremented
o After the fork, the parent and child share the same physical pages of
memory in their address spaces
Swapping and Paging The VM paging system relocates pages of memory from
physical memory out to disk when the memory is needed for something else
The VM paging system can be divided into two sections:
o The pageout-policy algorithm decides which pages to write out to disk, and
when
o The paging mechanism actually carries out the transfer, and pages data back
into physical memory as needed
o Can page out to either swap device or normal files
o Bitmap used to track used blocks in swap space kept in physical memory
o Allocator uses next-fit algorithm to try to write contiguous runs
Kernel Virtual Memory
The Linux kernel reserves a constant, architecture-dependent region of the
virtual address space of every process for its own internal use
This kernel virtual-memory area contains two regions:
o A static area that contains page table references to every available
physical page of memory in the system, so that there is a simple
translation from physical to virtual addresses when running kernel
code
o The reminder of the reserved section is not reserved for any specific
purpose; its page-table entries can be modified to point to any other
areas of memory
Executing and Loading User Programs
Linux maintains a table of functions for loading programs; it gives each function
the opportunity to try loading the given file when an exec system call is made
The registration of multiple loader routines allows Linux to support both the ELF
and a.out binary formats
Initially, binary-file pages are mapped into virtual memory
o Only when a program tries to access a given page will a page fault result in
that page being loaded into physical memory
An ELF-format binary file consists of a header followed by several page-aligned
sections
11
o The ELF loader works by reading the header and mapping the sections of
the file into separate regions of virtual memory
12
The Linux VFS is designed around object-oriented principles and is composed of
four components:
o A set of definitions that define what a file object is allowed to look like
The inode object structure represent an individual file
The file object represents an open file
The superblock object represents an entire file system
A dentry object represents an individual directory entry
To the user, Linuxs file system appears as a hierarchical directory tree obeying
UNIX semantics
Internally, the kernel hides implementation details and manages the multiple
different file systems via an abstraction layer, that is, the virtual file system (VFS)
The Linux VFS is designed around object-oriented principles and layer of software
to manipulate those objects with a set of operations on the objects
o For example for the file object operations include (from struct
file_operations in /usr/include/linux/fs.h
int open(. . .) Open a file
ssize t read(. . .) Read from a file
ssize t write(. . .) Write to a file
int mmap(. . .) Memory-map a file
The Linux ext3 File System
ext3 is standard on disk file system for Linux
o Uses a mechanism similar to that of BSD Fast File System (FFS) for
locating data blocks belonging to a specific file
o Supersedes older extfs, ext2 file systems
o Work underway on ext4 adding features like extents
o Of course, many other file system choices with Linux distros
The main differences between ext2fs and FFS concern their disk allocation policies
o In ffs, the disk is allocated to files in blocks of 8Kb, with blocks being
subdivided into fragments of 1Kb to store small files or partially filled
blocks at the end of a file
o ext3 does not use fragments; it performs its allocations in smaller units
The default block size on ext3 varies as a function of total size of
file system with support for 1, 2, 4 and 8 KB blocks
o ext3 uses cluster allocation policies designed to place logically adjacent
blocks of a file into physically adjacent blocks on disk, so that it can
submit an I/O request for several disk blocks as a single operation on a
block group
o Maintains bit map of free blocks in a block group, searches for free byte to
allocate at least 8 blocks at a time
13
Ext2fs Block-Allocation Policies
Journaling
ext3 implements journaling, with file system updates first written to a log file in
the form of transactions
o Once in log file, considered committed
o Over time, log file transactions replayed over file system to put changes in
place
On system crash, some transactions might be in journal but not yet placed into file
system
o Must be completed once system recovers
o No other consistency checking is needed after a crash (much faster than
older methods)
Improves write performance on hard disks by turning random I/O into sequential
I/O
The Linux Proc File System
The proc file system does not store data, rather, its contents are computed on
demand according to user file I/O requests
proc must implement a directory structure, and the file contents within; it must
then define a unique and persistent inode number for each directory and files it
contains
o It uses this inode number to identify just what operation is required when a
user tries to read from a particular file inode or perform a lookup in a
particular directory inode
14
o When data is read from one of these files, proc collects the appropriate
information, formats it into text form and places it into the requesting
processs read buffer
Input and Output
The Linux device-oriented file system accesses disk storage through two caches:
o Data is cached in the page cache, which is unified with the virtual memory
system
o Metadata is cached in the buffer cache, a separate cache indexed by the
physical disk block
Linux splits all devices into three classes:
o block devices allow random access to completely independent, fixed size
blocks of data
o character devices include most other devices; they dont need to support
the functionality of regular files
o network devices are interfaced via the kernels networking subsystem
Block Devices
Provide the main interface to all disk devices in a system
The block buffer cache serves two main purposes:
o it acts as a pool of buffers for active I/O
o it serves as a cache for completed I/O
The request manager manages the reading and writing of buffer contents to and
from a block device driver
Kernel 2.6 introduced Completely Fair Queueing (CFQ)
o Now the default scheduler
o Fundamentally different from elevator algorithms
o Maintains set of lists, one for each process by default
o Uses C-SCAN algorithm, with round robin between all outstanding I/O
from all processes
o Four blocks from each process put on at once
15
Device-Driver Block Structure
Character Devices
A device driver which does not offer random access to fixed blocks of data
A character device driver must register a set of functions which implement the
drivers various file I/O operations
The kernel performs almost no preprocessing of a file read or write request to a
character device, but simply passes on the request to the device
The main exception to this rule is the special subset of character device drivers
which implement terminal devices, for which the kernel maintains a standard
interface
Line discipline is an interpreter for the information from the terminal device
o The most common line discipline is tty discipline, which glues the
terminals data stream onto standard input and output streams of users
running processes, allowing processes to communicate directly with the
users terminal
o Several processes may be running simultaneously, tty line discipline
responsible for attaching and detaching terminals input and output from
various processes connected to it as processes are suspended or awakened
by user
o Other line disciplines also are implemented have nothing to do with I/O to
user process i.e. PPP and SLIP networking protocols
Interprocess Communication
Like UNIX, Linux informs processes that an event has occurred via signals
There is a limited number of signals, and they cannot carry information: Only the
fact that a signal occurred is available to a process
The Linux kernel does not use signals to communicate with processes with are
running in kernel mode, rather, communication within the kernel is accomplished
via scheduling states and wait_queue structures
Also implements System V Unix semaphores
o Process can wait for a signal or a semaphore
16
o Semaphores scale better
o Operations on multiple semaphores can be atomic
17
o It has added a process characteristic that grants just a subset of the rights of
the effective uid
Linux provides another mechanism that allows a client to selectively pass access to
a single file to some server process without granting it any other privileges
Simpler hello.c
Lkmpg gives an example of the world's simplest LKM, hello-1.c. But it is not as
simple as it could be and depends on your having kernel messaging set up a certain way
on your system to see it work. Finally, the program requires you to include -D options on
your compile command to work, because it does not define some macros in the source
code, where the definitions belong.
/* hello.c
* "Hello, world" - the loadable kernel module version.
* Compile this with
* gcc -c hello.c -Wall
*/
/* Declare what kind of code we want from the header files */
#define __KERNEL__ /* We're part of the kernel */
#define MODULE /* Not a permanent part, though. */
18
/* Cleanup - undo whatever init_module did */
void cleanup_module()
{
console_print("Short is the life of an LKM\n");
}
The -I above assumes that you have the source code from which your base kernel
(the base kernel of the kernel into which you hope to load hello.c) was built in the
conventional spot, /usr/src/linux. If you're masochistic enough to be using symbol
versioning in your base kernel, then you better have run 'make dep' on that kernel source
too, because that's what builds the .ver files that change the names of all your symbols.
But note that it's reasonably common not to have the kernel headers installed
there, and often, the wrong headers are installed there. When you use a kernel that you
loaded from a distribution CD, you often have to separately load the headers for it. To be
safe, if you're playing with compiling LKMs, you really should compile your own kernel,
so you know exactly what you're working with and can be absolutely sure you're working
with matching header files.
The -nostdinc option isn't strictly necessary, but is the right thing to do. It will
keep you out of trouble and also remind you that the services of the standard C library,
which you may have melded in your mind with C itself, are not available to kernel
code. -nostdinc says not to include "standard" directories in the include file search path.
This means, most notably, /usr/include.
The -c option says you just want to create an object (.o) file, as opposed to gcc's
default which is to create the object file, then link it with a few other standard object files
to create something suitable for exec'ing in a user process. As you will not be exec'ing
this module but rather adding it to the kernel, that link phase would be entirely
inappropriate.
-Wall (which makes the compiler warn you about lots of kinds of questionable
code) is obviously not necessary, but this program should not generate any warnings. If it
does, you need to fix something.
Lkmpg contains fine instructions for building (compiling) an LKM (except that
the __KERNEL__ macro and usually the MODULE macro should be defined in the
19
source code instead of with -D compiler options as Lkmpg suggests). But it deserves
mention that some Linux kernel programmers believe that the only right way to build an
LKM is to add it to a copy of the complete Linux source tree and build it with the
existing Linux make files just like the LKMs that are part of Linux.
There are advantages to this. The biggest one is that when Linux programmers
change the way LKMs interface with the rest of the kernel in a way that affects how you
build an LKM, you're covered.
A kernel source tree to build against, and this might require a bit more explanation.
So let's do that.
This part's important so let's spend a couple minutes here. In order to compile a
kernel module, you need at least part of a kernel source tree against which to compile.
That's because when you write your module, all of the preprocessor #include statements
you use do not refer to your normal user space header files. Rather, they refer to
the kernel space header files found in the kernel source tree so, one way or another, you
have to have the relevant portion of some kernel tree available to build against.
While you can get fancy and download your own kernel source tree for this, a
simpler and easier solution (for now) is to install the official kernel development package
that matches your running kernel. That kernel development package normally installs,
under /usr/src/kernels, just enough of the source tree to contain the necessary header files
and build infrastructure, and little else. (In Fedora, this would be the kernel-devel
package. Under other distros, your mileage may vary, as they say.)
Finally, once that package is installed, you'll have to pass its directory location to
your build step. You can either make a note of the actual directory name, or you can take
advantage of the fact that it's normally available under the /lib/modules directory, by way
of a symlink. On this Fedora 11 system:
$ ls -l /lib/modules/`uname -r`
... build ->
20
../../../usr/src/kernels/2.6.29.4-167.fc11.x86_64
In other words, if that symlink exists, any time I need the location of the kernel
source tree corresponding to the currently running kernel, I can always use the expression
/lib/modules/`uname -r`/build, knowing it will keep up with any kernel upgrades. And
that's exactly what we're going to do.
And now that we have our building blocks in place, on to writing our first
module.
"Hello, Kernel!"
And without further ado, your first loadable module:
/* Module source file 'hi.c'. */
#include <linux/module.h> // for all modules
#include <linux/init.h> // for entry/exit macros
#include <linux/kernel.h> // for printk priority macros
#include <asm/current.h> // process information, just for fun
#include <linux/sched.h> // for "struct task_struct"
MODULE_AUTHOR("Robert P. J. Day");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("You have to start somewhere.");
Some notes about the above:
21
Technically, I didn't need to print anything upon module insertion or removal but,
without some feedback, loading and unloading that module would be stultifyingly
boring.
Always return zero from the init routine to signify a successful load.
Pick a valid license for your module, or you'll end up "tainting" the kernel--something
we'll get into in the next article.
No, there is no comma after the log level in a printk statement. That's a common
mistake. Don't make it.
So there's our first module. Let's build it.
The Makefile
Once again, let's get right at the Makefile we'll use to compile our module:
ifeq ($(KERNELRELEASE),)
build:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
else
22
MODPOST 1 modules
CC /home/rpjday/lf/1/hi.mod.o
LD [M] /home/rpjday/lf/1/hi.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.29.4-167.fc11.x86_64'
$ ls -l hi.ko
-rw-rw-r--. 1 rpjday rpjday 126716 2009-06-24 19:18 hi.ko
$
And there it is--our loadable module hi.ko, ready to be loaded. But what was that
Makefile all about?
To make a long story very short, that's a two-part Makefile. When you run make
to compile your module, the Makefile immediately realizes that you're still in your source
directory, at which point the make wanders off to the kernel source tree that you've
identified, where it finds all of the necessary build infrastructure and kernel headers and
so on, which it then uses to come back to compile your module.
We might come back some day and take a closer look at that. For now, take my
word for it. If you got a hi.ko module out of it, you're good. And we're almost done here.
But first ...
Poking at that Module
If you want to examine your newly-built module while it's just sitting there, no
sweat--there's the modinfo command:
$ modinfo hi.ko
filename: hi.ko
description: You have to start somewhere.
license: Dual BSD/GPL
author: Robert P. J. Day
srcversion: 658D8123B9EE52CF16981C4
depends:
vermagic: 2.6.29.4-167.fc11.x86_64 SMP mod_unload
Which, mercifully, brings us to...
Loading and Unloading the Module
And assuming you managed to score root privilege, away we go:
# insmod hi.ko
# lsmod
Module Size Used by
hi 1792 0 <--- oh, look!
... snip ...
# rmmod hi
#
But where did all your printk output go? Kernel programming rule one: you don't
normally interact with user space, so don't expect to see print output coming back to your
23
terminal. Instead, our output would have been directed to the standard syslog messages
log file (in our case, /var/log/messages), so if we'd been keeping an eye on that file we
would have seen:
Jun 24 19:33:01 localhost kernel: hi module being loaded.
Jun 24 19:33:01 localhost kernel: User space process is 'insmod'
Jun 24 19:33:01 localhost kernel: User space PID is 15359
Jun 24 19:33:03 localhost kernel: hi module being unloaded.
Suppose we want to add some extra functionality in the Linux kernel.So the first
idea that strikes the mind is to enhance the kernel by adding more code to it, compiling
the code and getting the new kernel up. But this process has the following drawbacks
among several others:
The added code adds to the size of kernel permanently.
The whole kernel needs to be compiled again for the changes to get compiled.
This means that machine needs to be rebooted for changes to take affect.
The solution to above problems is the concept of LKMs.
LKM stands for Loadable kernel modules (LKM). As the name suggests LKMs
are the modules that can be directly loaded in kernel at run time.
The loadable kernel module overcomes all the above mentioned shortcomings.
The module can be compiled separately
The module can be loaded onto kernel at run time without having the machine to
reboot.
The module can be unloaded anytime and hence no permanent affect on kernel size.
24
How to Create LKMs
25
make: Leaving directory `/usr/src/linux-headers-2.6.32-21-generic'
After the above successful compilation you will find a .ko file in the same
directory where the compilation took place. This .ko file is the module that will be loaded
in the kernel. modinfo utility can be used to fetch the information about this module :
$ modinfo lkm.ko
filename: lkm.ko
srcversion: 19967CB3EAB7B31E643E006
depends:
vermagic: 2.6.32.11+drm33.2 SMP mod_unload modversions
So we see that the utility modinfo provides some information about this module.
So modprobe is a better utility but since our module is not dependent on any
other module so we will use insmod only. So, to insert the module, the following
command is used :
$ sudo insmod ./lkm.ko
if this command does not give any error then that means the LKM is loaded
successfully in the kernel. To unload the LKM, the following command is used :
$ sudo rmmod lkm.ko
Again, if this command does not give any error then that means the LKM is un-
loaded successfully in the kernel. To check that the module was loaded and unloaded
correctly we can use the dmesg utilitywhich gives the last set of logs as logged by the
kernel. Youll see the following two lines among all the other logs :
....
....
[ 4048.333756] Welcome.....
[ 4084.205143] Bye....
26
If you go back to the code and see then you will realize that these are the logs
from the two functions in the code. So we see that one function was called when the
insmod was called and the other function was called when the rmmod was called.This
was just a dummy LKM. In this way many working LKM (that carry out meaningful
tasks) work inside Linux kernel.
RESULT:
Thus the case study has been analyzed and built a loadable module.
27
DATE:
EX.NO:
CASE STUDY 2: MINIX 3
Agenda
Introduction
Minix 3 Features
Design Goals
Minix 3 Architecture
Minix 3 Drivers and Servers
Reliability and security
Installation
Conclusion
References
Introduction
MINIX 3 Features
POSIX compliant, Networking with TCP/IP
X Window System, Languages: cc, gcc, g++, perl, python, etc.
Over 650 UNIX programs, Many improvements since V2
Full multiuser and multiprogramming, Device drivers run as user processes
High degree of fault tolerance, Full C source code supplied
28
Design Goals
The approach that MINIX 3 uses to achieve high reliability is fault isolation. In
particular, unlike traditional OSes, where all the code is linked into a single huge binary
running in kernel mode, in MINIX 3, only a tiny bit of code runs in kernel mode--about
4000 lines in all (Minix 2). This code handles interrupts, process scheduling, and
interprocess communication. The rest of the operating system runs as a collection of user-
mode processes, each one encapsulated by the MMU hardware and none of them running
as superuser. One of these processes, dubbed thereincarnation server, keeps tabs on all
the others and when one of them begins acting sick or crashes, it automatically replaces it
by a fresh version. Since many bugs are transient, triggered by unusual timing, in most
cases, restarting the faulty component solves the problem and allows the system to repair
itself without a reboot and without the user even noticing it. This property is called self
healing, and traditional systems do not have it.
Minix 3 Architecture
29
Although from the kernels point of view the server and driver processes are
also just user-mode processes, logically they can be structured into three layers. The
lowest level of user-mode processes are the device drivers, each one control-ling some
device. Drivers for IDE, floppy, and RAM disks, etc. Above the driver layer are the
server processes. These include the VFS server, underlying file sys-tem
implementations, process server, reincarnation server, and others. On top of the servers
come the ordinary user processes including shells, compilers, utilities, and application
programs. Figure 1.1 shows the structure of the operating system.
Because the default mode of interprocess communication (IPC) are synchronous calls,
deadlocks can occur when two or more processes simultaneously try to communicate and
all processes are blocked waiting for one another. Therefore, a deadlock avoidance
protocol has been carefully devised that prescribes a partial, top-down message ordering.
The message ordering roughly follows the layering that is described above. Deadlock
detection is also implemented in the kernel. If a process unexpectedly were to cause a
deadlock, the offending is denied and an error message is returned to the caller.
30
sources) requires 8 MB RAM and 50 MB of disk space. Serial ATA, USB, and SCSI
disks are not supported at present. For USB CD-ROMS, see the Website:
www.minix3.org.
A.1 PREPARATION
If you already have the CD-ROM (e.g., from the book), you can skip steps 1 and
2, but it is wise to check www.minix3.org to see if a newer version is avail-able. If you
want to run MINIX 3 on a simulator instead of native, see Part V first. If you do not have
an IDE CD-ROM, either get the special USB CD-ROM boot image or use a simulator.
Windows 2000:Start > Settings > Control Panel > System > Hardware > Device
Manager Windows XP: Start > Control Panel > System > Hardware > Device Manager
System requires double clicking; the rest are single. Expand the + next to Net-
work adapters to see what you have. Write it down. If you do not have a sup-ported
31
chip, you can still run MINIX 3, but without Ethernet.
You can boot the computer from your CD-ROM if you like and MINIX 3 will
start, but to do anything useful, you have to create a partition for it on your hard disk. But
before partitioning, be sure to back up your data to an external med-ium like CD-
ROM or DVD as a safety precaution, just in case something goes wrong. Your files are
valuable; protect them.
Unless you are sure you are an expert on disk partitioning with much experi-ence,
it is strongly suggested that you read the online tutorial on disk partitioning at
www.minix3.org/doc/partitions.html. If you already know how to manage par-titions,
create a contiguous chunk of free disk space of at least 50 MB, or, if you want all the
commands sources, 1 GB. If you do not know how to manage parti-tions but have a
partitioning program like Partition Magic, use it to create a region of free disk space.
Also make sure there is at least one primary partition (i.e., Master Boot Record slot) free.
The MINIX 3 setup script will guide you through creating a MINIX partition in the free
space, which can be on either the first or second IDE disk.
If you are running Windows 95, 98, ME, or 2000 and your disk consists of a
single FAT partition, you can use the presz134.exe program on the CD-ROM (also
available at zeleps.com) to reduce its size to leave room for MINIX. In all other cases,
please read the online tutorial cited above.
If your disk is larger than 128 GB, the MINIX 3 partition must fall entirely in the
first 128 GB (due to the way disk blocks are addressed).
WARNING: If you make a mistake during disk partitioning, you can lose all
the data on the disk, so be sure to back it up to CD-ROM or DVD before starting.
Disk partitioning requires great care, so proceed with caution.
A.2 BOOTING
By now you should have allocated some free space on your disk. If you have not
done so yet, please do it now unless there is an existing partition you are wil-ling to
convert to MINIX 3.
32
and enter the BIOS setup program to change the order of boot devices, putting the CD-
ROM before the hard disk.
2. Login as root
When the login prompt appears, login as root. After a successful login as root,
you will see the shell prompt (#). At this point you are running fully-operational MINIX
3. If you type:
ls /usr/bin | more
you can see what software is available. Hit space to scroll the list. To see what
program foo does, type:
man foo
The manual pages are also available at www.minix3.org/manpages.
After this and all other commands, be sure to type ENTER (RETURN). When the
installation script ends a screen with a colon, hit ENTER to continue. If the screen
suddenly goes blank, press CTRL-F3 to select software scrolling (should only be needed
on very old computers). Note that CTRL-key means depress the CTRL key and while
holding it down, press key.
33
GB or more, choose F for a full installation.
For choices (1) and (2), type the region number. For (3) type
Delete
then give the region number when asked. This region will be overwritten and its previous
contents lost forever.
You have now reached the point of no return. You will be asked if you want to
continue. If you do, the data in the selected region will be lost forever. If you are sure,
type:
yes
and then ENTER. To exit the setup script without changing the partition table, hit
CTRL-C.
5. Reinstall choice
If you chose an existing MINIX 3 partition, in this step you will be offered a
choice between a Full install, which erases everything in the partition, and a Rein-stall,
which does not affect your existing /home partition. This design means that you can put
34
your personal files on /home and reinstall a newer version of MINIX 3 when it is
available without losing your personal files.
shutdown
Always stop MINIX 3 this way to avoid data loss as MINIX 3 keeps some files on
the RAM disk and only copies them back to the hard disk at shutdown time.
35
all the binaries and sources, or select the packages you want. When you have finished
installing packages, exit packman by choosing option 5. If you have installed the X
Windows package, you can start it now by typing
xdm
A.4 TESTING
This section tells you how to test your installation, rebuild the system after
modifying it, and boot it later. To start, boot your new MINIX 3 system. For example, if
you used controller 0, disk 0, partition 3, type
boot c0d0p3
and log in as root. Under very rare conditions the drive number seen by the BIOS (and
used by the boot monitor) may not agree with the one used by MINIX 3. Try the one
announced by the setup script first. This is a good time to create a root password. See
man passwd for help.
to run the test programs. They should all run correctly but they can take 20 min on a fast
machine and over an hour on a slow one. Note: It is necessary to compile the test suite
when running as root but execute it as bin in order to see if the setuid bit works correctly.
36
You just rebuilt the operating system, including all the kernel and user-mode parts. That
did not take very long, did it? If you have a legacy floppy disk drive, you can make a
bootable floppy for use later by inserting a formatted floppy and typing
make fdboot
This approach does not currently work with USB floppies since there is no MINIX 3
USB floppy disk driver yet. To update the boot image currently installed on the hard disk,
type
make hdboot
5. Booting Tomorrow
If you have a legacy floppy disk drive, the simplest way to boot MINIX 3 is by
inserting your new boot floppy and turning on the power. It takes only a few seconds.
Alternatively, boot from the MINIX 3 CD-ROM, login as bin and type:
shutdown
boot c0d0p0
to boot from the operating system image file on controller 0, driver 0, partition 0. Of
course, if you put MINIX 3 on drive 0 partition 1, use:
boot c0d0p1
and so on.
37
A third possibility for booting is to make the MINIX 3 partition the active one, and
use the MINIX 3 boot monitor to start MINIX 3 or any other operating system. For
details see www.minix3.org/manpages/man8/boot.8.html.
Finally, a fourth option is for you to install a multiboot loader such as LILO or GRUB
(www.gnu.org/software/grub). Then you can boot any of your operating systems easily.
Discussion of multiboot loaders is beyond the scope of this guide, but there is some
information on the subject at www.minix3.org/doc.
d VMware (www.vmware.com)
d Bochs (www.bochs.org)
d QEMU (www.qemu.org)
See the documentation for each of them. Running a program on a simulator is similar to
running it on the actual machine, so you should go back to Part I and acquire the latest
CD-ROM and continue from there.
38
Keeps track of free and used pages
Catches and handles page faults
o Data store
Small local name server
Used to map server name to end point
Could be used for recoverable drivers
o Information server
Used for debug dumps
o Network server
Contains full TCP/IP stack in user space (Interesting huh? :-D)
o X server
o Reincarnation server
Parent of all drivers and servers
Whenever a server/driver dies the RS collects it
RS checks a table for action to take e.g., Restart it
RS also ping drivers and servers frequently
39
Restricted power to do damage (not superuser)
Conclusion
1. Introduction
In Minix3, the servers handle system calls. Adding a new system call consists of
two steps: writing a system- call handler and writing a user library. System-call handler is
a function that is called in response to a user requesting a system call. Each system call
has one handler. A user library packages the parameters for the system call and calls the
handler on the appropriate server. A user always invokes a system call using the library.
This document illustrates the method for adding a new system call for Minix3
using an example. We would implement a system-call handler do_printmessage() in the
FS server that would simply print a message I am a system call. However, the method
described could be used for adding the handler to any server. We would also add a user-
library to call the handler.
40
2. Creating a System-call Handler
The source code for all servers are located at /usr/src/servers. Each server has a
separate directory. Filesystem (FS) is located at /usr/src/servers/fs. Each of the server
source directories contain two files: table.c and proto.h. Table.c contains definition for
the call_vec table. The call_vec table is an array of function pointers that is indexed by
the system-call number. In each line, the address of a system-call handler function is
assigned to one entry in the table and the index of the entry is the system-call number.
There are a few unused entries. For adding a new system call, we need to identify
41
one unused entry. For instance, index 69 contains an unused entry. We could use slot
number 69 for our system-call handler do_printmessage(). To use entry 69, we replace
no_sys with do_printmessage().
do_revive, /* 67 = REVIVE*/
no_sys, /* 68 TASK_REPLY*/
do_printmessage(), /* 69 = unused */
no_sys, /* 70 = unused */
no_sys, /* 71 = si */
/* open.c */
_PROTOTYPE( int do_close, (void) );
_PROTOTYPE( int do_creat, (void) );
_PROTOTYPE( int do_lseek, (void) );
_PROTOTYPE( int do_mknod, (void) );
_PROTOTYPE( int do_mkdir, (void) );
_PROTOTYPE( int do_open, (void) );
Figure 4: /usr/src/servers/fs/proto.h
Int do_printmessage()
{
printf(\I am a system
call \n); return (OK);
}
A few files like misc.c, stadir.c, write.c, and read.c contain the definitions for the
system-call handler functions. We could either add our system-call handler to one of
these files or have it in a separate file. If we choose to add it in a separate file, we have to
make changes in the /usr/src/servers/fs/Makefile accordingly. For our example, we will
add the definition of function do_printmessage() to /usr/src/servers/fs/misc.c. After
42
implementing the system-call handler, we can compile the FS server to ensure that our
new system-call handler does not contain any errors.
Our system-call handler function do_printmessage() has the system-call number 69.
We could call the system-handler function directly using the system call _syscall.
_syscall takes three parameters: the recipient process, system-call number, and pointer to
a message structure.
In our example, the recipient process is FS, the system-call number is 69, and we do
not pass any parameters. Still, we should pass a pointer to an empty message for the third
parameter when calling the handler function. We call the handler as show below.
message m;
_syscall(FS,69,&m)
;
When the system-call handler needs to receive some parameters, we pass the
parameters using the message structure. The message structure is described in figure 6.
To use the message structure, the header file lib.h should be used. The header file
contains some #defines that makes using the message structure simple.
typedef struct {int m1i1, m1i2, m1i3; char *m1p1, *m1p2, *m1p3;} mess_1;
typedef struct {int m2i1, m2i2, m2i3; long m2l1, m2l2;
char *m2p1;} mess_2; typedef struct {int m3i1, m3i2;
char *m3p1; char m3ca1[M3_STRING];} mess_3;
typedef struct {long m4l1, m4l2, m4l3, m4l4, m4l5;} mess_4;
typedef struct {short m5c1, m5c2;
int m5i1, m5i2; long m5l1, m5l2, m5l3;}mess_5;
typedef struct {int m7i1, m7i2, m7i3, m7i4; char *m7p1, *m7p2;} mess_7;
typedef struct {int m8i1, m8i2; char *m8p1, *m8p2, *m8p3, *m8p4;} mess_8;
typedef struct {
int m_source; /* who sent the message */
43
int m_type; /* what kind of message is it */
union {
mess_1 m_m1;
mess_2 m_m2;
mess_3 m_m3;
mess_4 m_m4;
mess_5 m_m5;
mess_7 m_m7;
mess_8 m_m8;
} m_u;
} message;
/* The following defines provide names for
useful members. */ #define m1_i1
m_u.m_m1.m1i1
#define m1_i2 m_u.m_m1.m1i2
#define m1_i3 m_u.m_m1.m1i3
#define m1_p1 m_u.m_m1.m1p1
#define m1_p2 m_u.m_m1.m1p2
#define m1_p3 m_u.m_m1.m1p3
#define m2_i1 m_u.m_m2.m2i1
#define m2_i2 m_u.m_m2.m2i2
#define m2_i3 m_u.m_m2.m2i3
#define m2_l1 m_u.m_m2.m2l1
#define m2_l2 m_u.m_m2.m2l2
#define m2_p1 m_u.m_m2.m2p1
#define m3_i1 m_u.m_m3.m3i1
#define m3_i2 m_u.m_m3.m3i2
#define m3_p1 m_u.m_m3.m3p1
#define m3_ca1 m_u.m_m3.m3ca1
#define m4_l1 m_u.m_m4.m4l1
#define m4_l2 m_u.m_m4.m4l2
#define m4_l3 m_u.m_m4.m4l3
#define m4_l4 m_u.m_m4.m4l4
#define m4_l5 m_u.m_m4.m4l5
#define m5_c1 m_u.m_m5.m5c1
#define m5_c2 m_u.m_m5.m5c2
#define m5_i1 m_u.m_m5.m5i1
#define m5_i2 m_u.m_m5.m5i2
Message structure
44
parameters. The system-call number of do_managecap is 58. We need to initialize the
three parameters in the message structure, and call the system call handler using the
message structure as shown in figure 7.
message m;
m.m1_i1=45;
m.m1_i2=55;
m.m1_i3=65;
_syscall(FS,58,&m);
The FS server has a global variable named m_in, which is a message structure.
Whenever a system-call arrives at the FS server, m_in would contain the message
structure pointed to by the third parameter in the call. We retrieve the three parameters
from the m_in message structure in the system-call handler function.
A user library function would package the parameters for the system-call handler in the
message structure and would call the handler function. First, we should use #define to
map the system-call number of the handler function to an identifier in the file
/usr/src/include/minix/callnr.h and /usr/include/minix/callnr.h.
#define PRINTMESSAGE 69
We implement the library function for the do_printmessage system call in a separate
file named _printmessage.c. This file should be placed in the directory
/usr/src/lib/posix/.
45
#include
<lib.h>
#include
<unistd.h>
3.1. Creating a New Boot-Image Using the Updated Servers and Library
We already compiled and created the binaries for the servers, and now we have the fresh
libraries compiled and installed. Now, we need to merge them the updated binaries and
create a new boot image.
These steps would create a new boot -image in the directory /boot/image/. Note down the
name of the new boot-image. When we shutdown and reboot, we should select the new
boot-image.
In the boot prompt, we could setup the new image for booting using the command image
=/boot/image/<name of boot-image>. Then we could issue the command boot to startup
using the new boot-image.
46
4. Using the New System Call
#include <stdio.h>
int main()
{
printmessage();
}
RESULT:
Thus the Study of educational operating systems such as Minix and Weenix has
been done and developed a reasonably sized interesting modules for them
47
DATE:
EX.NO:
CASESTUDY 3: ANDROID
Andoid:
The user interface of Android is based on direct manipulation, using touch inputs
that loosely correspond to real-world actions, like swiping, tapping, pinching and reverse
pinching to manipulate on-screen objects. Internal hardware .
eg: accelerometers, gyroscopes and proximity sensors are used by some applications to
respond to additional user actions.
For example adjusting the screen from portrait to landscape depending on how the
device is oriented. Android allows users to customize their home screens with shortcuts
to applications and widgets, which allow users to display live content, such as emails and
weather information, directly on the home screen. Applications can further send
notifications to the user to inform them of relevant information, such as new emails and
text messages.
1.3%
2.2 Froyo May 20, 2010 8
48
History:
49
2011-01-26: Gingerbread-x86 branch is ready to download.
2011-01-13: Android-x86 2.2 is released.
2011-01-01: Test build 20110101 is released.
Operating System
Middleware
Key mobile applications
Open
Breaking down Application Boundaries
Fast & Easy Application Development
50
Surface Manager for composing window manager with off-screen
buffering
Core Libraries
Dalvik VM
Important blocks:
51
Intents
Intent = asynchronous message w/ or w/o designated target
Like a polymorphic Unix signal, but w/o required target
Intents payload held in Intent Object
Intent Filters specified in Manifest file
Components
1 App = N Components
Apps can use components of other applications
App processes are automagically started whenever any part is needed
Ergo: N entry points, !1, and !main()
Components:
Activities
Services
Broadcast Receivers
Content Providers
52
Component lifecycle
System automagically starts/stops/kills processes:
Entire system behaviour predicated on low memory
System triggers Lifecycle callbacks when relevant
Ergo: Must manage Component Lifecycle
Some Components are more complex to manage than others
Development tools
SDK:
android manage AVDs and SDK components
apkbuilder creating .apk packages
dx converting .jar to .dex
adb debug bridge
emulator QEMU-based ARM emulator
Eclipse w/ ADT plugin
NDK: GNU toolchain for native binaries
System Server
Entropy Service Device Policy Audio Service
Power Manager Status Bar Headset Observer
Activity Manager Clipboard Service Dock Observer
Telephone Registry Input Method Service UI Mode Manager Service
Package Manager Backup Service
Account Manager
Content Manager Connectivity Service Recognition Service
System Content Providers Throttle Service Status Bar Icons
Battery Service Accessibility Manager
Lights Service Mount Service ADB Settings Observer
Vibrator Service Notification Manager
Alarm Manager Device Storage Monitor
Location Manager
Sensor Service Search Service
Window Manager
Wallpaper Service
NetStat Service
NetworkManagement Service AppWidget Service
DiskStats Service
Init Watchdog
DropBox Service
Bluetooth Service
53
ActivityManager
Start new Activities, Services
Fetch Content Providers
Intent broadcasting
OOM adj. maintenance
Application Not Responding
Permissions
Task management
Lifecycle management
Java Native Interface(JNI)
JNI defines naming and coding convention so that Java VM can find and call
native code.
JNI is built into JVM to provide access to OS I/O and others.
Zygote
Android at its core has a process they call the Zygote, which starts up at init. It
gets it's name from dictionary definition: "It is the initial cell formed when a
new organism is produced". This process is a Warmed-up process, which means its a
process thats been initialized and has all the core libraries linked in. When you start an
application, the Zygote is forked.
54
Stock AOSP Apps
/packages/apps /packages/providers
Launcher2
Music
Browser
Calculator
Calendar Provision
Camera
Settings
Contacts
Email
Gallery
/packages/inputmethods
AccountsAndSettings ApplicationProvider LatinIME
AlarmClock Mms CalendarProvider OpenWnn
Bluetooth ContactsProvider PinyinIME
PackageInstaller DownloadProvider
Protips DrmProvider
GoogleContactsProvider
QuickSearchBox MediaProvider
CertInstaller TelephonyProvider
SoundRecorder UserDictionaryProvider
DeskClock SpeechRecorder
Stk
VoiceDialer
HTMLViewer
55
Creating an Android Project
An Android project contains all the files that comprise the source code for your
Android app. The Android SDK tools make it easy to start a new Android project with a
set of default project directories and files.
2. In the window that appears, open the Android folder, select Android
Application Project, and click Next.
56
"com.example.myfirstapp." However, you cannot publish your app on Google Play
using the "com.example" namespace.
o Minimum Required SDK is the lowest version of Android that your app
supports, indicated using the API level. To support as many devices as possible, you
should set this to the lowest version available that allows your app to provide its
core feature set. If any feature of your app is possible only on newer versions of
Android and it's not critical to the app's core feature set, you can enable the feature
only when running on the versions that support it (as discussed in Supporting
Different Platform Versions). Leave this set to the default value for this project.
o Target SDK indicates the highest version of Android (also using the API
level) with which you have tested with your application.
As new versions of Android become available, you should test your app on the new
version and update this value to match the latest API level in order to take
advantage of new platform features.
o Compile With is the platform version against which you will compile
your app. By default, this is set to the latest version of Android available in your
SDK. (It should be Android 4.1 or greater; if you don't have such a version
available, you must install one using the SDK Manager). You can still build your
app to support older versions, but setting the build target to the latest version allows
you to enable new features and optimize your app for a great user experience on the
latest devices.
o Theme specifies the Android UI style to apply for your app. You can
leave this alone.
Click Next.
4. On the next screen to configure the project, leave the default selections and
click Next.
5. The next screen can help you create a launcher icon for your app.
You can customize an icon in several ways and the tool generates an icon for all
screen densities. Before you publish your app, you should be sure your icon meets the
specifications defined in the Iconography design guide.
Click Next.
6. Now you can select an activity template from which to begin building your app.
For this project, select BlankActivity and click Next.
7. Leave all the details for the activity in their default state and click Finish.
If you're not using the Eclipse IDE with the ADT plugin, you can instead create your
project using the SDK tools from a command line:
57
2. Execute:
android list targets
This prints a list of the available Android platforms that youve downloaded for your
SDK. Find the platform against which you want to compile your app. Make a note of
the target id. We recommend that you select the highest version possible. You can still
build your app to support older versions, but setting the build target to the latest
version allows you to optimize your app for the latest devices.
If you don't see any targets listed, you need to install some using the Android SDK
Manager tool. See Adding Platforms and Packages.
3. Execute:
android create project --target <target-id> --name MyFirstApp \
--path <path-to-workspace>/MyFirstApp --activity MainActivity \
--package com.example.myfirstapp
Replace <target-id> with an id from the list of targets (from the previous step) and
replace <path-to-workspace> with the location in which you want to save your
Android projects.
Tip: Add the platform-tools/ as well as the tools/ directory to your PATH environment
variable.
How you run your app depends on two things: whether you have a real Android-
powered device and whether you're using Eclipse. This lesson shows you how to install
and run your app on a real device and on the Android emulator, and in both cases with
either Eclipse or the command line tools.
Before you run your app, you should be aware of a few directories and files in the
Android project:
AndroidManifest.xml
The manifest file describes the fundamental characteristics of the app and defines each
of its components. You'll learn about various declarations in this file as you read more
training classes.
One of the most important elements your manifest should include is the <uses-
sdk> element. This declares your app's compatibility with different Android versions
using the android:minSdkVersion andandroid:targetSdkVersion attributes. For your
first app, it should look like this:
58
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17"
/>
...
</manifest>
You should always set the android:targetSdkVersion as high as possible and test your
app on the corresponding platform version. For more information, read Supporting
Different Platform Versions.
src/
Directory for your app's main source files. By default, it includes an Activity class that
runs when your app is launched using the app icon.
res/
Contains several sub-directories for app resources. Here are just a few:
drawable-hdpi/
Directory for drawable objects (such as bitmaps) that are designed for high-density
(hdpi) screens. Other drawable directories contain assets designed for other screen
densities.
layout/
Directory for files that define your app's user interface.
values/
Directory for other various XML files that contain a collection of resources, such
as string and color definitions.
When you build and run the default Android app, the default Activity class starts
and loads a layout file that says "Hello World." The result is nothing exciting, but it's
important that you understand how to run your app before you start developing.
If you have a real Android-powered device, here's how you can install and run your app:
1. Plug in your device to your development machine with a USB cable. If you're
developing on Windows, you might need to install the appropriate USB driver
for your device. For help installing drivers, see the OEM USB Drivers document.
2. Enable USB debugging on your device.
o On most devices running Android 3.2 or older, you can find the option under Settings
> Applications > Development.
o On Android 4.0 and newer, it's in Settings > Developer options.
59
Note: On Android 4.2 and newer, Developer options is hidden by default. To make it
available, go toSettings > About phone and tap Build number seven times. Return to the
previous screen to findDeveloper options.
To run the app from Eclipse:
1. Open one of your project's files and click Run from the toolbar.
2. In the Run as window that appears, select Android Application and
click OK.
Eclipse installs the app on your connected device and starts it.
To create an AVD:
60
2. In the Android Virtual Device Manager panel, click New.
3. Fill in the details for the AVD. Give it a name, a platform target, an SD
card size, and a skin (HVGA is default).
4. Click Create AVD.
5. Select the new AVD from the Android Virtual Device Manager and
click Start.
6. After the emulator boots up, unlock the emulator screen.
1. Open one of your project's files and click Run from the toolbar.
2. In the Run as window that appears, select Android Application and
click OK.
Eclipse installs the app on your AVD and starts it.
Example Project:
Android Google Maps Tutorial
The Android platform provides easy and tight integration between Android
applications and Google Maps. The well established Google Maps APIis used under the
hood in order to bring the power of Google Maps to your Android applications. In this
tutorial we will see how to incorporate Google Maps into an Android app.Installing the
Google APIs
In order to be able to use Google Maps, the Google APIs have to be present in
your SDK. In case the Google APIs are not already installed, you will have to manually
install them. This is accomplished by using the Android SDK and AVD Manager.
Launch the manager and choose the Installed Options section to see what is
already installed and the Available Packages to download the additional APIs.
61
You can find more information about this procedure in the following links:
Adding SDK Components
Installing the Google APIs Add-On
Now that the appropriate tools are installed, lets proceed with creating a new
Android project in Eclipse. The project I created is named AndroidGoogleMapsProject
and has the following configuration:
It is important to use the Google APIs as the target since this option includes
the Google extensions that allow you to use Google Maps. Return to the first step of this
tutorial if no such option is available in your configuration. I chose the 1.5 version of the
platform since we will not be using any of the latest fancy API stuff.
As you might know if you have used the Google Maps API in the past, a key is
required in order to be able to use the API. The process is slightly different for use in
Android applications, so lets see what is required to do.
First, we have to calculate the MD5 fingerprint of the certificate that we will use
to sign the final application. This fingerprint will have to be provided to the Google Maps
API service so that it can associate the key with your application. Javas Key and
Certificate Management tool named keytool is used for the fingerprint generation.
62
MD5 fingerprint of the debug certificate we first need to locate the debug keystore. The
location of the keystore varies by platform:
Windows Vista: C:\Users\\.android\debug.keystore
Windows XP: C:\Documents and Settings\\.android\debug.keystore
OS X and Linux: ~/.android/debug.keystore
Now that we have located the keystore, we use the keytool executable to get the MD5
fingerprint of the debug certificate by issuing the following command:
Note that this was executed against the debug keystore, you will have to repeat
this for the keystore that will be used with the application you are going to create.
Additionally, the application is run on another development environment, with different
Android SDK keystore, the API key will be invalid and Google Maps will not work.
This the fingerprint we have to provide to the Google Maps service. Now we are ready to
sign up for a key by visiting the Android Maps API Key Signup page. After we read and
accept the terms and conditions, we provide the generated fingerprint as follows:
We generate the API key and we are presented with the following screen:
63
Creating the Google Maps application
Finally, its time to write some code. Bookmark the Google APIs Add-On
Javadocs for future reference. Integrating Google Maps is quite straightforward and can
be achieved by extending the MapActivity class instead of the Activity class that we
usually do. The main work is performed by a MapView which displays a map with data
obtained from the Google Maps service. A MapActivity is actually a base class with
code to manage the boring necessities of any activity that displays a MapView. Activity
responsibilities include:
Activity lifecycle management and Setup and teardown of services behind
a MapView
In our map activity, we will just take reference of a MapView. This view will be
defined in the layout XML. We will also use thesetBuiltInZoomControls method to
enable the built-in zoom controls.
64
Lets see how our activity looks like so far:
Do not forget to provide your API key in the relevant field or else Google Maps will not
work.
To test the application we will have to use a device that includes the Google APIs.
We will use the AVD manager to create a new device with target set to one of the Google
APIs and settings like the following:
If we now launch the Eclipse configuration, we will encounter the following exception:
65
java.lang.ClassNotFoundException:
com.javacodegeeks.android.googlemaps.GMapsActivity in loader
dalvik.system.PathClassLoader@435988d0
The problem is that we havent notified Android that we wish to use the add-on Google
APIs which are external to the base API. To do so, we have to use the uses-
library element in our Android manifest file, informing Android that we are going to use
classes from the com.google.android.maps package.
66
If you click inside the map, the zoom controls will appear and you will be able to zoom in
and out.
The next step is to add some custom map overlays. To do so, we can extend
the Overlay class, which is a base class representing an overlay which may be displayed
on top of a map. Alternatively, we may extend the ItemizedOverlay, which is a base class
for an Overlaywhich consists of a list of OverlayItems. Lets see how we can do this
(note that the following example is very similar to the Hello Map Viewarticle from the
Android documentation):
67
Our class requires an Android Drawable in its constructor, which will be used as a
marker. Additionally, the current Context has to be provided. We use an ArrayList to
store all the OverlayItems stored in the specific class, so the createItem and size methods
are pretty much self-explanatory. The onTap method is called when an item is tapped
and that could be from a touchscreen tap on an onscreen Item, or from a trackball click on
a centered, selected Item. In that method, we just create an AlertDialog and show it to the
user. Finally, in the exposed addOverlay method, we add the OverlayItem and invoke
the populate method, which is a utility method to perform all processing on a
new ItemizedOverlay.
Lets see how this class can be utilized from our map activity:
68
We create a new instance of our CustomItemizedOverlay class by using the
default Android icon as the Drawable. Then we create aGeoPoint pointing to a predefined
location and use that to generate an OverlayItem object. We add the overlay item to our
CustomItemizedOverlay class and it magically appears in our map on the predefined
point.
Finally, we take reference of the underlying MapController and use it to point the
map to a specific geographical point using theanimateTo method and to define the zoom
level by using the setZoom method.
69
If we launch again the configuration, we will be presented with a zoomed-in map
which includes an overlay marker pointing toJavaCodeGeeks home town Athens, Greece.
Clicking on the marker will cause the alert dialog to pop-up displaying our custom
message.
RESULT:
Thus the Study the Android open source operating system for mobile devices has
been done and developed a module.
70
DATE:
EX.NO:
CASE STUDY 4 :eCos
eCos:
eCos is provided as an open source runtime system supported by the GNU open
source development tools. Developers have full and unfettered access to all aspects of the
runtime system. No parts of it are proprietary or hidden, and you are at liberty to
examine, add to, and modify the code as you deem necessary. These rights are granted to
you and protected by the eCos license. It also grants you the right to freely develop and
distribute applications based on eCos. We welcome all contributions back to eCos such as
board ports, device drivers and other components, as this helps the growth and
development of eCos, and is of benefit to the entire eCos community.
One of the key technological innovations in eCos is the configuration system. The
configuration system allows the application writer to impose their requirements on the
run-time components, both in terms of their functionality and implementation, whereas
traditionally the operating system has constrained the application's own implementation.
Essentially, this enables eCos developers to create their own application-specific
operating system and makes eCos suitable for a wide range of embedded uses.
Configuration also ensures that the resource footprint of eCos is minimized as all
unnecessary functionality and features are removed. The configuration system also
presents eCos as a component architecture. This provides a standardized mechanism for
component suppliers to extend the functionality of eCos and allows applications to be
built from a wide set of optional configurable run-time components. Components can be
provided from a variety of sources including the standard eCos release, commercial third
party developers and open source contributors.
The royalty-free nature of eCos means that you can develop and deploy your
application using the standard eCos release without incurring any royalty charges. In
addition, there are no up-front license charges for the eCos runtime source code and
associated tools. eCos delivers, without charge, everything necessary for basic embedded
applications development.
68K/ColdFire
ARM (including ARM7TDMI, ARM9TDMI, Cortex-M, StrongARM, XScale)
71
CalmRISC16 and CalmRISC32 (RedBoot only)
Fujitsu FR-V
Fujitsu FR30
Hitachi H8/300
Intel x86
Matsushita AM3x
MIPS
NEC V8xx
PowerPC
SPARC
SuperH
Support includes many of the popular variants of these architectures and evaluation
boards. Many new ports are in development and will be released as they become
available.
72
System requirements
The eCos net distribution is available in both Linux and Windows versions. The
Linux version is tested under recent versions of the Fedora, openSUSE and Ubuntu
distributions for x86 and should work under most Linux variants. The Windows version
has been tested under Microsoft Windows 2000 Professional, Windows XP and Windows
Vista. It should also work under Windows NT4 with SP6a. The use of eCos under
Windows 95/98/ME is no-longer supported.
The eCos net distribution is supplied with full support for configuration of eCos
on all host platforms via both a graphical configuration tool and a command-line tool. It
is intended to be used in conjunction with GNU development tools which are available
freely on the net. As a minimum, the gcc compiler, gdb debugger and binutils tools are
required to build eCos, link with application code and undertake debugging.
Status Key:
A: Alpha quality
B: Beta quality
73
Downloading and Installation
These instructions describe how to download and install recent versions of the
eCos real-time operating system.
Host support
The eCos net distribution is available in both Linux and Windows versions. The
Linux version is tested under recent versions of the Fedora, openSUSE and Ubuntu
distributions for x86 and should work under most Linux variants. The Windows version
has been tested under Windows 2000 Professional, Windows XP and Windows Vista. It
should also work under Microsoft Windows NT 4.0 with SP6a. Please note that eCos is
no longer supported under Windows 95/98/ME.
Linux
Developers wishing to use the pre-built eCos 3.0 host tools on a 32-bit Linux host
(i686) must first ensure that they have libstdc++ v3 (/usr/lib/libstdc++.so.5) installed. Users
of Linux distributions which provide a more recent libstdc++ may need to install a
libstdc++ v3 compatibility package. Installation of the compatibility package may be
achieved as follows:
Developers working with a 64-bit Linux host (x86_64) should use the above
snapshot build and will also need to install 32-bit libraries as follows:
74
The Linux-hosted eCos Configuration Tool also requires the GTK+ toolkit
version 2.0 or later.
Cygwin
Developers wishing to install eCos on a Windows host must first install a recent
version of the Cygwin UNIX emulation system. Full instructions on installing Cygwin
for use with eCos are available. The following instructions assume that Cygwin has
already been installed (where necessary) and that the reader is familiar with invoking
a bash shell.
The most recent eCos release (eCos 3.0) may be installed using an installation
tool which simplifies the downloading and installation of the eCos sources, host tools and
documentation. The installation tool can optionally download one or more pre-built GNU
cross toolchains (contributed by eCosCentric Limited) for use in conjunction with eCos.
At present, toolchains for the following target architectures are available for download in
pre-built form:
Architecture Target
ColdFire m68k-elf
MIPS32 mipsisa32-elf
PowerPC powerpc-eabi
SuperH sh-elf
75
Developers targetting one of the other architectures must build a toolchain
themselves at present. Full instructions for downloading source code and building a
toolchain are available.
sh ecos-install.tcl
The installation tool will present a list of mirror sites from which the software
may be downloaded. For best results, please select a mirror site in your own geographical
region. The tool will then prompt for an installation location. Finally, the tool will present
a list of pre-built GNU toolchains available for download. Select each toolchain you wish
to download by entering the corresponding number. When all required toolchains have
been selected, enter q. Downloading and installation of the software will then commence.
Note: Following installation of eCos, most users will need to replace their eCos host
tools with more recent snapshot builds. Download instructions for the most recent
snapshot builds are available in the ecos-discuss mailing list archives:
Windows users should note that POSIX-style paths are relative to the root of their
Cygwin installation (typically c:\cygwin) by default. For example, /opt/ecos might be
located atc:\cygwin\opt\ecos in the Windows Explorer.
Users may wish to create a shortcut to the eCos Configuration Tool on their desktop.
Typically, this may be achieved by dragging the configtool or configtool.exe executable file
from the file manager provided by your operating system onto the desktop and dropping
it while holding down the shift and ctrl keys. This file is located in the ecos-
version/tools/bin directory under the location at which eCos was installed. On Windows
hosts, it will be necessary to modify the "Start in" property of the shortcut to specify the
Cygwin /bin directory (typically c:\cygwin\bin) as the working directory.
Users who have downloaded eCos previously and now wish to download additional
toolchains should re-invoke the eCos installer, specifying the -t switch on the installer
command line as follows:
sh ecos-install.tcl -t
76
Documentation
The eCos Configuration Tool is used to tailor eCos at source level, prior to
compilation or assembly, and provides a configuration file and a set of files used to build
user applications. The sources and other files used for building a configuration are
provided in a component repository, which is loaded when the eCos Configuration
Tool is invoked. The component repository includes a set of files defining the structure of
relationships between the Configuration Tool and other components, and is written in
a Component Definition Language (CDL). For a description of the concepts underlying
component configuration,
Add the eCos Configuration Tool install directory to your PATH, for example:
export PATH=/opt/ecos/ecos<version>/bin:$PATH
You may run configtool with zero, one or two arguments. You can specify
the eCos repository location, and/or an eCos save file (extension .ecc) on the command
line. The ordering of these two arguments is not significant. For example:
On Windows
There are two ways in which to invoke the eCos Configuration Tool:
from the desktop explorer or program set up at installation time (by default Start -
> Programs -> eCos -> Configuration Tool ).
type (at a command prompt or in the Start menus Run item):
<foldername>\ConfigTool.exe where <foldername> is the full path of the
directory in which you installed the eCos Configuration Tool.
The Configuration Tool will be displayed
You may run configtool with zero, one or two arguments. You can specify
the eCos repository location, and/or an eCos save file (extension .ecc) on the command
line. The ordering of these two arguments is not significant. For example:
If you invoke the configuration tool from the command line with --help, you will see this
output:
77
Usage: eCos Configuration Tool [-h] [-e] [-v] [-c] [input file 1] [input file 2]
-h --help displays help on the command line parameters
-e --edit-only edit save file only
-v --version print version
-c --compile-help compile online help only
This summarizes valid parameters and switches. Switches are shown with both
short form and long form.
--edit-only runs the Configuration Tool in a mode that suppresses creation of a build
tree, in case you only want to create and edit save files.
--compile-help compiles help contents files from the HTML documentation files that
the tool finds in the eCos repository, and exits.
When you invoke the eCos Configuration Tool, it accesses the Component
Repository, a read-only location of configuration information. The eCos Configuration
Tool will look for a component repository using (in descending order of preference):
78
The final case above will normally only occur if the previous repository has been
moved or (under Windows) installation information stored in the Windows registry has
been modified; it will result in a dialog box being displayed that allows you to specify the
repository location:
Note that in order to use the eCos Configuration Tool you are obliged to provide a
valid repository location.
In the rare event that you subsequently wish to change the component location,
select Build->Repository and the above dialog box will then be displayed.
You can check the location of the current repository, the current save file path,
and the current hardware template and default package, by selecting Help->Repository
Information.... A summary will be displayed.
Use the File->Save menu item or click the Save Document icon on the toolbar;
if the current document is unnamed, you will be prompted to supply a name for the
configuration save file.
79
Open an existing document
Select File->Open, or click the Open Document icon on the toolbar. You will be
prompted to supply a name for the configuration save file.
Select File->Save As. You will be prompted to supply a new name for the
configuration save file.
The location of the build and install trees are derived from the eCos save file
name as illustrated in the following example:
Save file name = c:\My eCos\config1.ecc
Install tree folder = c:\My eCos\config1_install
Build tree folder = c:\My eCos\config1_build
These names are automatically generated from the name of the save file.
80
Building and Running Sample Applications
The first program you will run is a hello world-style application, then you will run
a more complex application that demonstrates the creation of threads and the use of
cyg_thread_delay(), and finally you will run one that uses clocks and alarm handlers.
The Makefile depends on an externally defined variable to find the eCos library and
header files. This variable is INSTALL_DIR and must be set to the pathname of the
install directory.
$ export INSTALL_DIR=BASE_DIR/ecos-
work/arm_install
You can then run make without any extra parameters to build the examples.
$ make INSTALL_DIR=BASE_DIR/ecos-
work/arm_install
The following code is found in the file hello.c in the examples directory:
To compile this or any other program that is not part of the eCos distribution, you
can follow the procedures described below. Type this explicit compilation command
(assuming your current working directory is also where you built the eCos kernel):
$ TARGET-gcc -g -IBASE_DIR/ecos-work/install/include
hello.c -LBASE_DIR/ecos-work/install/lib -Ttarget.ld -
nostdlib
81
The compilation command above contains some standard GCC options (for
example, -g enables debugging), as well as some mention of paths (-IBASE_DIR/ecos-
work/install/include allows files likecyg/kernel/kapi.h to be found, and -
LBASE_DIR/ecos-work/install/lib allows the linker to find -Ttarget.ld).
You can now run the resulting program using GDB in exactly the same the way
you ran the test case before. The procedure will be the same, but this time run TARGET-
gdb specifying -nw a.out on the command line:
For targets other than the synthetic linux target, you should now run the usual
GDB commands described earlier. Once this is done, typing the command "continue" at
the (gdb) prompt ("run" for simulators) will allow the program to execute and print the
string "Hello, eCos world!" on your screen.
On the synthetic linux target, you may use the "run" command immediately - you
do not need to connect to the target, nor use the "load" command.
Below is a program that uses some of eCos' system calls. It creates two threads,
each of which goes into an infinite loop in which it sleeps for a while (using
cyg_thread_delay()). This code is found in the file twothreads.cin the examples directory.
#include <cyg/kernel/kapi.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/* now declare (and allocate space for) some kernel objects, like the two threads we
will use */
cyg_thread thread_s[2]; /* space for two thread objects */
char stack[2][4096]; /* space for two 4K stacks */
82
/* and now a mutex to protect calls to the C library */
cyg_mutex_t cliblock;
When you run the program (by typing continue at the (gdb) prompt) the output should
look like this:
83
Thread 0: and now a delay of 240 clock ticks
Thread 1: and now a delay of 225 clock ticks
Thread 1: and now a delay of 234 clock ticks
Thread 0: and now a delay of 231 clock ticks
Thread 1: and now a delay of 224 clock ticks
Thread 0: and now a delay of 249 clock ticks
Thread 1: and now a delay of 202 clock ticks
Thread 0: and now a delay of 235 clock ticks
Note: When running in a simulator the delays might be quite long. On a hardware board
(where the clock speed is 100 ticks/second) the delays should average to about 2.25
seconds. In simulation, the delay will depend on the speed of the host processor and will
almost always be much slower than the actual board. You might want to reduce the delay
parameter when running in simulation.
Following figure shows how this multitasking program executes. Note that apart from
the thread creation system calls, this program also creates and uses a mutex for
synchronization between the printf() calls in the two threads. This is because the C
library standard I/O (by default) is configured not to be thread-safe, which means that if
more than one thread is using standard I/O they might corrupt each other. This is fixed by
a mutual exclusion (or mutex) lockout mechanism: the threads do not
call printf() until cyg_mutex_lock() has returned, which only happens when the other
thread calls cyg_mutex_unlock().
Figure. Two threads with simple print statements after random delays
84
Ecosconfig on Windows and Linux Quick Start
To use the ecosconfig command you need to start a shell. In Windows you need
to start a CygWin bash shell, not a DOS command line. The following instructions
assume that the PATH and ECOS_REPOSITORY environment variables have been setup
correctly. They also assume Linux usage but equally well apply to Windows running
Cygwin.
Before invoking ecosconfig you need to choose a directory in which to work. For
the purposes of this tutorial, the default path will be BASE_DIR/ecos-work. Create this
directory and change to it by typing:
$ mkdir BASE_DIR/ecos-work
$ cd BASE_DIR/ecos-work
$ ecosconfig --help
Usage: ecosconfig [ qualifier ... ] [ command ]
commands are:
list : list repository
contents
new TARGET [ TEMPLATE [ VERSION : create a
configuration
target TARGET : change the target
hardware
template TEMPLATE [ VERSION ] : change the template
add PACKAGE [ PACKAGE ... ] : add package(s)
remove PACKAGE [ PACKAGE ... ] : remove package(s)
version VERSION PACKAGE [ PACKAGE ... ] : change version of
package(s)
export FILE : export minimal config
85
info
import FILE : import additional
config info
check : check the
configuration
resolve : resolve conflicts
tree : create a build tree
qualifiers are:
--config=FILE : the configuration file
--prefix=DIRECTORY : the install prefix
--srcdir=DIRECTORY : the source repository
--no-resolve : disable conflict
resolution
--version : show version and
copyright
RESULT:
Thus the Study the eCos open source operating system has been done and
developed a module.
86