mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 22:37:49 +00:00
Update Linux/Windows/Mac entry points
This commit is contained in:
@@ -131,9 +131,8 @@ fn main() {}
|
|||||||
#[lang = "panic_fmt"]
|
#[lang = "panic_fmt"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
|
pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
|
||||||
_file: &'static str,
|
_file: &'static str, _line: u32, _column: u32) -> !
|
||||||
_line: u32,
|
{
|
||||||
_column: u32) -> ! {
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -213,7 +212,7 @@ On Linux, the default entry point is called `_start`. The linker just looks for
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn _start() -> ! {
|
pub extern fn _start() -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -260,16 +259,16 @@ One way to pass linker attributes via cargo is the `cargo rustc` command. The co
|
|||||||
With this command, our crate builds again as a freestanding executable!
|
With this command, our crate builds again as a freestanding executable!
|
||||||
|
|
||||||
#### Windows
|
#### Windows
|
||||||
On Windows, the linker requires two entry points: `WinMain` and `WinMainCRTStartup`. The one that actually is called is `WinMainCRTStartup`. Like on Linux, we overwrite the entry points by defining `no_mangle` functions:
|
On Windows, the linker requires two entry points: `WinMain` and `WinMainCRTStartup`, [depending on the used subsystem](https://msdn.microsoft.com/en-us/library/f9t8842e.aspx). Like on Linux, we overwrite the entry points by defining `no_mangle` functions:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn WinMainCRTStartup() -> ! {
|
pub extern fn WinMainCRTStartup() -> ! {
|
||||||
WinMain();
|
WinMain();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn WinMain() -> ! {
|
pub extern fn WinMain() -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -277,7 +276,23 @@ pub fn WinMain() -> ! {
|
|||||||
We just call `WinMain` from `WinMainCRTStartup` to avoid any ambiguity which function is called.
|
We just call `WinMain` from `WinMainCRTStartup` to avoid any ambiguity which function is called.
|
||||||
|
|
||||||
#### OS X
|
#### OS X
|
||||||
TODO: I don't have access to a Mac at the moment. In case you know the entry point procedure on Mac and would like to help, please send a pull request!
|
Mac OS X [does not support statically linked binaries], so we have to link the `libSystem` library. The entry point is the called `main`:
|
||||||
|
|
||||||
|
[does not support statically linked binaries]: https://developer.apple.com/library/content/qa/qa1118/_index.html
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern fn main() -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To build it and link `libSystem`, we execute:
|
||||||
|
|
||||||
|
```
|
||||||
|
> cargo rustc -- -Z pre-link-arg=-lSystem
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
@@ -300,7 +315,7 @@ pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
|
|||||||
|
|
||||||
// On Linux:
|
// On Linux:
|
||||||
#[no_mangle] // don't mangle the name of this function
|
#[no_mangle] // don't mangle the name of this function
|
||||||
pub fn _start() -> ! {
|
pub extern fn _start() -> ! {
|
||||||
// this function is the entry point, since the linker looks for a function
|
// this function is the entry point, since the linker looks for a function
|
||||||
// named `_start_` by default
|
// named `_start_` by default
|
||||||
loop {}
|
loop {}
|
||||||
@@ -308,17 +323,21 @@ pub fn _start() -> ! {
|
|||||||
|
|
||||||
// On Windows:
|
// On Windows:
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn WinMainCRTStartup() -> ! {
|
pub extern fn WinMainCRTStartup() -> ! {
|
||||||
WinMain();
|
WinMain();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn WinMain() -> ! {
|
pub extern fn WinMain() -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On Mac:
|
// On Mac:
|
||||||
// TODO
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern fn main() -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
`Cargo.toml`:
|
`Cargo.toml`:
|
||||||
@@ -340,8 +359,13 @@ panic = "abort" # disable stack unwinding on panic
|
|||||||
|
|
||||||
It can be compiled with:
|
It can be compiled with:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
cargo rustc -- -Z pre-link-arg=-nostartfiles
|
# Linux
|
||||||
|
> cargo rustc -- -Z pre-link-arg=-nostartfiles
|
||||||
|
# Windows
|
||||||
|
> cargo build
|
||||||
|
# Mac
|
||||||
|
> cargo rustc -- -Z pre-link-arg=-lSystem
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that this is just a minimal example of a freestanding Rust binary. This binary expects various things, for example that a stack is initialized when the `_start` function is called. **So for any real use of such a binary, more steps are required**.
|
Note that this is just a minimal example of a freestanding Rust binary. This binary expects various things, for example that a stack is initialized when the `_start` function is called. **So for any real use of such a binary, more steps are required**.
|
||||||
|
|||||||
Reference in New Issue
Block a user