Kernel

From S1MP3 Wiki
Jump to: navigation, search
This page contains statements not yet ratified and is classified as work in progress

Warning: This page may contain information which is out of date.

EXCUSE US...

Excuse us, this page is a total mess. It refers to something that is completely work in progress. You may adventure to read it if you are brave. We are working on this page, and we WILL fix it! --Wladston 21:41, 27 March 2008 (UTC)


Tasks Done

  • First Kernel Alpha version - This code is for showing the ideas that are here, and how they will work. It's for testing and IT ISN'T ac omplete firmware it's just a test. Download it from here: Download
  • API - Specification is released, we will use it as a guide for the development of the Kernel.
  • TASK SWITCHER - We will have two different Priority Level for tasks, Critical and Non-Critical.
  • WATCHDOG - A software watchdog will be implement so it will terminate any APP that stops respongding. Critical Tasks can change the Watchdog timer to take more time executed. Critical Tasks are System-Driver functions and trusted modules.
  • KERNEL CALLS - We will use Interrupts. The functions will be clasified in groups. The Z80 architecture allows us to have 8 differents software interrupts configured. Each interrupts will be one of the Groups of Functions. Group 0 will be System and Kernel Functions, Groups 1-5 are for drivers, and Group 6 is for API.
  • Key detection program : Started the new detection program, using as starting point the LCD detection program here is a demo that show the LCD functions, the shell system, Flash info, the Keys Detection Program, adn a new Demo the Memory Viewer. Download it Demos.zip. Now we are focused on writing the Kernel Specification
  • LCD Detect: Started and FINISHED!!! the Detect program for the LCD Port and Pin configuration(look at the TRAC) Well the DEMO was remved and the final release is done, now has Autodetection and Manual Detecion :D, try it Detect.zip and let us know how it works on your player.


Current approved way of calling Kernel and APIs functions.

A = Function (For Drivers only 7 low bits are valid, bit7 indicates wich Driver of the 2 drivers that are in one ISR is called)
Other Registers = Parameters
rst GROUP_ID

Groups of Functions

Finally we agree (BC and Kidscracker) we have decided to use a mix of both proposal, we won't use 1 RST for each device, but we neither use ony one for all, we've decided to agroup only two devices per rst, taht way we will have expansion posibilities for drivers, reduce the code for determining the function that is called and also leave room for API expansion (API in discussion).

Group Group_ID Description
Kernel 0x00 All functions of the Kernel
STDIO 0x08 Display Functions(LCD Modo/LCD Color/OLED/etc) / Keyboard
SOUNDIN 0x10 Mic / Radio
STORAGE_DSP 0x18 Storage Functions(NAND/Disk/etc) / DSP Functions
COMMUNICATION 0x20 USB Functions / I2C Functions
???? 0x28 Other Devices or the API (Actually in discussion, the API will be a concept or a reallity?)
USER 0x30 Function's loaded and registered by the user APP
Kernel 0x38 Hardware Maskable Interrupts Handler. It won't be used as we use the interrupt MODE1


Drivers (In discussion. We will have Drivers or they will be one piece with API and Kernel ? )

Drivers will be compiled together with the Kernel. Every Driver must give a a minimun group of functions and functionalities, any extra functionality not indicated as basic for it's type will be calificated as Enhaced (*Will need more explanation*)

  • Basic Functions
    • For ALL
      • getDriverInfo().- Returns the Type of Driver (DISPLAY,STORAGE,DSP,RADIO,etc), functionalities (If it has ENHACEMENTS or not)
      • initDriver(boolean useEnhaced).- Inits the driver and hardware that is asociated with it. It registers all its functions on the Global Functions Table for the Group 1(Drivers). Parameter useEnhaced indicates if extra functionalities are going to be used.
    • For Displays
      • ???.- ???

Memory

Every chunk of memory will have a header that contains all the necessary information of it, even the kernel and drivers, so the kernel will manage the memory and modules loaded. The Header will contain specific information for each type. The Type will be indicated by the MAGIC signature of the headers.

Candidates to Headers for the memory chunks:

Block Type String_ID Description
Kernel KRN→ Is the firs block allocated, it contains all the code and data of the Kernel, not including anything else.
Drivers DRV→ These Blocks contain driver code and data.
API Interface API→ Block that contains all the code and data of the API interface. (It will be loaded and unloaded???)
Aplications APP→ These Blocks has sub headers that contains info about the Code, Data and Stack used by it.
. . ..

Kernel Init Sequence

This is only an idea of what will do the kernel on the start-up (after it's loaded by the BREC). After accepted this will be used as the model for the coding phase of the kernel.

  1. Initiliase Basic Hardware
    1. Memory
    2. MCU Clock
    3. Hardware WatchDog
    4. Non Mascable Interrupts Service Routine (NMISR)
    5. All Interrupts (ISRs)
  2. Initialise Internal Data
    1. Kernel Stack
    2. Task's Stacks
    3. Tasks Queue
      ( To this point -> [KERNEL OK] )
  3. Call each Driver Install Function
    1. Display (LCD Mono/LCD Colour/OLED/etc.)
    2. Storage (NAND/Disk/etc.)
    3. DSP
    4. etc.
  4. Get Drivers Information
  5. Initialise Drivers
    1. Each Driver initialise Hardware and ISRs
      ( From here an APP will work using only Driver's functions )
  6. Load API from Storage
    1. (Note this isn't a file, it's part of the Firmware itself)
  7. Initialise API ISR
    ( From here any APP will work )
  8. Load Default APP (File Browser, Player,etc)
  9. Start Default APP
  10. Enter System Loop for Tasks

FOLLOWS OUT OF DATE CONTENT

Boot stage

We will have a boot record, like the original one, but our S1BREC (S1BootRECord) will:

  1. install the core API into ZRAM, included USB core API. At this point I hope we will know what TROM is and how to use it(maybe the perfect storage for core APIs?)
  2. perform some basic environment setup operations
  3. try to load system.ap (through a different hard-coded version of exec() that won't return to the caller) and show a critical error message if not present (also hard-coded)
  4. pass control to system.ap

system.ap will be under all points of view a normal high-level APPlication, but it will be one of the default in the Swan distribution. It can be a simple dummy APP (e.g. no real application but only a file explorer (pieces of code shared with fileman.ap, but compiled independently) which shows basic system info and allows to choose an application to execute) or the custom made APP that turns the player into whatever we want.

Run-Time Module Manager (RTMM) stage

While launching an application (see exec()), in the app_init(..) stage the OS has to take care of the application's needs. This is a hypotethical working scheme:

  • 1. the APP header will specify the needed high-level API modules (those not bound to the hardware) and the RTMM will load them from NAND moving on also the ZRAM_START_ADDR pointer so that it starts exactly after all the loaded API modules. In this stage eventual previously loaded modules are held/moved on in a smart way (if S1BREC has launched the APP there won't be any previously loaded modules). (ZRAM_START_ADDR will be like the 100h in ORG 100h)

Run-Time Dynamic Linker (RTDL) stage

  • 2. once the ZRAM_START_ADDR is defined, the RTDL will start its relocation job: considering the minimal value for ZRAM_START_ADDR (that will be the base absolute memory reference value used in the compiled APPlication), all absolute memory references will be fixed with the new ZRAM_START_ADDR.
  • 3. the RTDL will fix also the references of libraries to other libraries, using the same method as above (this step happens before the last, actually)
  • 4. we will have a general API jumptable stored in ZRAM at a fixed position immediately before ZRAM_START_ADDR. This jumptable will be updated depending on the loaded modules, while the core API functions (bound to hardware) will keep at fixed positions and compiled into the APPs.

In parallel with the jumptable, there will be a moduleref table defined as below:

  typedef struct S_apidef {
    ui8   unused;      // maybe a backup copy of module_id?
    ui8   param_sz;    // the parameters total size as they are passed
    ui16  addr;        // address of function body (always after ZRAM_START_ADDR+APP_SIZE)
  };
  struct {
    ui8        module_id;   // identifier of module
    struct S_apidef *apidef;      // pointer to the 1st api definition in jumptable
  } moduleref[TOTAL_LOADED_MODULES];
 struct apidef jumptable[TOTAL_LOADED_API_FUNCTIONS];
 // each TOTAL_* constant is determined at run-time by RTMM
  • 5. API Functions will be referenced (by RTDL) cardinally like in
  CALL        moduleref[module_id].apidef[function_id]

These are the possible ways an APP/module can call an API function:

    • using an interrupt
  LD     A, function_id
  LD     B, module_id
  LD     C, computed_param_sz
  INT    whatever
    • calling a RTMM special function located at a fixed address
  LD     A, function_id
  LD     B, module_id
  LD     C, computed_param_sz
  CALL   RTMM_api_query   ; this function will be part of the core low-level API
    • in the smartest/best way: the RTMM parses (in the relocation phase) a special sequence of HLTs (as many as needed for a absolute address CALL) followed by 2 bytes specifying (function_id, module_id and maybe computed_param_sz) and replaces it with the current absolute address of the API function. This way should also prevent the presence of explicit needed modules ids in the APP header because they should be identified while looking for the interested API functions.
  • 6. the application is actually called (see exec())

Errors that happen in the RTDL phase will be reported. Also, the RTMM will prevent API calls if param_sz is not matching the caller's specified parameters' size, if the function does not exist or if the module is not loaded.

Note: the above examples are about register calls, but also stack calls can be triggered

Related Pages