2011年4月30日 星期六

2011年4月21日 星期四

set io parameter on mac

sysctl -w kern.aioprocmax=1000

sysctl

get or set kernel state

show value
ex:
sysctl -a | grep aio
->

kern.aiomax = 90
kern.aioprocmax = 16
kern.aiothreads = 4
kern.aiomax: 90
kern.aioprocmax: 16
kern.aiothreads: 4


modify value
ex:
sysctl -w kern.aioprocmax=1000

iometer

http://sourceforge.net/news/?group_id=40179

use iometer to test  disk performance on mac
(the dynamo for mac & iometer for windows must be the same version)

(1) run dynamo on mac os
 ex:
sudo ./Dynamo -i 192.168.4.112  -m 172.18.8.21
192.168.4.112 is windows IP,
172.18.8.21  is mac os IP

(2) run iometer on windows

2011年4月20日 星期三

atomic operation in mac driver

SInt32 OSDecrementAtomic(volatile SInt32 * address);
SInt32 OSIncrementAtomic(volatile SInt32 * address);

vibrate on iOS

AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
( add AudioToolbox.framework) 

2011年4月19日 星期二

linux driver location

ex:
/lib/modules/2.6.18-128.el5/kernel/drivers/net/e1000/e1000.ko

find network card driver on linux

check /etc/modules.conf
ex:
cat /etc/modprobe.conf
-> alias scsi_hostadapter ata_piix alias eth1 e1000 alias eth3 e1000

linux driver command

lsmod 

modinfo
ex:
modinfo test
show info about test module

mac driver plist

mac driver plist
mac driver:

1. CFBundleIdentifier
unique id for kext
ex:
com.deeplove.test
it does not need to match with IOClass

2. OSBundleLibraries
define depended libraries
we can use kextlibs to find linked libraries
ex:
kextlibs -xml GenericKext.kext
->
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.kpi.libkern</key>
<string>10.4</string>
</dict>
the match version number lib is define in OSBundleCompatibleVersion
ex:
<key>OSBundleCompatibleVersion</key>
<string>1.0</string>

3. IOKitPersonalities
ex:
<key>IOKitPersonalities</key>
<dict>
<key>MyIokitDriver</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.driver.MyIokitDriver</string>
<key>IOClass</key>
<string>com_yourcompany_driver_MyIokitDriver</string>
<key>IOKitDebug</key>
<integer>65535</integer>
<key>IOProviderClass</key>
<string>IOResources</string>
<key>IOMatchCategory</key>
<string>com_yourcompany_driver_MyIokitDriver</string>
</dict>
</dict>
CFBundleIdentifier in IOKitPersonalities must be the same  with outer CFBundleIdentifier
IOProviderClass:
 indicates the class of the provider objects that your driver can match on

IOMatchCategory:
 allows other drivers to match on the same device as your driver,
 as long as the drivers values for this property differ



ipos tool

python program
http://benjamin-schweizer.de/files/iops/

2011年4月18日 星期一

create install package for kext

reference:
http://developer.apple.com/library/mac/#documentation/Darwin/Conceptual/KEXTConcept/KEXTConceptPackaging/packaging_tutorial.html%23//apple_ref/doc/uid/20002368-CHDCBCJA

1. create dir for kext
    cd /tmp
    sudo mkdir  tempKext

2. copy kext into dir
   cd /KEXT_PROJECT_PATH/build/Release
   sudo cp -R test.kext  /tmp/tempKext

3. use PackageMaker to create install package
    (/Developer/Application/Utilities)
    drag tempKext dir into PackageMaker window
    save editing result as .pmdoc file( PackageMaker file)

4. build
    create .pkg file (install file)

.







2011年4月16日 星期六

multitouch on iOS

get touch events for specific view


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSSet *touchesForTestView = [event touchesForView:testView];
}

2011年4月15日 星期五

create global variable on iOS project

ex:
test.m 
int a = 3;

hello.h
extern int a;

useA.m
#import hello.h

NSNotificationCenter

- (void)addObserver:(id)observer selector:(SEL)aSelector :(NSString *)aName object:(id)anObject;
register to receive notification
parameter:
1. observer: the object to receive notification

2. aName: name of notification, if it is nil, we receive all notifications sent out by anObject

3. anObject: specify object we want to observe. If it is nil, we receive all notification with aName

we can register many objects to receive same notification.


- (void)postNotificationName:(NSString *)aName object:(id)anObject;
send notfication
parameter:
anObject: sender




create project on github

1. new repository

2. edit repository info


3. add  collaborator





2011年4月12日 星期二

find element in ioregistry

from client program:


#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/IOType.h>




int findClassesInIoregistry(io_iterator_t*  iterator, char *match_name)
{
        CFDictionaryRef classToMatch;
kern_return_t kernResult; 
classToMatch = IOServiceMatching(match_name);
if (classToMatch == NULL)
        {
              return -1;
        }
// use class name to match
        kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault,    
                      classToMatch, iterator);
if (kernResult != KERN_SUCCESS
        {
        
             return -1;
        }
return kIOReturnSuccess;
}


io_iterator_t ethernetInterfaceIterator;
result = findClassesInIoregistry(& ethernetInterfaceIterator, kIOEthernetInterfaceIterator);
if(result == kIOReturnSuccess)
{
        io_service_t ethernetInterface;
    while(ethernetInterface = IOIteratorNext(ethernetInterfaceIterator))
    {
        NSString *bsdName =
             (NSString*)IORegistryEntrySearchCFProperty(ethernetInterface,
                                                        kIOServicePlane
                                                        CFSTR("BSD Name"), 
                                                        kCFAllocatorDefault,
                                                   kIORegistryIterateRecursively);


       io_service_t ethernetController;
       result = IORegistryEntryGetParentEntry(ethernetInterface, 
                                           kIOServicePlane
                                           &ethernetController);
       if(result == kIOReturnSuccess)
       {
        
           IOObjectRelease(ethernetController);
       }



        IOObjectRelease(ethernetInterface);
        
    }
    IOObjectRelease(ethernetInterfaceIterator);
}



from driver program:


OSIterator *blockDriverIter =  this->getProviderIterator();
com_my_BlockStorageDriver *blockDriver;

if(blockDriverIter)

{
while (blockDriver = (com_my_BlockStorageDriver*)blockDriverIter->getNextObject()) 
        {
    
IOLog("blockDriver %p inAct %d\n", blockDriver,

blockDriver->isInactive());

   
}
blockDriverIter->release();
}






2011年4月11日 星期一

IO statistics in mac

From IORegistryExplorer, check IOBlockStorageDriver 

detect blow on iOS SDK

http://mobileorchard.com/tutorial-detecting-when-a-user-blows-into-the-mic/

IOUserClient

reference sample code from Apple:
SimpleUserClient


IOExternalMethodDispatch structure:

struct IOExternalMethodDispatch
{
    IOExternalMethodAction function;
    uint32_t     checkScalarInputCount;
    uint32_t     checkStructureInputSize;
    uint32_t     checkScalarOutputCount;
    uint32_t     checkStructureOutputSize;
};

mac & raid

scsi id on each channel in raid must be different

2011年4月10日 星期日

2011年4月9日 星期六

responder chain in iOS & Cocoa

events are passed through responder chain

ex:
if first responder is view A
when view A does not handle event, it forward event to next responder, its view controller
if view controller  does not handle event, it forward event to view A's parent view B
if view B does not handle event, it forward event to its view controller
Hence,  sequence is
view A ->  view A's view controller -> view A's parent view B -> view A's parent view B's view controller
note:
if event is passed through all view hierarchy, it is then passed to app's window. If window does not handle event, it is passed to UIApplication object

forward an event:
ex:
[self.nextResponder processEvent:event];

CMMotionManager

passive detect:
get data from callback

active detect:
get data when we need

acceleration value for different device orientations:

2011年4月8日 星期五

UIKit and thread

when dealing with UIKit class, we must be in the main thread
If we are not in the main thread,
and we want to modify label's text,
we must do following
->

[textLabel performSelectorOnMainThread:@selector(setText:)  
      withObject:@"hello" waitUntilDone:YES];

operation is iOS SDK

Add operations into operation queue and queue will manage operation for us

operation type:
1. Block operation
2. Invocation operation
3. Plane operation

operation 執行的順序和加入operation queue的順序無關

UINavigationBar

height:
44

share memory between app and kernel on mac os

memory allocated in the kernel cannot be written to by applications


 if a buffer must be modified by an application, the buffer must be allocated by that program, not by the kernel

2011年4月7日 星期四

mac driver debug

1. download kernel debug kit from Apple website
ex:
kernel_debug_kit_10.6.7_10j869.dmg



2.  create kext symbol file
ex:
find address from crash report (/Library/Logs/DiagnosticReports/)

Thu Apr  7 15:19:35 2011
panic(cpu 0 caller 0xffffff80002cffca): Kernel trap at 0xffffff8000521c10, type 14=page fault, registers:
CR0: 0x000000008001003b, CR2: 0x0000000000000000, CR3: 0x0000000000100000, CR4: 0x0000000000000660
RAX: 0xffffff800918f260, RBX: 0xffffff8009a45c00, RCX: 0x00000000f25d0000, RDX: 0xffffff80088a5e20
RSP: 0xffffff804a4db790, RBP: 0xffffff804a4db7b0, RSI: 0x0000000020000001, RDI: 0x0000000000000000
R8:  0x000000000000000a, R9:  0x0000000000000000, R10: 0x0000000000000000, R11: 0xffffff80004f3b3a
R12: 0xffffff8008ce1000, R13: 0xffffff8009a45c00, R14: 0xffffff8009a459c0, R15: 0x0000000000000000
RFL: 0x0000000000010246, RIP: 0xffffff8000521c10, CS:  0x0000000000000008, SS:  0x0000000000000000
Error code: 0x0000000000000000

Backtrace (CPU 0), Frame : Return Address
0xffffff804a4db430 : 0xffffff8000204b99
0xffffff804a4db530 : 0xffffff80002cffca
0xffffff804a4db680 : 0xffffff80002e20da
0xffffff804a4db690 : 0xffffff8000521c10
0xffffff804a4db7b0 : 0xffffff8000521408
0xffffff804a4db7e0 : 0xffffff7f806e699a
0xffffff804a4db970 : 0xffffff7f806defca
0xffffff804a4db9e0 : 0xffffff7f806e76f9
0xffffff804a4dba30 : 0xffffff7f8067f5ad
0xffffff804a4dbaa0 : 0xffffff7f806807e2
0xffffff804a4dbba0 : 0xffffff7f80680191
0xffffff804a4dbbd0 : 0xffffff7f80680458
0xffffff804a4dbc50 : 0xffffff7f806e6d30
0xffffff804a4dbcb0 : 0xffffff80005267da
0xffffff804a4dbd20 : 0xffffff80005239bf
0xffffff804a4dbd40 : 0xffffff8000521e78
0xffffff804a4dbd70 : 0xffffff800052649f
0xffffff804a4dbda0 : 0xffffff8000523a07
0xffffff804a4dbde0 : 0xffffff80005267da
0xffffff804a4dbe50 : 0xffffff80005239bf
0xffffff804a4dbd40 : 0xffffff8000521e78
0xffffff804a4dbd70 : 0xffffff800052649f
0xffffff804a4dbda0 : 0xffffff8000523a07
0xffffff804a4dbde0 : 0xffffff80005267da
0xffffff804a4dbe50 : 0xffffff80005239bf
0xffffff804a4dbe70 : 0xffffff8000521e78
0xffffff804a4dbea0 : 0xffffff800052649f
0xffffff804a4dbed0 : 0xffffff8000523a07
0xffffff804a4dbf10 : 0xffffff7f806c276b
0xffffff804a4dbf40 : 0xffffff7f806c09f6
0xffffff804a4dbf60 : 0xffffff800028504e
0xffffff804a4dbfa0 : 0xffffff80002c7387
      Kernel Extensions in backtrace (with dependencies):
         com.eonpath.driver.TestC(1.0.1)@0xffffff7f806dc000->0xffffff7f806edfff
            dependency: com.apple.iokit.IOSCSIBlockCommandsDevice(2.6.5)@0xffffff7f806be000
            dependency: com.ift.driver.TestB(1.0.0)@0xffffff7f806ce000
            dependency: com.apple.iokit.IOStorageFamily(1.6.2)@0xffffff7f80679000
            dependency: com.apple.iokit.IOSCSIArchitectureModelFamily(2.6.5)@0xffffff7f806a5000
         com.apple.iokit.IOSCSIBlockCommandsDevice(2.6.5)@0xffffff7f806be000->0xffffff7f806cdfff
            dependency: com.apple.iokit.IOSCSIArchitectureModelFamily(2.6.5)@0xffffff7f806a5000
            dependency: com.apple.iokit.IOStorageFamily(1.6.2)@0xffffff7f80679000
         com.apple.iokit.IOStorageFamily(1.6.2)@0xffffff7f80679000->0xffffff7f80692fff

kextutil -n -s /tmp /System/Library/Extensions/test.kext
-s: location for symbol file

Notice: Using running kernel architecture x86_64 to generate symbols.
No kernel file specified; using running kernel for linking.
/System/Library/Extensions/mpioDriver.kext appears to be loadable (not including linkage for on-disk libraries).

Enter the hexadecimal load addresses for these extensions
(press Return to skip symbol generation for an extension):

com.apple.iokit.IOSCSIArchitectureModelFamily: 0xffffff7f806a5000
com.apple.iokit.IOStorageFamily: 0xffffff7f80679000
com.apple.iokit.IOSCSIBlockCommandsDevice: 0xffffff7f806be000
com.peter.driver.testB: 0xffffff7f806ce000
com.peter.driver.testC: 0xffffff7f806dc000

->
.sym files are created at /tmp/

3. find source code line number that triggers panic:
ex:

gdb /Volumes/KernelDebugKit/mach_kernel
--> set kext-symbol-file-path /tmp
--> add-kext ~/test.kext
--> set print asm-demangle on
--> x/i 0xffffff7f806e699a
find the function mapped to this address
--> disass 0xffffff7f806e699a
show this function's content
--> info line * 0xffffff7f806e699a
show the line number of EIP in the function

note:
0xffffff7f806e699a is address for our driver in backtrace


2011年4月6日 星期三

modify entry in ioregistry

OSDictionary *dic = OSDictionary::withCapacity(6);
OSNumber *index = OSNumber::withNumber(100, 32);
dic->setObject("TEST_INDEX", index);
index->release();
this->setProperty("TEST_DIC", dic);
dic->release();
index->setValue(1);

note:
we can not modify collection directly
Following code will trigger crash
dic->setObject("testIndex", OSNumber::withNumber(200, 32));
If we want to add or delete entry in collection,
we must create new collection and  use setProperty to replace old collection

mac crash log

location
/Library/Logs/DiagnosticReports

read log from Console App:

mac driver command

ioclasscount
displays the instance counts of OSObject-based C++ classes in the kernel
ex:
ioclasscount | grep My

->
com_MyCompany_driver_MyDriver = 1

kextutil:

load, diagnose problems with, and generate symbols for kernel extensions
ex:
kextutil test.kext

iokit driver

TestIokit.h


#include <IOKit/IOService.h>

class com_MyCompany_driver_MyDriver : public IOService
{
OSDeclareDefaultStructors(com_MyCompany_driver_MyDriver)
public:
    virtual bool init(OSDictionary *dictionary = 0);
    virtual void free(void);
    virtual IOService *probe(IOService *provider, SInt32 *score);
    virtual bool start(IOService *provider);
    virtual void stop(IOService *provider);
};

TestIokit.cpp


#include <IOKit/IOLib.h>
#include "MyDriver.h"

// This required macro defines the class's constructors, destructors,
// and several other methods I/O Kit requires.
OSDefineMetaClassAndStructors(com_MyCompany_driver_MyDriver, IOService)

// Define the driver's superclass.
#define super IOService

bool com_MyCompany_driver_MyDriver::init(OSDictionary *dict)
{
    bool result = super::init(dict);
    IOLog("Initializing\n");
    return result;
}

void com_MyCompany_driver_MyDriver::free(void)
{
    IOLog("Freeing\n");
    super::free();
}

IOService *com_MyCompany_driver_MyDriver::probe(IOService *provider,
SInt32 *score)
{
    IOService *result = super::probe(provider, score);
    IOLog("Probing\n");
    return result;
}

bool com_MyCompany_driver_MyDriver::start(IOService *provider)
{
    bool result = super::start(provider);
    IOLog("Starting\n");
    return result;
}

void com_MyCompany_driver_MyDriver::stop(IOService *provider)
{
    IOLog("Stopping\n");
    super::stop(provider);
}

TestIokit-Info.plist


gcd: Grand Central Dispatch

provide a number of predefined queues

we can create our own queue

queue is FIFO

block in Objective-C

also known as closures or lambdas

block syntax:
1. ^
2. ( parameterType parameterName )
3. { code to be executed }


ex:
// declare a block variable test
void (^test)(void);
//  define block's code
test = ^ { NSLog("test"); };
// execute block
test();

ex:
void (^test)(void) = ^ { NSLog("test"); };

solaris service

steps to create service:

1. Create a service manifest file.
this file defines dependency and start/stop script location
ex:
nfs server's manifest file
/lib/svc/manifest/network/nfs/server.xml
content ex:

 <exec_method
        type='method'
        name='start'
        exec='/lib/svc/method/nfs-server %m'
        timeout_seconds='3600' />


2. Create a methods script file to define the start, stop, and restart methods for the service.
ex:
nfs server's script
/lib/svc/method/nfs-server

3. Validate and import the service manifest using svccfg(1M).
4. Enable or start the service using svcadm(1M).
5. Verify the service is running using svcs(1).