C Sharp: Difference between revisions

From OSDev Wiki
Jump to navigation Jump to search
mNo edit summary
(Updated to reflect the current state of C#, with the open-source .NET SDK (as opposed to the older .NET Framework))
Line 1: Line 1:
<p style="margin-left:2em; font-size:smaller;">Please note that the correct title of this article is C#, however because of technical restrictions it's called "C Sharp".</p>
<p style="margin-left:2em; font-size:smaller;">Please note that the correct title of this article is C#, however because of technical restrictions it's called "C Sharp".</p>


C# is an object-oriented programming language developed by (削除) Microsoft (削除ここまで)and standardized by the ECMA and ISO. Its syntax is similar to [[C++]], but with significant differences in functionality. (削除) It was designed to be used to create applications to run under Microsoft's .NET infrastructure. The idea was that it would be compiled (削除ここまで)into an intermediate bytecode language called [[CIL]] which was then just-in-time compiled into machine code by the .NET runtime. (削除) The runtime also provided several useful functions to the code with regards to garbage collection (削除ここまで), (削除) run (削除ここまで)time (削除) type information and dynamic (削除ここまで)compilation. (削除) (削除ここまで)A standard library (called (削除) mscorlib (削除ここまで)) (削除) would provide string (削除ここまで)and (削除) other data structure classes (similar to the stdlib (削除ここまで)in C(削除) ++) with calls into the Windows API for other tasks (predominantly I/O (削除ここまで), (削除) GUI and process and thread management) (削除ここまで).
C# is an object-oriented programming language developed by (追記) the .NET Foundation (追記ここまで)and standardized by the ECMA and ISO. Its syntax is similar to [[C++]], but with significant differences in functionality. (追記) Typically, source files written in C# compile (追記ここまで)into an intermediate bytecode language called [[CIL]] (追記) (also referred to as ''IL'') (追記ここまで)which was then just-in-time compiled into machine code by the .NET runtime. (追記) As of .NET 7 (追記ここまで), (追記) tradition ahead-of- (追記ここまで)time compilation (追記) is also available (追記ここまで). A standard library ((追記) also (追記ここまで)called (追記) a ''system module'' throughout .NET's tooling (追記ここまで)) (追記) provides well-known base classes, such as <code>System.Object</code>, (追記ここまで)and (追記) is automatically referenced by regular C# projects. For kernels written (追記ここまで)in C(追記) #, though (追記ここまで), (追記) a custom standard library usually needs to be provided (追記ここまで).
== Why write a kernel in C#? ==
== Why write a kernel in C#? ==


(削除) There are many disadvantages to (削除ここまで)writing a kernel in C#(削除) . Firstly, one would need to provide a substantial portion of both the runtime and the standard library along with some method of converting the kernel into machine code just to allow the kernel itself to run. Secondly direct memory access (削除ここまで)is (削除) difficult (although not impossible - see (削除ここまで)the (削除) 'unsafe' keyword for further information). The benefits are primarily those provided by (削除ここまで)type and memory safety. (削除) Given (削除ここまで)a (削除) CIL to native (削除ここまで)code (削除) compiler that works (削除ここまで)as (削除) expected, and without using the ' (削除ここまで)unsafe(削除) ' keyword (削除ここまで), it (削除) should (削除ここまで)be (削除) possible to write a kernel (削除ここまで)that (削除) guarantees against accessing code or data outside of certain pre-defined regions (削除ここまで). (削除) (削除ここまで)This idea can (削除) then (削除ここまで)be extended to (削除) all user programs which would prevent user programs attempting (削除ここまで)to (削除) access areas (削除ここまで)of (削除) the (削除ここまで)kernel (削除) that (削除ここまで)it (削除) is not allowed to or areas (削除ここまで)of (削除) other programs (削除ここまで). (削除) What this means is (削除ここまで)that (削除) you could theoretically (削除ここまで)run (削除) all programs (削除ここまで)in the same address space (削除) without them either accidentally or maliciously interfering (削除ここまで)with (削除) each other (削除ここまで), (削除) provided that (削除ここまで)the (削除) address space is big enough. It is probable (削除ここまで)that (削除) the expanded address space provided with x86_64 (削除ここまで)is (削除) large enough for this (削除ここまで).
(追記) The primary benefits of (追記ここまで)writing a kernel in C# is the type and memory safety (追記) the language provides (追記ここまで). (追記) If (追記ここまで)a (追記) region of (追記ここまで)code (追記) is not explicitly marked (追記ここまで)as (追記) <code> (追記ここまで)unsafe(追記) </code> (追記ここまで), it (追記) can (追記ここまで)be (追記) safely assumed (追記ここまで)that (追記) it will not perform any invalid memory accesses (追記ここまで). This idea can be extended to (追記) trivially formally verify a region of IL bytecode as being memory safe, simply by excluding certain instructions that are known (追記ここまで)to (追記) be unsafe. As a verified region (追記ここまで)of (追記) code is certain to be well-behaved, a (追記ここまで)kernel (追記) may run (追記ここまで)it (追記) without any kind (追記ここまで)of (追記) address space switching, nor protection ring changes (追記ここまで). (追記) Given the fact (追記ここまで)that (追記) two safe (or '''managed''') processes can (追記ここまで)run in the same address space(追記) , there exists potential for an extremely efficient implementation of a microkernel, as an IPC call would be equivalent to a plain function invocation. A similar concept has been explored in the [https://www4.cs.fau.de/Projects/JX/publications/jx-usenix.pdf JX Operating System] (追記ここまで)with (追記) Java - however (追記ここまで), (追記) it's important to make (追記ここまで)the (追記) distinction (追記ここまで)that (追記) Java manages dependencies in a fundamentally different way than C#, and (追記ここまで)is (追記) known to be more restrictive (追記ここまで).


(追記) The disadvantages of writing a C# kernel are the complexity needed for a custom standard library to properly function. In addition to regular functions one may find in the standard libraries of Rust or C, C# also requires the system module to provide a garbage collection implementation, as well as many internal datatypes that the Roslyn C# compiler (<code>csc</code>) uses for newer syntax features. Depending on the IL-to-native code compiler used, intrinsic features (which are often undocumented) also need to be implemented. (追記ここまで)


(追記) Writing a C# kernel also requires a capable GC. A good choice for a garbage collector living in kernel-mode would be an on-the-fly GC, which only needs to stop one thread at a time. This can happen when the thread is idle (e.g. waiting for an I/O operation to complete), meaning no noticable pause is made to the thread's execution. The kernel's code should also avoid unnecessary allocations that may stress the GC; for example, instead of allocating a temporary buffer with <code>var example = new int[16]</code>, a better solution would be to use a small stack allocation, e.g. <code>Span<int> example = stackalloc int[16]</code>. Another viable option is to use custom pool/allocation functions. As of C# 8.0, you may use the disposable ref structs feature to safely and automatically free temporary buffers that are retrieved with such methods, similar to C++'s RAII. Both stack-allocated memory and pool/custom allocation functionality bypass the GC. (追記ここまで)
== Compiling your kernel to machine code ==
== Compiling your kernel to machine code ==


There are two approaches one could take to converting C# code to machine code:
There are two approaches one could take to converting C# code to machine code:


(削除) 1) Write (削除ここまで)a compiler which converts C# (or a superset of it) (削除) directly (削除ここまで)to machine code. (削除) (削除ここまで)This is the approach taken by Microsoft's research OS, [http://research.microsoft.com/en-us/projects/singularity/ Singularity], which defines the [http://en.wikipedia.org/wiki/Sing_Sharp Sing# language] for easier interaction with the underlying hardware. (削除) (削除ここまで)The Sing# code is converted to machine code by their compiler, [http://en.wikipedia.org/wiki/Bartok_%28compiler%29 Bartok].
(追記) # Use (追記ここまで)a compiler which (追記) directly (追記ここまで)converts C# (or a superset of it) to machine code. This is the approach taken by Microsoft's research OS, [http://research.microsoft.com/en-us/projects/singularity/ Singularity], which defines the [http://en.wikipedia.org/wiki/Sing_Sharp Sing# language] for easier interaction with the underlying hardware. The Sing# code is converted to machine code by their compiler, [http://en.wikipedia.org/wiki/Bartok_%28compiler%29 Bartok(追記) ]. (追記ここまで)
(追記) # Create a compiler which converts CIL to machine code. This leverages the C# to CIL compilers already present in .NET or the Mono project. This is the approach taken by many open source C# kernels, including [[squeak:projects/sharpos/|SharpOS]], [http://www.gocosmos.org/index.en.aspx Cosmos], [http://www.mosa-project.org/ the MOSA project] and [https://github.com/jncronin/tysos tysos (追記ここまで)].


(削除) 2 (削除ここまで)) (削除) Write a (削除ここまで)compiler which (削除) converts CIL (削除ここまで)to (削除) machine code (削除ここまで). (削除) This leverages the C# to CIL compilers already present in Microsoft (削除ここまで).(削除) NET or the mono project (削除ここまで). (削除) This (削除ここまで)is the (削除) approach taken by many open source C# kernels, including [http://sourceforge (削除ここまで).(削除) net/projects/sharpos/ SharpOS] (削除ここまで), (削除) [http://www.gocosmos.org/index.en.aspx Cosmos], [http://www.mosa-project.org/ the MOSA project] (削除ここまで)and (削除) [https://github.com/jncronin/tysos tysos] (削除ここまで).
(追記) Both of the above approaches could be performed ahead-of-time (AOT (追記ここまで)) (追記) or just-in-time (JIT). The AOT approach is simpler to begin with - you have your (追記ここまで)compiler (追記) running on your development system (追記ここまで)which (追記) is used (追記ここまで)to (追記) produce executable files (e (追記ここまで).(追記) g (追記ここまで). (追記) [[ELF]]) which can then be loaded directly by a standard bootloader (追記ここまで). (追記) A JIT design would require a not insubstantial amount of code that (追記ここまで)is (追記) loaded before your kernel which then converts your kernel into machine code before running it. The problem here is that (追記ここまで)the (追記) JIT compiler would likely need a lot of services which only your kernel could compile (追記ここまで). (追記) The best combination is probably to AOT compile your kernel and JIT compiler and have them loaded (追記ここまで), and (追記) then all other processes can be JIT compiled (追記ここまで).


(削除) In addition, both of the above approaches could be performed ahead-of-time ( (削除ここまで)AOT(削除) ) or just (削除ここまで)-in(削除) -time (JIT). The AOT approach is probably simpler (削除ここまで)to (削除) begin with - you have your compiler running on your development system which is used to produce executable files (e (削除ここまで).(削除) g (削除ここまで). (削除) [[ELF]]) which can then be loaded directly by a standard bootloader (削除ここまで). (削除) A JIT design would require a not insubstantial amount of code that is loaded before your kernel which then converts your kernel into machine code before running (削除ここまで)it(削除) . The problem here is that the JIT compiler would likely need a lot of services which only your kernel could compile. The best combination is probably to AOT compile your kernel and JIT compiler and have them loaded (削除ここまで), (削除) and then all other processes (削除ここまで)can (削除) be JIT compiled. (削除ここまで)
(追記) An (追記ここまで)AOT (追記) compiler is built (追記ここまで)-in to .(追記) NET >=7 (追記ここまで).(追記) 0 (追記ここまで). (追記) In order to use (追記ここまで)it, (追記) you (追記ここまで)can(追記) : (追記ここまで)


(削除) == (削除ここまで)The (削除) runtime == (削除ここまで)
(追記) * Use <code>ilc</code> - the IL compiler, internally used for Native AOT (NAOT) compilation, provided by .NET >7.0. ILC may be invoked manually by installing the .NET tool with <code>dotnet tool install -g ilc</code>. (追記ここまで)The (追記) compiler accepts managed CLR assemblies, in the form of DLL files. You can get such files by compiling your C# source code with <code>csc</code>, which can be installed the same way as ILC. (追記ここまで)
(追記) * Use Native AOT deployment provided by the .NET build system. Note that this will require large amounts of tweaking in order to customize the default Linux/Windows build rules. For an example, the [https://github.com/MichalStrehovsky/zerosharp ZeroSharp: C# for systems programming] demonstration may be of interest. The repository only uses features that are built-in to .NET. (追記ここまで)


(削除) Several C# commands (or their equivalent in CIL) require (削除ここまで)a (削除) functioning runtime (Microsoft calls this (削除ここまで)the (削除) Virtual Execution System (削除ここまで), (削除) or VES) (削除ここまで). (削除) For example, the expected result of the (削除ここまで)'(削除) newobj (削除ここまで)' (削除) CIL command is to create an object on a garbage managed heap (削除ここまで). (削除) This would require a malloc function and then some method to perform gargabe collection on the heap. With clever coding (mainly using static or stack (削除ここまで)-(削除) defined objects), (削除ここまで)it (削除) is possible to have your kernel not use (削除ここまで)the (削除) newobj command until you have set up a heap and malloc function (削除ここまで).
(追記) Alternatively, for (追記ここまで)a (追記) more streamlined experience, (追記ここまで)the (追記) [https://github.com/bflattened/bflat/ bflat] toolchain provides a simple way to use ILC (追記ここまで), (追記) alongside a simple, systems-programming-oriented "zerolib" standard library (追記ここまで). (追記) It automatically interfaces with ILC. Do note that bflat is ''not (追記ここまで)'' (追記) integrated with (追記ここまで).(追記) NET (追記ここまで)- it (追記) also uses its a seperate version of (追記ここまで)the (追記) Roslyn C# compiler (追記ここまで).


(削除) You will also need to provide an encapsulation of the run-time type information for a class and some way to implement the System.Object.GetType() and typeof() functions to return a class semantically equivalent to System.Type. (削除ここまで)
(追記) == The runtime == (追記ここまで)


(追記) Several C# commands (or their equivalent in CIL) require a functioning runtime (in .NET, called the CLR - the Common Language Runtime). For example, the expected result of the <code>newobj</code> CIL command is to create an object on a garbage managed heap. This would require a <code>malloc</code> function and then some method to perform garbage collection on the heap. With clever coding (mainly using static or stack-defined objects), it is possible to have your kernel not use the newobj command until you have initialized your memory allocator. (追記ここまで)


(追記) You may also need to provide an encapsulation of the run-time type information for a class and some way to implement the <code>System.Object.GetType()</code> and <code>typeof()</code> functions to return a class semantically equivalent to <code>System.Type</code>. This is not necessarily required when using Native AOT (ILC) compilation. (追記ここまで)
== The standard library ==
== The standard library ==


(削除) Mscorlib.dll (削除ここまで)is a basic component of the .NET runtime and provides definitions of all the standard types (e.g. System.Int32 for a 32-bit signed integer, System.String for a string, System.Collections.Generic.List<T> for a list of objects of type (削除) ' (削除ここまで)T(削除) ' (削除ここまで)). (削除) (削除ここまで)To write any sort of meaningful code in your kernel you are probably going to need to provide implementations (削除) of (削除ここまで)most of these. (削除) Options are: (削除ここまで)
(追記) The standard library (追記ここまで)is a basic component of the .NET runtime and provides definitions of all the standard types (e.g. (追記) <code> (追記ここまで)System.Int32(追記) </code> (追記ここまで)for a 32-bit signed integer, (追記) <code> (追記ここまで)System.String(追記) </code> (追記ここまで)for a string, (追記) <code> (追記ここまで)System.Collections.Generic.List<T(追記) ></code (追記ここまで)> for a list of objects of type (追記) <code> (追記ここまで)T(追記) </code> (追記ここまで)). To write any sort of meaningful code in your kernel(追記) , (追記ここまで)you are probably going to need to provide implementations (追記) for (追記ここまで)most of these.
(削除) 1) Attempt to compile the Microsoft mscorlib.dll with your compiler. I strongly recommend that anyone who considers this please check all the legal implications prior to doing it. You have been warned. (削除ここまで)
(削除) 2) Use the corlib provided by the [http://www.mono-project.com/Main_Page Mono project]. Note that a lot of the functions in their implementation are marked either 'InternalCall' or 'PInvoke'. What these mean is that you have to provide an implementation of the function, either as a compiler builtin or provided by your kernel. The library is quite complex and large, however, and you will need to make sure your compiler produces accurate code for every function - unit tests are your friend here. (削除ここまで)
(削除) 3) Write your own basic corlib containing only those functions you need. (削除ここまで)
(削除) 4) Don't use a corlib library - as long as you don't try and use any of the functions contained in it within your kernel you should be okay. There is nothing stating that because you use C# to write your kernel you have to use the corlib library. (削除ここまで)
(削除) == Summary == (削除ここまで)


(削除) Whilst is (削除ここまで)is possible (削除) to write a kernel in C# (as many of the projects listed above have demonstrated) (削除ここまで), it is not (削除) something that (currently) can be done quickly. You will need a combination (削除ここまで)of kernel(削除) , compiler, runtime and standard library to get (削除ここまで)it running (削除) properly. It may (削除ここまで), (削除) however, be possible to re-use the compiler (削除ここまで)and (削除) standard library used in many of the projects listed above once they have reached sufficient maturity, so (削除ここまで)that (削除) 'all' you need to do is write the kernel and some memory management functions. Please note (削除ここまで), (削除) however (削除ここまで), (削除) that most (削除ここまで)of the (削除) ahead-of-time compilers used in these projects are closely tied (削除ここまで)to (削除) the (削除ここまで)operating system (削除) they are being used to develop. If you choose to write your own compiler, be warned: to paraphrase [[Languages]] (削除ここまで)- (削除) writing a compiler is as hard if not harder than writing a kernel (削除ここまで).
(追記) While using the BCL (Base Class Library - .NET's standard library) (追記ここまで)is (追記) theoretically (追記ここまで)possible, it is (追記) generally (追記ここまで)not (追記) suited for any kind (追記ここまで)of kernel (追記) development - (追記ここまで)it (追記) assumes that the (追記ここまで)running (追記) program is in user-mode (追記ここまで), and that (追記) most system facilities (追記ここまで), (追記) such as file I/O (追記ここまで), (追記) are already configured. Projects such as Cosmos handle this by selectively patching certain methods (追記ここまで)of the (追記) BCL which use code intrinsic (追記ここまで)to (追記) select (追記ここまで)operating system - (追記) called ''plugging'' (追記ここまで).


(削除) Part (削除ここまで)of (削除) reason it is not so simple is (削除ここまで)that (削除) all current C# compilers output MSIL or .NET bytecode, which involves an extra step (削除ここまで)to (削除) convert it to machine code (削除ここまで). (削除) However (削除ここまで), (削除) it would be theoretically possible that one day somebody produces a C# frontend for GCC (so (削除ここまで)you can (削除) compile GCC straight to raw machine code) and this would be a completely different story (削除ここまで).
(追記) Writing a custom core library more suitable for kernel-mode programming is a better solution - the amount (追記ここまで)of (追記) classes (追記ここまで)that (追記) need (追記ここまで)to (追記) be implemented depends on the toolset used (追記ここまで). (追記) For reference (追記ここまで), you can (追記) use [https://github.com/bflattened/bflat/tree/master/src/zerolib bflat's minimal runtime library] (追記ここまで).


== See Also ==
== See Also ==
Line 52: Line 45:
=== External Links ===
=== External Links ===
* [http://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29 C#] on Wikipedia
* [http://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29 C#] on Wikipedia
(追記) * [https://flattened.net/ bflat - C# as you know it but with Go-inspired tooling] (追記ここまで)


[[Category:Languages]]
[[Category:Languages]]
[[Category:CSharp]]
[[Category:CSharp]]

Revision as of 09:40, 12 August 2024

Please note that the correct title of this article is C#, however because of technical restrictions it's called "C Sharp".

C# is an object-oriented programming language developed by the .NET Foundation and standardized by the ECMA and ISO. Its syntax is similar to C++, but with significant differences in functionality. Typically, source files written in C# compile into an intermediate bytecode language called CIL (also referred to as IL) which was then just-in-time compiled into machine code by the .NET runtime. As of .NET 7, tradition ahead-of-time compilation is also available. A standard library (also called a system module throughout .NET's tooling) provides well-known base classes, such as System.Object, and is automatically referenced by regular C# projects. For kernels written in C#, though, a custom standard library usually needs to be provided.

Why write a kernel in C#?

The primary benefits of writing a kernel in C# is the type and memory safety the language provides. If a region of code is not explicitly marked as unsafe, it can be safely assumed that it will not perform any invalid memory accesses. This idea can be extended to trivially formally verify a region of IL bytecode as being memory safe, simply by excluding certain instructions that are known to be unsafe. As a verified region of code is certain to be well-behaved, a kernel may run it without any kind of address space switching, nor protection ring changes. Given the fact that two safe (or managed) processes can run in the same address space, there exists potential for an extremely efficient implementation of a microkernel, as an IPC call would be equivalent to a plain function invocation. A similar concept has been explored in the JX Operating System with Java - however, it's important to make the distinction that Java manages dependencies in a fundamentally different way than C#, and is known to be more restrictive.

The disadvantages of writing a C# kernel are the complexity needed for a custom standard library to properly function. In addition to regular functions one may find in the standard libraries of Rust or C, C# also requires the system module to provide a garbage collection implementation, as well as many internal datatypes that the Roslyn C# compiler (csc) uses for newer syntax features. Depending on the IL-to-native code compiler used, intrinsic features (which are often undocumented) also need to be implemented.

Writing a C# kernel also requires a capable GC. A good choice for a garbage collector living in kernel-mode would be an on-the-fly GC, which only needs to stop one thread at a time. This can happen when the thread is idle (e.g. waiting for an I/O operation to complete), meaning no noticable pause is made to the thread's execution. The kernel's code should also avoid unnecessary allocations that may stress the GC; for example, instead of allocating a temporary buffer with var example = new int[16], a better solution would be to use a small stack allocation, e.g. Span<int> example = stackalloc int[16]. Another viable option is to use custom pool/allocation functions. As of C# 8.0, you may use the disposable ref structs feature to safely and automatically free temporary buffers that are retrieved with such methods, similar to C++'s RAII. Both stack-allocated memory and pool/custom allocation functionality bypass the GC.

Compiling your kernel to machine code

There are two approaches one could take to converting C# code to machine code:

  1. Use a compiler which directly converts C# (or a superset of it) to machine code. This is the approach taken by Microsoft's research OS, Singularity, which defines the Sing# language for easier interaction with the underlying hardware. The Sing# code is converted to machine code by their compiler, Bartok.
  2. Create a compiler which converts CIL to machine code. This leverages the C# to CIL compilers already present in .NET or the Mono project. This is the approach taken by many open source C# kernels, including SharpOS, Cosmos, the MOSA project and tysos.

Both of the above approaches could be performed ahead-of-time (AOT) or just-in-time (JIT). The AOT approach is simpler to begin with - you have your compiler running on your development system which is used to produce executable files (e.g. ELF) which can then be loaded directly by a standard bootloader. A JIT design would require a not insubstantial amount of code that is loaded before your kernel which then converts your kernel into machine code before running it. The problem here is that the JIT compiler would likely need a lot of services which only your kernel could compile. The best combination is probably to AOT compile your kernel and JIT compiler and have them loaded, and then all other processes can be JIT compiled.

An AOT compiler is built-in to .NET >=7.0. In order to use it, you can:

  • Use ilc - the IL compiler, internally used for Native AOT (NAOT) compilation, provided by .NET >7.0. ILC may be invoked manually by installing the .NET tool with dotnet tool install -g ilc. The compiler accepts managed CLR assemblies, in the form of DLL files. You can get such files by compiling your C# source code with csc, which can be installed the same way as ILC.
  • Use Native AOT deployment provided by the .NET build system. Note that this will require large amounts of tweaking in order to customize the default Linux/Windows build rules. For an example, the ZeroSharp: C# for systems programming demonstration may be of interest. The repository only uses features that are built-in to .NET.

Alternatively, for a more streamlined experience, the bflat toolchain provides a simple way to use ILC, alongside a simple, systems-programming-oriented "zerolib" standard library. It automatically interfaces with ILC. Do note that bflat is not integrated with .NET - it also uses its a seperate version of the Roslyn C# compiler.

The runtime

Several C# commands (or their equivalent in CIL) require a functioning runtime (in .NET, called the CLR - the Common Language Runtime). For example, the expected result of the newobj CIL command is to create an object on a garbage managed heap. This would require a malloc function and then some method to perform garbage collection on the heap. With clever coding (mainly using static or stack-defined objects), it is possible to have your kernel not use the newobj command until you have initialized your memory allocator.

You may also need to provide an encapsulation of the run-time type information for a class and some way to implement the System.Object.GetType() and typeof() functions to return a class semantically equivalent to System.Type. This is not necessarily required when using Native AOT (ILC) compilation.

The standard library

The standard library is a basic component of the .NET runtime and provides definitions of all the standard types (e.g. System.Int32 for a 32-bit signed integer, System.String for a string, System.Collections.Generic.List<T> for a list of objects of type T). To write any sort of meaningful code in your kernel, you are probably going to need to provide implementations for most of these.

While using the BCL (Base Class Library - .NET's standard library) is theoretically possible, it is generally not suited for any kind of kernel development - it assumes that the running program is in user-mode, and that most system facilities, such as file I/O, are already configured. Projects such as Cosmos handle this by selectively patching certain methods of the BCL which use code intrinsic to select operating system - called plugging.

Writing a custom core library more suitable for kernel-mode programming is a better solution - the amount of classes that need to be implemented depends on the toolset used. For reference, you can use bflat's minimal runtime library.

See Also

Articles

External Links

Retrieved from "https://wiki.osdev.org/index.php?title=C_Sharp&oldid=29215"