mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-17 06:47:49 +00:00
Update testing posts
This commit is contained in:
@@ -103,12 +103,13 @@ Like with the [VGA text buffer][vga lazy-static], we use `lazy_static` and a spi
|
||||
To make the serial port easily usable, we add `serial_print!` and `serial_println!` macros:
|
||||
|
||||
```rust
|
||||
pub fn print(args: ::core::fmt::Arguments) {
|
||||
pub fn _print(args: ::core::fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
SERIAL1.lock().write_fmt(args).expect("Printing to serial failed");
|
||||
}
|
||||
|
||||
/// Prints to the host through the serial interface.
|
||||
#[macro_export]
|
||||
macro_rules! serial_print {
|
||||
($($arg:tt)*) => {
|
||||
$crate::serial::print(format_args!($($arg)*));
|
||||
@@ -116,10 +117,11 @@ macro_rules! serial_print {
|
||||
}
|
||||
|
||||
/// Prints to the host through the serial interface, appending a newline.
|
||||
#[macro_export]
|
||||
macro_rules! serial_println {
|
||||
() => (serial_print!("\n"));
|
||||
($fmt:expr) => (serial_print!(concat!($fmt, "\n")));
|
||||
($fmt:expr, $($arg:tt)*) => (serial_print!(concat!($fmt, "\n"), $($arg)*));
|
||||
() => ($crate::serial_print!("\n"));
|
||||
($fmt:expr) => ($crate::serial_print!(concat!($fmt, "\n")));
|
||||
($fmt:expr, $($arg:tt)*) => ($crate::serial_print!(concat!($fmt, "\n"), $($arg)*));
|
||||
}
|
||||
```
|
||||
|
||||
@@ -132,7 +134,8 @@ Now we can print to the serial interface in our `main.rs`:
|
||||
```rust
|
||||
// in src/main.rs
|
||||
|
||||
#[macro_use]
|
||||
use crate::serial_println;
|
||||
|
||||
mod serial;
|
||||
|
||||
#[cfg(not(test))]
|
||||
@@ -145,7 +148,7 @@ pub extern "C" fn _start() -> ! {
|
||||
}
|
||||
```
|
||||
|
||||
Note that we need to add the `#[macro_use]` attribute to the `mod serial` declaration, because otherwise the `serial_println` macro is not imported.
|
||||
Note that the `serial_println` macro lives directly under the root namespace because we used the `#[macro_export]` attribute, so importing it through `use crate::serial::serial_println` will not work.
|
||||
|
||||
### QEMU Arguments
|
||||
|
||||
@@ -371,7 +374,7 @@ Cargo supports hybrid projects that are both a library and a binary. We only nee
|
||||
```rust
|
||||
// src/lib.rs
|
||||
|
||||
#![no_std] // don't link the Rust standard library
|
||||
#![cfg_attr(not(test), no_std)] // don't link the Rust standard library
|
||||
|
||||
extern crate bootloader;
|
||||
extern crate spin;
|
||||
@@ -382,8 +385,6 @@ extern crate x86_64;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate array_init;
|
||||
#[cfg(test)]
|
||||
extern crate std;
|
||||
|
||||
// NEW: We need to add `pub` here to make them accessible from the outside
|
||||
pub mod vga_buffer;
|
||||
@@ -405,10 +406,10 @@ pub unsafe fn exit_qemu() {
|
||||
#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))]
|
||||
|
||||
// NEW: Add the library as dependency (same crate name as executable)
|
||||
#[macro_use]
|
||||
extern crate blog_os;
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use blog_os::println;
|
||||
|
||||
/// This function is the entry point, since the linker looks for a function
|
||||
/// named `_start` by default.
|
||||
@@ -429,29 +430,7 @@ fn panic(info: &PanicInfo) -> ! {
|
||||
}
|
||||
```
|
||||
|
||||
So we move everything except `_start` and `panic` to `lib.rs`, make the `vga_buffer` and `serial` modules public, and add an `extern crate` definition to our `main.rs`.
|
||||
|
||||
This doesn't compile yet, because Rust's macros are not exported over crate boundaries by default. To export our printing macros, we need to add the `#[macro_export]` attribute to them:
|
||||
|
||||
```rust
|
||||
// in src/vga_buffer.rs
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {…}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! println {…}
|
||||
|
||||
// in src/serial.rs
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! serial_print {…}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! serial_println {…}
|
||||
```
|
||||
|
||||
Now everything should work exactly as before, including `bootimage run` and `cargo test`.
|
||||
So we move everything except `_start` and `panic` to `lib.rs`, make the `vga_buffer` and `serial` modules public, and add an `extern crate` definition to our `main.rs`. Everything should work exactly as before, including `bootimage run` and `cargo test`.
|
||||
|
||||
### Test Basic Boot
|
||||
|
||||
@@ -465,11 +444,10 @@ We are finally able to create our first integration test executable. We start si
|
||||
#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))]
|
||||
|
||||
// add the library as dependency (same crate name as executable)
|
||||
#[macro_use]
|
||||
extern crate blog_os;
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use blog_os::exit_qemu;
|
||||
use blog_os::{exit_qemu, serial_println};
|
||||
|
||||
/// This function is the entry point, since the linker looks for a function
|
||||
/// named `_start` by default.
|
||||
@@ -529,11 +507,10 @@ To test that our panic handler is really invoked on a panic, we create a `test-p
|
||||
#![cfg_attr(not(test), no_main)]
|
||||
#![cfg_attr(test, allow(dead_code, unused_macros, unused_imports))]
|
||||
|
||||
#[macro_use]
|
||||
extern crate blog_os;
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use blog_os::exit_qemu;
|
||||
use blog_os::{exit_qemu, serial_println};
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[no_mangle]
|
||||
|
||||
Reference in New Issue
Block a user