写在前面

本随笔是非常菜的菜鸡写的。如有问题请及时提出。

可以联系:1160712160@qq.com

GitHhub:https://github.com/WindDevil (目前啥也没有

批处理操作系统的启动和运行流程

要想把本章实现的那些模块全部都串联在一起以实现运行一个批处理操作系统,回顾本章内容,思考批处理操作系统的运行流程.

可以看到本章完成的内容大概如图所示:

可以看到在内核层,最重要的就是实现了batch来加载程序和切换程序,以及trap用来处理用户层的请求.

因此,我们只需要在main.rs中添加这两个模块的初始化即可.

编写main.rs

主要是三部分:

  1. 引入上述编写模块

    1. 嵌入link_app.S
    2. 引入batch,trap,syscall
  2. 初始化模块
  3. 开始运行用户态APP

需要添加的内容就这么多:

pub mod batch;
pub mod syscall;
pub mod trap; global_asm!(include_str!("link_app.S"));
pub fn rust_main() -> ! {
trap::init();
batch::init();
batch::run_next_app();
}

最终实现的main.rs:

//! The main module and entrypoint
//!
//! Various facilities of the kernels are implemented as submodules. The most
//! important ones are:
//!
//! - [`trap`]: Handles all cases of switching from userspace to the kernel
//! - [`syscall`]: System call handling and implementation
//!
//! The operating system also starts in this module. Kernel code starts
//! executing from `entry.asm`, after which [`rust_main()`] is called to
//! initialize various pieces of functionality. (See its source code for
//! details.)
//!
//! We then call [`batch::run_next_app()`] and for the first time go to
//! userspace. #![deny(missing_docs)]
#![deny(warnings)]
#![no_std]
#![no_main]
#![feature(panic_info_message)] use core::arch::global_asm; use log::*;
#[macro_use]
mod console;
pub mod batch;
mod lang_items;
mod logging;
mod sbi;
mod sync;
pub mod syscall;
pub mod trap; global_asm!(include_str!("entry.asm"));
global_asm!(include_str!("link_app.S")); /// clear BSS segment
fn clear_bss() {
extern "C" {
fn sbss();
fn ebss();
}
unsafe {
core::slice::from_raw_parts_mut(sbss as usize as *mut u8, ebss as usize - sbss as usize)
.fill(0);
}
} /// the rust entry-point of os
#[no_mangle]
pub fn rust_main() -> ! {
extern "C" {
fn stext(); // begin addr of text segment
fn etext(); // end addr of text segment
fn srodata(); // start addr of Read-Only data segment
fn erodata(); // end addr of Read-Only data ssegment
fn sdata(); // start addr of data segment
fn edata(); // end addr of data segment
fn sbss(); // start addr of BSS segment
fn ebss(); // end addr of BSS segment
fn boot_stack_lower_bound(); // stack lower bound
fn boot_stack_top(); // stack top
}
clear_bss();
logging::init();
println!("[kernel] Hello, world!");
trace!(
"[kernel] .text [{:#x}, {:#x})",
stext as usize,
etext as usize
);
debug!(
"[kernel] .rodata [{:#x}, {:#x})",
srodata as usize, erodata as usize
);
info!(
"[kernel] .data [{:#x}, {:#x})",
sdata as usize, edata as usize
);
warn!(
"[kernel] boot_stack top=bottom={:#x}, lower_bound={:#x}",
boot_stack_top as usize, boot_stack_lower_bound as usize
);
error!("[kernel] .bss [{:#x}, {:#x})", sbss as usize, ebss as usize);
trap::init();
batch::init();
batch::run_next_app();
}

编译运行

使用第一章就编写好的Makefile文件实现一键编译运行:

cd os
make run

第一次编译运行:

error: expected expression, found keyword `extern`
--> src/batch.rs:94:13
|
94 | extern "C"
| ^^^^^^ expected expression error: cannot find macro `asm` in this scope
--> src/batch.rs:84:9
|
84 | asm!("fence.i")
| ^^^
|
help: consider importing this macro
|
1 + use core::arch::asm;
| error: cannot find macro `global_asm` in this scope
--> src/trap/mod.rs:3:1
|
3 | global_asm!(include_str!("trap.S"));
| ^^^^^^^^^^
|
help: consider importing one of these items
|
3 + use core::arch::global_asm;
|
3 + use crate::global_asm;
| error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:34:36
|
34 | pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
| ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:34:65
|
34 | pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
| ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:35:60
|
35 | let cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
| ^^^^^^^^^^^ not found in this scope
|
help: you might be missing a type parameter
|
30 | impl<TrapContext> KernelStack {
| +++++++++++++ error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:35:84
|
35 | let cx_ptr = (self.get_sp() - core::mem::size_of::<TrapContext>()) as *mut TrapContext;
| ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `RefCell` in this scope
--> src/sync/up.rs:5:12
|
5 | inner: RefCell<T>,
| ^^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use core::cell::RefCell;
| error[E0433]: failed to resolve: use of undeclared type `RefCell`
--> src/sync/up.rs:14:23
|
14 | Self { inner: RefCell::new(value) }
| ^^^^^^^ use of undeclared type `RefCell`
|
help: consider importing this struct
|
3 + use core::cell::RefCell;
| error[E0412]: cannot find type `RefMut` in this scope
--> src/sync/up.rs:17:39
|
17 | pub fn exclusive_access(&self) -> RefMut<'_, T> {
| ^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use core::cell::RefMut;
| error[E0412]: cannot find type `TrapContext` in this scope
--> src/trap/mod.rs:13:30
|
13 | pub fn trap_handler(cx: &mut TrapContext) -> &mut TrapContext {
| ^^^^^^^^^^^ not found in this scope error[E0412]: cannot find type `TrapContext` in this scope
--> src/trap/mod.rs:13:51
|
13 | pub fn trap_handler(cx: &mut TrapContext) -> &mut TrapContext {
| ^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `syscall` in this scope
--> src/trap/mod.rs:19:24
|
19 | cx.x[10] = syscall(cx.x[17], [cx.x[10], cx.x[11], cx.x[12]]) as usize;
| ^^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use crate::syscall::syscall;
| error[E0425]: cannot find function `run_next_app` in this scope
--> src/trap/mod.rs:24:13
|
24 | run_next_app();
| ^^^^^^^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use crate::batch::run_next_app;
| error[E0425]: cannot find function `run_next_app` in this scope
--> src/trap/mod.rs:28:13
|
28 | run_next_app();
| ^^^^^^^^^^^^ not found in this scope
|
help: consider importing this function
|
3 + use crate::batch::run_next_app;
| error[E0425]: cannot find function `init` in module `batch`
--> src/main.rs:88:12
|
88 | batch::init();
| ^^^^ not found in `batch`
|
help: consider importing one of these items
|
23 + use crate::logging::init;
|
23 + use crate::trap::init;
|
help: if you import `init`, refer to it directly
|
88 - batch::init();
88 + init();
| error[E0308]: mismatched types
--> src/batch.rs:80:41
|
80 | core::slice::from_raw_parts_mut(APP_BASE_ADDRESS as *const u8, APP_SIZE_LIMIT).fill(0);
| ------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
| |
| arguments to this function are incorrect
|
= note: expected raw pointer `*mut _`
found raw pointer `*const u8`
note: function defined here
--> /home/winddevil/.rustup/toolchains/nightly-2024-05-01-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/raw.rs:147:21
|
147 | pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
| ^^^^^^^^^^^^^^^^^^ error[E0599]: the method `get` exists for struct `Lazy<UPSafeCell<AppManager>>`, but its trait bounds were not satisfied
--> src/batch.rs:88:1
|
88 | / lazy_static!
89 | | {
90 | | static ref APP_MANAGER: UPSafeCell<AppManager> = unsafe
91 | | {
... |
110 | | };
111 | | }
| |_^ method cannot be called on `Lazy<UPSafeCell<AppManager>>` due to unsatisfied trait bounds
|
::: src/sync/up.rs:3:1
|
3 | pub struct UPSafeCell<T> {
| ------------------------ doesn't satisfy `UPSafeCell<AppManager>: Sized`
|
= note: the following trait bounds were not satisfied:
`{type error}: Sized`
which is required by `UPSafeCell<AppManager>: Sized`
= note: this error originates in the macro `__lazy_static_internal` which comes from the expansion of the macro `lazy_static` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0433]: failed to resolve: use of undeclared type `TrapContext`
--> src/batch.rs:126:13
|
126 | TrapContext::app_init_context(APP_BASE_ADDRESS, USER_STACK.get_sp())
| ^^^^^^^^^^^ use of undeclared type `TrapContext` error[E0425]: cannot find function `sys_write` in this scope
--> src/syscall/mod.rs:5:26
|
5 | SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
| ^^^^^^^^^ not found in this scope error[E0425]: cannot find function `sys_exit` in this scope
--> src/syscall/mod.rs:6:25
|
6 | SYSCALL_EXIT => sys_exit(args[0] as i32),
| ^^^^^^^^ not found in this scope error[E0433]: failed to resolve: use of undeclared crate or module `stvec`
--> src/trap/mod.rs:8:9
|
8 | stvec::write(__alltraps as usize, TrapMode::Direct);
| ^^^^^ use of undeclared crate or module `stvec` error[E0433]: failed to resolve: use of undeclared type `TrapMode`
--> src/trap/mod.rs:8:43
|
8 | stvec::write(__alltraps as usize, TrapMode::Direct);
| ^^^^^^^^ use of undeclared type `TrapMode` error[E0433]: failed to resolve: use of undeclared crate or module `scause`
--> src/trap/mod.rs:14:18
|
14 | let scause = scause::read();
| ^^^^^^ use of undeclared crate or module `scause` error[E0433]: failed to resolve: use of undeclared crate or module `stval`
--> src/trap/mod.rs:15:17
|
15 | let stval = stval::read();
| ^^^^^ use of undeclared crate or module `stval` error: unused variable: `metadata`
--> src/logging.rs:9:23
|
9 | fn enabled(&self, metadata: &Metadata) -> bool
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_metadata`
|
note: the lint level is defined here
--> src/main.rs:18:9
|
18 | #![deny(warnings)]
| ^^^^^^^^
= note: `#[deny(unused_variables)]` implied by `#[deny(warnings)]` error[E0433]: failed to resolve: use of undeclared type `Exception`
--> src/trap/mod.rs:26:25
|
26 | Trap::Exception(Exception::IllegalInstruction) => {
| ^^^^^^^^^ use of undeclared type `Exception` error[E0433]: failed to resolve: use of undeclared type `Trap`
--> src/trap/mod.rs:26:9
|
26 | Trap::Exception(Exception::IllegalInstruction) => {
| ^^^^ use of undeclared type `Trap` error[E0433]: failed to resolve: use of undeclared type `Exception`
--> src/trap/mod.rs:22:25
|
22 | Trap::Exception(Exception::StorePageFault) => {
| ^^^^^^^^^ use of undeclared type `Exception` error[E0433]: failed to resolve: use of undeclared type `Trap`
--> src/trap/mod.rs:22:9
|
22 | Trap::Exception(Exception::StorePageFault) => {
| ^^^^ use of undeclared type `Trap` error[E0433]: failed to resolve: use of undeclared type `Exception`
--> src/trap/mod.rs:21:25
|
21 | Trap::Exception(Exception::StoreFault) |
| ^^^^^^^^^ use of undeclared type `Exception` error[E0433]: failed to resolve: use of undeclared type `Trap`
--> src/trap/mod.rs:17:9
|
17 | Trap::Exception(Exception::UserEnvCall) => {
| ^^^^ use of undeclared type `Trap` error[E0433]: failed to resolve: use of undeclared type `Exception`
--> src/trap/mod.rs:17:25
|
17 | Trap::Exception(Exception::UserEnvCall) => {
| ^^^^^^^^^ use of undeclared type `Exception` error[E0433]: failed to resolve: use of undeclared type `Trap`
--> src/trap/mod.rs:21:9
|
21 | Trap::Exception(Exception::StoreFault) |
| ^^^^ use of undeclared type `Trap` Some errors have detailed explanations: E0308, E0412, E0425, E0433, E0599.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `os` (bin "os") due to 34 previous errors
make: *** [Makefile:42: kernel] Error 101

看到大段的报错不要着急,首先先看容易解决,能够解决的.

首先是在batch.rs里加入use core::arch::asm;:

error: cannot find macro `asm` in this scope
--> src/batch.rs:84:9
|
84 | asm!("fence.i")
| ^^^
|
help: consider importing this macro
|
1 + use core::arch::asm;
|

同样地,在src/trap/mod.rs里边加入use core::arch::global_asm;:

error: cannot find macro `global_asm` in this scope
--> src/trap/mod.rs:3:1
|
3 | global_asm!(include_str!("trap.S"));
| ^^^^^^^^^^
|
help: consider importing one of these items
|
3 + use core::arch::global_asm;
|
3 + use crate::global_asm;
|

batch.rs加入use crate::trap::TrapContext;,这时候我们发现实际上在src/trap/mod.rs里也没有声明TrapContext则在里边声明mod context;:

error[E0412]: cannot find type `TrapContext` in this scope
--> src/batch.rs:34:36
|
34 | pub fn push_context(&self, cx: TrapContext) -> &'static mut TrapContext {
| ^^^^^^^^^^^ not found in this scope

后续有很多找不到TrapContext的问题,可能都会解决.

src/sync/up.rs里加入use core::cell::{RefCell, RefMut};:

error[E0412]: cannot find type `RefCell` in this scope
--> src/sync/up.rs:5:12
|
5 | inner: RefCell<T>,
| ^^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use core::cell::RefCell;
|
error[E0412]: cannot find type `RefMut` in this scope
--> src/sync/up.rs:17:39
|
17 | pub fn exclusive_access(&self) -> RefMut<'_, T> {
| ^^^^^^ not found in this scope
|
help: consider importing this struct
|
3 + use core::cell::RefMut;
|

这里还有一个比较难搞的依赖问题,如果这个module不是自己实现的,那么一般考虑外部依赖问题,

error[E0433]: failed to resolve: use of undeclared crate or module `riscv`
--> src/trap/context.rs:2:5
|
2 | use riscv::register::sstatus::{self, Sstatus, SPP};
| ^^^^^ use of undeclared crate or module `riscv`

Cargo.toml加入riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }

同理,把所有的这种依赖性问题都解决, 不一定 是对应着这个报错列表来,而是可以选择根据rust-analyzer自动报错的内容,顺便改一下.

再次编译一下,发现有很多类似的报错:

error: missing documentation for an associated function

这意味着你在编译一个 Rust 项目时启用了某个 lint (编译时检查规则),该 lint 要求所有关联函数都必须有文档注释.

那么我们只需要给这些函数加上注释就行了.

还有一个新的问题:

error: unused variable: `metadata`
--> src/logging.rs:9:23
|
9 | fn enabled(&self, metadata: &Metadata) -> bool
| ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_metadata`
|

因为这个metadataenbaled函数中没有被调用,因此需要在其前面加一个下划线_,从而声明这个参数是故意不被调用的.

另外.trap.S需要被链接到.text部分,并且需要声明__alltraps__restore,因此需要加入这个.

    .section .text
.globl __alltraps
.globl __restore

最终得到的trap.S为:

.altmacro
.macro SAVE_GP n
sd x\n, \n*8(sp)
.endm
.macro LOAD_GP n
ld x\n, \n*8(sp)
.endm
.section .text
.globl __alltraps
.globl __restore
.align 2
__alltraps:
csrrw sp, sscratch, sp
# now sp->kernel stack, sscratch->user stack
# allocate a TrapContext on kernel stack
addi sp, sp, -34*8
# save general-purpose registers
sd x1, 1*8(sp)
# skip sp(x2), we will save it later
sd x3, 3*8(sp)
# skip tp(x4), application does not use it
# save x5~x31
.set n, 5
.rept 27
SAVE_GP %n
.set n, n+1
.endr
# we can use t0/t1/t2 freely, because they were saved on kernel stack
csrr t0, sstatus
csrr t1, sepc
sd t0, 32*8(sp)
sd t1, 33*8(sp)
# read user stack from sscratch and save it on the kernel stack
csrr t2, sscratch
sd t2, 2*8(sp)
# set input argument of trap_handler(cx: &mut TrapContext)
mv a0, sp
call trap_handler __restore:
# case1: start running app by __restore
# case2: back to U after handling trap
mv sp, a0
# now sp->kernel stack(after allocated), sscratch->user stack
# restore sstatus/sepc
ld t0, 32*8(sp)
ld t1, 33*8(sp)
ld t2, 2*8(sp)
csrw sstatus, t0
csrw sepc, t1
csrw sscratch, t2
# restore general-purpuse registers except sp/tp
ld x1, 1*8(sp)
ld x3, 3*8(sp)
.set n, 5
.rept 27
LOAD_GP %n
.set n, n+1
.endr
# release TrapContext on kernel stack
addi sp, sp, 34*8
# now sp->kernel stack, sscratch->user stack
csrrw sp, sscratch, sp
sret

最后运行结果是:

[rustsbi] RustSBI version 0.3.1, adapting to RISC-V SBI v1.0.0
.______ __ __ _______.___________. _______..______ __
| _ \ | | | | / | | / || _ \ | |
| |_) | | | | | | (----`---| |----`| (----`| |_) || |
| / | | | | \ \ | | \ \ | _ < | |
| |\ \----.| `--' |.----) | | | .----) | | |_) || |
| _| `._____| \______/ |_______/ |__| |_______/ |______/ |__|
[rustsbi] Implementation : RustSBI-QEMU Version 0.2.0-alpha.2
[rustsbi] Platform Name : riscv-virtio,qemu
[rustsbi] Platform SMP : 1
[rustsbi] Platform Memory : 0x80000000..0x88000000
[rustsbi] Boot HART : 0
[rustsbi] Device Tree Region : 0x87000000..0x87000f02
[rustsbi] Firmware Address : 0x80000000
[rustsbi] Supervisor Address : 0x80200000
[rustsbi] pmp01: 0x00000000..0x80000000 (-wr)
[rustsbi] pmp02: 0x80000000..0x80200000 (---)
[rustsbi] pmp03: 0x80200000..0x88000000 (xwr)
[rustsbi] pmp04: 0x88000000..0x00000000 (-wr)
[kernel] Hello, world!
[kernel] num_app = 5
[kernel] app_0 [0x8020a038, 0x8020b360)
[kernel] app_1 [0x8020b360, 0x8020c730)
[kernel] app_2 [0x8020c730, 0x8020dcd8)
[kernel] app_3 [0x8020dcd8, 0x8020f090)
[kernel] app_4 [0x8020f090, 0x80210440)
[kernel] Loading app_0
Hello, world!
[kernel] Application exited with code 0
[kernel] Loading app_1
Into Test store_fault, we will insert an invalid store operation...
Kernel should kill this application!
[kernel] PageFault in application, kernel killed it.
[kernel] Loading app_2
3^10000=5079(MOD 10007)
3^20000=8202(MOD 10007)
3^30000=8824(MOD 10007)
3^40000=5750(MOD 10007)
3^50000=3824(MOD 10007)
3^60000=8516(MOD 10007)
3^70000=2510(MOD 10007)
3^80000=9379(MOD 10007)
3^90000=2621(MOD 10007)
3^100000=2749(MOD 10007)
Test power OK!
[kernel] Application exited with code 0
[kernel] Loading app_3
Try to execute privileged instruction in U Mode
Kernel should kill this application!
[kernel] IllegalInstruction in application, kernel killed it.
[kernel] Loading app_4
Try to access privileged CSR in U Mode
Kernel should kill this application!
[kernel] IllegalInstruction in application, kernel killed it.
All applications completed!

可以看到启动了批处理系统之后,一个个APP运行,然后会想起用户层lib.rs中为每个app写得启动部分:

#[no_mangle]
#[link_section = ".text.entry"]
pub extern "C" fn _start() -> ! {
clear_bss();
exit(main());
panic!("unreachable after sys_exit!");
}

每次运行之后,

  1. 因为触发了异常而退出
  2. 直接由exit(main());退出

都会陷入trap,然后在trap_handler里处理,只要不出现没有预期到的Expectation都会调用run_next_app,因此所有的app按顺序运行.

最后完美结束了这一章,我真是一条懒狗,怎么什么坑都要踩一遍.

[rCore学习笔记 019]在main中测试本章实现的更多相关文章

  1. C# 动态生成word文档 [C#学习笔记3]关于Main(string[ ] args)中args命令行参数 实现DataTables搜索框查询结果高亮显示 二维码神器QRCoder Asp.net MVC 中 CodeFirst 开发模式实例

    C# 动态生成word文档 本文以一个简单的小例子,简述利用C#语言开发word表格相关的知识,仅供学习分享使用,如有不足之处,还请指正. 在工程中引用word的动态库 在项目中,点击项目名称右键-- ...

  2. Hadoop源码学习笔记(2) ——进入main函数打印包信息

    Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...

  3. 《python基础教程(第二版)》学习笔记 文件和素材(第11章)

    <python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...

  4. 《python基础教程(第二版)》学习笔记 语句/循环/条件(第5章)

    <python基础教程(第二版)>学习笔记 语句/循环/条件(第5章) print 'AB', 123 ==> AB 123 # 插入了一个空格print 'AB', 'CD' == ...

  5. 《python基础教程(第二版)》学习笔记 类和对象(第7章)

    <python基础教程(第二版)>学习笔记 类和对象(第7章) 定义类class Person:    def setName(self,name):        self.name=n ...

  6. [C#学习笔记3]关于Main(string[ ] args)中args命令行参数

    Main(string[] args)方法是C#程序的入口,程序从这里开始执行,在这里结束.C#代码逻辑要包含在一个类型(Type)中,游离的.全局的变量或函数是不存在的,这里的类型包括类(class ...

  7. Android(java)学习笔记167:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  8. [C#] 类型学习笔记一:CLR中的类型,装箱和拆箱

    在学习.NET的时候,因为一些疑问,让我打算把.NET的类型篇做一个总结.总结以三篇博文的形式呈现. 这篇博文,作为三篇博文的第一篇,主要探讨了.NET Framework中的基本类型,以及这些类型一 ...

  9. Android(java)学习笔记110:Java中操作文件的类介绍(File + IO流)

    1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creat ...

  10. Docker学习笔记之-在CentOS中安装Docker

    上一节演示了如何 通过Xshell连接CentOS服务,链接:Docker学习笔记之-通过Xshell连接 CentOS服务 本节将演示 如何在CentOS中安装 Docker 第一步:更新系统包到最 ...

随机推荐

  1. mac http&git代理配置

    git代理清除git config --global --unset http.proxygit config --global --unset https.proxy 输出代理:$echo $htt ...

  2. Java第一次blog

    7-1 答题判题程序-1 前言 这些题目主要用到对象与类的处理: 对象是现实世界或抽象概念中的实体在计算机程序中的表示. 类则是具有相同属性和方法的对象的集合,是创建对象的模板.通过类,我们可以定义一 ...

  3. vm ware 虚拟WIN XP 时卡

    主机是I7 9700,SN750 NVME 1T SSD, 32G 内存,VM WARE 14,理论上虚拟WIN XP 不会卡,但实际情况就是很卡. 虚拟WIN7 ,WIN 10,UBUNTU LIN ...

  4. 老张,你的服务是不是挂了?论全局 SLI 的重要性

    场景再现 你正在午休,正梦见中了彩票,突然收到电话告警,说服务对外接口 95 分位延迟突增,惊出一身冷汗,睡意全无,抓紧打开监控系统,查看服务的 SLI 指标,发现确实有问题,已经持续 1 分钟,这服 ...

  5. restTemplate.getForEntity restTemplate.getForObject GET请求

    //带参数 @Test public void testGet1(){ String url = "http://IP:PORT/query?token={token}&memNo= ...

  6. OpenCompass 作业

    Smiling & Weeping ---- 愿我们都做生活的高手 -- 昭阳&乐瑶

  7. docker 报Failed to create thread: Operation not permitted (1) 解决方法

    docker启动容器时报:Failed to create thread: Operation not permitted (1) 原因:docker内的用户权限受限 解决办法1: 启动docker时 ...

  8. python 注册nacos 进行接口规范定义

    背景: 一般场景 python服务经常作为java下游的 算法服务或者 数据处理服务 但是使用http 去调用比较不灵活,通过注册到nacos上进行微服务调用才是比较爽的 1.定义feginapi的接 ...

  9. fastadmin的导出到excel功能

    正常的excel导出没什么问题,最近一直头疼的是怎么导出数据中包含图片,并且图片还是数组?????by user 悦悦 https://www.cnblogs.com/nuanai 1.导出的exce ...

  10. WPF/C#:BusinessLayerValidation

    BusinessLayerValidation介绍 BusinessLayerValidation,即业务层验证,是指在软件应用程序的业务逻辑层(Business Layer)中执行的验证过程.业务逻 ...