1 # Porting Lunaix to Other ISAs
3 This document briefly describe how to add support for other ISA
7 As of most modern operating system, Lunaix's abstraction layer allow
8 a clean separation between regular kernel code and the
9 architecture specific code, these parts defined as follow:
10 + kernel code: Provide the functionality of a kernel that do not assume
11 anything other than the kernel basic service and feature. This part of
12 code is thus said to be architecture-agnostic.
13 + architecture specific code: Provide implementation of low-level operations
14 or features required by the aforementioned kernel kernel basic service and
15 feature for them to function normally and expected.
19 Each architectural support is housed under the directory of
20 their respective name. For example, all support for x86 is
23 Aside from this, a special architecture
24 called `generic` is defined, which designed to be a fallback
25 option for any features/operations that are not being implemented or does not required to be implemented in architecture-specific way. However, not all feature/operations
26 have their respective fallback; In that case, presence of architectural support for these features/operations are mandatory.
28 Regardless, a typical architecture support must be a valid derivation of the following subdirectory layout:
42 + `asm` define all assembly level headers. These header is
43 typically designated to perform low-level architectural
44 tasks such as register manipulation, MMU/TLB
45 maintainance, SoC resource managment, or context saving/restoring.
46 + `sys` define all headers that is related to some kernel
47 service. These services, similar but unlike the **regular kernel code**, require architectural support or
48 optimisation. For example, syscall interfacing or cpu state dumping for debugging purpose.
49 + `linking` contain linker scripts that describe the linking
50 procedure for linking the architectural support with other subsystem such that a valid kernel binary can be produced. There is no limit on how many linker script can be put under it, however, only one specific linker script will be taken into account when linking, more detail as follow.
52 An implementation is required to follow this structure and must implement all mandatory header file, as described in the following section.
57 ### Mandatory and Optional Features
59 Lunaix provide bunch of headers that **MUST** be implemented in order to behave correctly.
63 includes/asm-generic/isrm.h
64 includes/asm/muldiv64.h
66 includes/asm/mempart.h
69 includes/asm/pagetable.h
71 includes/sys/syscall_utils.h
72 includes/sys/failsafe.h
73 includes/sys/gdbstub.h
74 includes/sys-generic/elf.h
77 An implementation should copy these file out of `arch/x86`, replacing any `x86` specific function-body/structure-members/macros with the chosen architecture.
79 Most headers located under `generic/` has default implementation and is designed to eliminate common code. The defaults can be optionally override, except for those with `fail()` as their only definition or those listed in above.
81 ### Preparing Linker Script
83 Lunaix use CC's preprocessing system on creating modularised linker script. Such linker scripts in denoted with 'ldx' as extension in contrast to the genuine one.
85 There is no limit on the number of linker scripts present. However, the following list the mandatory linker scripts required for an architectural support, as these scripts are referenced by the main script.
87 + `base_defs.ld.inc` Define the macros related to kernel
88 binary structure, the following macros are mandatory:
89 + `LOAD_OFF` base physical address of kernel when loaded into memory by firmware.
90 + `PAGE_GRAN` base page granule, used for section alignment
91 + `ENTRY_POINT` the entry point of kernel, where the firmware-kernel hand-off happened.
92 + `KEXEC_BASE` base virtual address of kernel, this define the boundary of kernel and user space.
93 + `boot_secs.ldx` Define the sections used by boot code, these section should be normally used without virtual address relocation. **Important: Implementation must not define variable-sized section such as .bss**
95 ### Booting and Initialising
97 Lunaix will always start the execution from entry point defined by `ENTRY_POINT` (see above section). A boot protocol might be invoked as earlier as possible in this stage. Such protocol defines the format and method to perform message exchange when firmware hand-over the control to the kernel. It is the implementation's responsibility for to decide whether such protocol is necessary and implement it accordingly.
99 After the completion of architectural tasks defined in boot stage, implementation must hand-over the control to the architecture-agnostic kernel entry-point: `kernel_bootstrap`, together with the an architecture-agnostically defined boot message structure: `struct boot_handoff` as the only parameter taken by the entry-point. In this structure, the implementation must provide **either** the following information:
101 1. `mem` sub-structure and pointer and length to the kernel command-line raw string.
102 2. `dtb_pa`, physical pointer to the devicetree blob (dtb) placed in memory. Fields stated in #1 will be ignored if `dtb_pa` is non-zero.
104 Implementation may also provide callback to `release` and `prepare` function pointer. Where the implementation-defined action can be performed before and after the kernel initialisation.
106 ### System-on-Chip Resources
108 Most of the SoC resources such as interrupt controller can be abstracted away by some mandatory headers defined in `asm/`, or as a regular device driver integrated into the Lunaix device subsystem. However, not all SoC resources can be fit into the said framework. The following list the such resources:
112 ### Architectural Optimisation on klibc
114 Most functions in `klibc` can be override by an architectural port. To achieve
115 this, one just need to add definition of such function. This allow port to
116 provide better performance on these library functions by exploiting the
117 architectural specific feature.
119 All non-static function from these header can be overriden: