Wiley.Symbian.OS.Internals.Real.time.Kernel.Programming.Dec.2005.eBook-DDU (779891), страница 41
Текст из файла (страница 41)
Here are the detailsof the functions associated with each bit:BitDescription31If this bit is set to 1, the system lock fast mutex will beacquired prior to calling the executive handler.30If this bit is set to 1, the system lock fast mutex will bereleased after returning from the executive handler.29If this bit is set to 1, the preprocessing handler will becalled prior to calling the executive handler. Note thatif bit 31 is also set to 1, the system lock is acquiredbefore calling the preprocessing handler.26, 27, 28These bits make a three-bit wide field indicating thenumber of additional arguments required by theexecutive call.
A value of 0 indicates that there are noadditional arguments; a value of n, where 1 ≤ n ≤ 7indicates that there are n + 1 additional arguments.Thus up to eight additional arguments may be specified.EXAMPLE USER-ACCESSIBLE SERVICES1835.2.1.8 Kernel server callsIf you know EKA1, you may be wondering why I haven’t mentionedkernel server calls. Let me explain a little bit about them, and then I hopethe reason will become clear.As I’ve said, EKA1 makes use of the EUSER library.
The heap functionsin EUSER allocate and free memory on the heap of the current thread.This made it difficult for any EKA1 exec calls that resulted in the creation(or destruction) of kernel objects – those objects must be created on thekernel heap, but during the executive call the thread context is that of thethread making the executive call.So, to ensure that the memory was allocated on the kernel heap, wehad to engineer a switch to a kernel thread context. To do this, an EKA1thread executes a special exec call that makes a request from the kernelserver thread and then blocks awaiting the reply.
At the next reschedule,the kernel server thread will run (as it is the highest priority thread in thesystem) and obviously it can then create or destroy objects on its ownheap on behalf of the user thread.EKA2 has its own memory allocation routines, and does not link toEUSER. This means that EKA2 exec calls can allocate and free kernelmemory and we do not need kernel server calls.5.2.2Executive calls in the emulatorThe emulator can’t use a software interrupt to implement executive calls,so instead it uses a function call but with a special calling convention.The executive dispatcher lives in the nanokernel, but the calls themselves are in the user library (EUSER.DLL).
To prevent EUSER.DLLdepending on EKERN.EXE, this call is not done using the standard importmachinery. Instead, there is a function pointer to the dispatcher in EUSER,which is initialized lazily to point to the first ordinal in EKERN.EXE – thisis the only export from EKERN that must be maintained in EKA2’s emulator. The executive functions in EUSER first set up two parameters (theexecutive number and the pointer to the parameters, which are all on thethread stack), then they jump to the nanokernel dispatcher function.The dispatcher then handles the executive in a way which is similarto that on a phone: the executive function runs with the thread in‘‘kernel mode’’, fast executive calls run with interrupts disabled and slowexecutive calls can manipulate the system lock and have preprocessingdone on their parameters.5.3 Example user-accessible servicesIn this section, I’m just aiming to give you a feel for the kind of servicesthat the kernel provides via EUSER, and how we decide to categorizeeach exec call.184KERNEL SERVICES5.3.1 Fast exec callsAs we saw, fast executive calls run with all interrupts off, so they must dotheir tasks very quickly and then return to the user.
Generally these callsjust get or set a single word of kernel memory. Here are some examples:RAllocator* Exec::Heap()Returns the current thread’s heap.TUint32 Exec::FastCounter()Returns the value of the fast counter, which can be used in profiling.Exec::SetDebugMask(TUint32)Sets the kernel’s debug bit mask to determine the level of printf()debugging displayed on the serial port. Often used in debug code torestrict debug printing to key areas of interest.5.3.2Slow exec calls5.3.2.1 Services that don’t claim the system lockThese services are ones which do not need to lock the system to protectthem from their own side effects – that is, two concurrent calls to thesame exec call will not interfere with each other.
These services oftenread, rather than modify, kernel data. Examples are:void Exec::IMB_Range(TAny* aBase, TUint aLength)Performs all necessary cache management for the address range aBaseto aBase+aLength in order that whatever has been written there canbe executed.
This is known as an instruction memory barrier (IMB).TUint Exec::TickCount()Returns the number of system ticks since boot.void Exec::DebugPrint(TAny* aDebugText, TInt aMode)Passes in a descriptor with text to print out as a debug string, and a modeto print in.5.3.2.2 Services that claim the system lockAs we’ve seen, certain slow exec calls have a bit set in their attributeword to say that the dispatcher should lock the system before calling theexecutive handler in the kernel. The main reason for this is to protectcertain kernel resources against multiple accesses.Examples of this type of service are:TUint32 Exec::MathRandom()Returns a random number.
Since this code is not re-entrant, the systemis locked.EXAMPLE USER-ACCESSIBLE SERVICES185void Exec::CaptureEventHook()The window server calls this function to capture the event hook. Onlyone thread may own this event hook, so the system is locked to preventa second thread gaining access to the function before the first threadhas flagged that it has taken the hook by setting the kernel variableK::EventThread to point to itself.
On the secure kernel, this functionpanics if the thread taking the event hook is not the window server thread.Services passing handlesCertain slow exec calls have a bit set in their attribute word to say that thedispatcher should call a preprocessing handler in the Symbian OS kernelbefore calling the executive handler in the kernel. The preprocessinghandler takes the first argument of the slow exec call, which is always ahandle, and translates it into a DObject derived object pointer.Any slow exec call that calls the preprocessing handler also claims thesystem lock.Examples of this type of service are:TUint8* Exec::ChunkBase(ChunkHandle aHandle)Returns a pointer to the start of a chunk.TInt Exec::ThreadId(ThreadHandle aHandle)Returns the ID of the given thread.TlibraryFunction LibraryLookup(LibraryHandleaHandle, TInt aFunction)Returns the address of the required function number in the given library.Services where the dispatcher doesn’t release the lockThese exec calls claim the system lock on entry, but don’t unlock iton exit.
This is because the exec handler functions release the systemlock themselves.Examples of this type of service are:void Exec::MutexWait(MutexHandle aHandle)Waits on the given mutex.void Exec::ProcessSetPriority (ProcessHandleaProcess, TProcessPriority aPriority)Sets the priority of the given process.void Exec::SemaphoreSignalN(SemHandle aHandle,TInt aNum)Signals the given semaphore a number of times.186KERNEL SERVICES5.3.3 HAL functionsAs we’ve seen, the EKA2 kernel is not linked to, and never calls, theuser library, EUSER.DLL. This is a major difference from EKA1, whichoften used the user library as a way to call its own services, going via anexecutive call and a supervisor mode SWI to the required service, eventhough it was already executing in supervisor mode.Not only does EKA2 not call EUSER, it rarely makes a SWI calleither – clearly a good thing for its performance.
In fact, there is only oneplace where EKA2 does make a SWI call – Kern::HalFunction().This function is used to request a service from a kernel extension, anduser threads call it via the function UserSvr::HalFunction().The hardware abstraction layer, or HAL, consists of a set of hardware or system attributes that can be set or read by software. Theseare broken down into groups of like functionality, as enumerated byTHalFunctionGroup:enum THalFunctionGroup{EHalGroupKernel=0,EHalGroupVariant=1,EHalGroupMedia=2,EHalGroupPower=3,EHalGroupDisplay=4,EHalGroupDigitiser=5,EHalGroupSound=6,EHalGroupMouse=7,EHalGroupEmulator=8,EHalGroupKeyboard=9,};Each of these groups then has a set of attributes. For example, the firstgroup, EHalGroupKernel, has these attributes:enum TKernelHalFunction{EKernelHalMemoryInfo,EKernelHalRomInfo,EKernelHalStartupReason,EKernelHalFaultReason,EKernelHalExceptionId,EKernelHalExceptionInfo,EKernelHalCpuInfo,EKernelHalPageSizeInBytes,EKernelHalTickPeriod,EKernelHalMemModelInfo,};Each HAL group has a handler function that manages the group’sattributes.
This handler can be dynamically installed by using the functionSERVICES PROVIDED BY THE KERNEL TO THE KERNEL187Kern::AddHalEntry(). For example, some HAL groups correspondto a particular hardware device, like the screen display or keyboards,and the kernel extension or device drivers for these devices will installa handler.As I said earlier, the kernel accesses HAL functions viaKern::HalFunction():EXPORT_C __NAKED__ TInt Kern::HalFunction(TInt /*aGroup*/,TInt /*aFunction*/, TAny* /*a1*/,TAny* /*a2*/, TInt /*aDeviceNumber*/){asm("ldr ip, [sp, #0] ");asm("orr r0, r0, ip, lsl #16 ");asm("mov ip, lr ");asm("swi %a0" : : "i"(EExecHalFunction|EXECUTIVE_SLOW));}You can see that the first and second parameters are the group and thenumber of the function. The remaining parameters, if present, are passedto the HAL function itself.5.4 Services provided by the kernel to the kernelIn the introduction to this book, I mentioned that we could consider thearchitecture of EKA2 from a software layering perspective, as shown inFigure 5.3, and went on to discuss the kind of software that appeared ateach layer.In this chapter, I am more concerned with the services each layerprovides to the other layers.NKernNKernSymbian OS KernelIndependentMemory ModelPlatformMemory ModelModelMemory ModelSymbian OS KernelCPUASSP DLLASSPVariant DLLVariantFigure 5.3Software layering188KERNEL SERVICES5.4.1 Independent layer5.4.1.1 NanokernelThe static interface to the independent nanokernel is provided throughthe class NKern, which is defined in nkern.h.