MMLite Part I: The Gospel Your Favorite Preacher.
Transcript of MMLite Part I: The Gospel Your Favorite Preacher.
Freedom
• You can never make them all happy – make it replaceable!
• Do *I* need that ?– make it optional!– avoid architectural restrictions (MMU,
interrupts,…)
• Interfaces should not mandate functionality– think hard!
Components
• A Component is code + static data + a number of objects
• Leads to modularity: formal interfaces, multiple implementations, configurability, replaceability (mutation)
• A componentized system is easily scalable
• Minimalism rules.
Objects Objects Objects..
• Operating Systems die young or live very, very long lives => Software Engineering
• No DLL hell
• Stress dynamic over static configuration
• Location independence
• No exposed Messages
• Reuse of code and interfaces
Base Component• “Kernel” is a very bad word
• Build-up is easy, scale-down impossible
• The “minimal” set of objects/APIs depends on your whole system requirements
• Both static and dynamic configurability are necessary features
• Security and modularity are different issues
• VM and IPC are loaded on-demand
Programming Model(s)
• Small config must still be usable
• People don’t like fakes
• Objects are popular
• Threading is not that easy– Use passive objects
Why COM ?
• It was there
• Explicit refcounting (unmanaged code)
• IUnknown is useful per-se (Namespace)
• Typechecked and versioning
• ..but we don’t need the whole enchilada– No Registry, CoCreateInstance, Class IIDs,
IIDs as names, IDispatch, Monikers, ….
NameSpaces
• Uniform naming (instead of Registry, Filesystems, Device trees, Web, ….)
• Register() the IUnknown of an object in the NameSpace, Bind() to it from somewhere else and you got an IPC.
• Register an INameSpace to extend the NameSpace
• Leverage simple tools (dir,type,…)
Virtual Machines
• An OS cannot be language-dependent
• Base supports unmanaged (C/C++) code
• VMs are implemented on top (URT!)
• Doing it upsy-turvy has been proven wrong (Inferno, JavaMachine).
Scheduling
• State of the art real-time (Time Constraints)
• TimeSharing
• FixedPriority
• ..do your own if you don’t like it!
Synchronization
• Mutexes (locks), Condition Variables, lock-free primitives
• Well established in academia• Simple and efficient• Precisely defined interactions with
scheduling and time constraints• Can build all others (cf. Herlihy) on top (events,
semaphores,monitors,…)
Tools
• Live with what is provided, cannot port VC to all processors.
• We do DLLs by hand, if necessary
• Code is ANSI-C, no MSFT “extensions”
• Debug on simulators (NT&VC,vendor’s)
• Extend simulators with full-system simulation (peripherals!)
Start from nothing
• “Just the initialization code, please.”
• Add a heap manager..
• … a scheduler...
• … a namespace…
• … a loader…
• … then go a-la carte, including VM & IPC
Initialization & MachDep code
• MD code gets control first, then calls the MI Initialization function [kinit.c]
• But it could do its own [h8\_kinit.c]
• MD code lives separately, can be macros
• A MI file foo.c includes a MD file _foo.c when it strongly expects MD code.
• All MD code filenames start with “_”
MD code in Base
• 64bit math, unless int64XXX.c does it
• Context switch [_schedul.c] & thread creation [_thread.c]
• CompareAndSwap [_atomic.c]
• Interrupts [_pic.c,_timer.c]
• Debug I/O [_debug.c]
• Startup initialization [_start.s]
Heap Managers
• Anything that provides the IHeap interface
• The obvious, plus Extract()– FreeList [heap.c]– Bitmap [bm_heap.c]– AllocOnly [no_heap.c]
Schedulers
• Separate from thread manager [thread.c] and from synchronization [mutex.c, condtn.c, atomic.c]
• Not exposed in NameSpace (for now?)– Constraints [cb_sched.c]– RoundRobin [rr_sched.c]– None, placeholder [no_sched.c]– ..or ask Equator for theirs
Namespaces
• Think of it as an extensible directory, or a filing system for live objects
• Per-process CurrentNameSpace()
• Root in Base [namespc.c]
• Demand-Loading in cobmgr
• Filesystems [romfs.c, memdev.c, drivers/fatfs.c, mips/_hostfs.c]
Loaders
• Implicitly part of IProcess/IModule
• AIF for ARM [arm_ldr.c]
• ELF for MIPS and Equator [elf_ldr.c]
• LIFE for TriMedia [life_ldr.c]
• PE for x86 [pe_ldr.c]
VM & IPC
• Both are on-demand loadable objects
• VM [src/vm] features:– Skiplist for ranges– 3 (instead of 2) separate concepts - virtual
address, TLB, and physical address– IVMFactory, IVMSpace, IVMMapping,
IVMView, IVTLB
• IPC is work-in-progress [src/ipc]
Interrupts & I/O
• AddDevice() both adds and removes ISRs
• No DPCs, no priorities, no nesting
• An ISR takes an object argument
• An ISR can only ConditionInterruptSignal()
• AtomicQueues are useful
• IDMA Interface
The RTL
• DLL-style linking into Base
• Deprecated but necessary for sharing the compiler’s builtins and for bootstrapping e.g. CurrentXXX()
• AtomicXXX, MutexXXX, ConditionXXX, Constraints, Sleep/Delay, some other constructors.
Networking Stack
• BSD4.4Lite based
• UDP,TCP,MCAST,IGMP,Routing,DHCP,DNS,UPnP
• Old: XNS,CCITT,OSI
• Winsock 1.1 interface
• Native interfaces (IEndPoint/INetDevice)
• Needs trimming and interface revision
Device Drivers
• 23 sample drivers, real-time safe, for typical PC peripherals.– IDevice/INetDevice interfaces, derive from
IFile.– Both C and C++, common base class code in C+
+– Autoconfig example also.
• MIDI, audio, GbEthernet, host pkt interface..
Apps are objects
• Objects are all created equal
• Performance tuning is a system-wide exercise...no barriers
• Security might require VM protection
• COB Namespace & programming model
• ..or just use your regular main(argc,argv)
COB E xamples
VMemAlloc() { pNS = CurrentNameSpace(); pUnk =pNSÔ Bind(“VMM”); pVM = pUnkÔ QueryInterface(I ID_ IVmSpace); pHeap = CreateHeap(pVM); pHeapÔ Allocate();}
IUnknown main() { pUnk = new(); return pUnk;}
The Source Trees
• Components publish their interfaces in the /MMLite/inc directory.
• Sources and private includes ..are somewhere under /MMLite/src.
• Compilers&co under /tools.
• Tools we own (&sources) are under /MMLite/mstools.
Build process
• Command scripts drive [mkall.bat, mkit.bat]
• Per-processor makefiles (e.g. arm.mak) with lots of common.mak
• Per-directory arm.mak file includes the top level arm.def
• Environment variables: MMLITE_SDK, BUILD_ROOT, ARM_TOOLS, KIND
Testing
• Lots of little regression tests [src/tests]
• Each one is pass/fail [calls DebugBreak()]
• All run in sequence [alltests.c], or by hand
• Normal startup code will run “init.exe”
• If you can run Doom you are not doomed