青藤木子


分类 Linux的日常 下的文章

最近需要用到Ubuntu19.04,于是又将Ubuntu给安装上了,但每次我都忘了配置Ubuntu,因此这里写给大家看,以及自己看

更新源配置

首先把更新源设置为中国的镜像源,比如清华镜像或阿里云的
2019-05-27 09-35-23屏幕截图.png

输入法配置
接下来就是配置中文输入法了,打开设置,找到区域和语言
2019-05-27 09-40-22屏幕截图.png
如果有汉语了,就先删除他,然后在重新添加汉语,然后会出现选择一个输入法
2019-05-27 09-46-12屏幕截图.png
选择就可以了

卸载软件
卸载office:

sudo apt-get purge libreoffice?

常用软件

注意:这些推荐的软件在其他linux上也能运行

Motrix:多线程下载工具
https://motrix.app/

CocoMusic:linux下的QQ音乐
https://github.com/xtuJSer/CoCoMusic

Chrome:必装浏览器
https://www.google.cn/chrome/

Electron-SSR:友好上网
注意:作者删github了,因此该软件不会更新了,不过还能用上四、五年吧,该软件仅用于学习!
链接: https://pan.baidu.com/s/1EQ6I69uKRsOccD-vM9fobg 提取码: sddc

Termius:ssh工具,贼好看
https://www.termius.com/

其他Electron应用(注意:链接里的软件不一定是属于linux软件)
https://electronjs.org/apps
https://github.com/sindresorhus/awesome-electron

在发表这个文章之前,我曾发布过另一篇文章:Rust开发操作系统系列:全新Hello World系统
那篇文章我发布在云栖社区以及我自己的博客:青藤木子上,但是这是我第一次认真的写一篇文章,虽然看的人不多,也没几个人回复我,文章里也有很多的问题,目前你可以在我的博客上找到最新的修订版本,感谢转载和分享,也请您在转发文章时添加上原文章地址。也希望有更多人回复我、批评我、分享一些我不知道的知识。

这个系统可以干什么??

  • [ ] 内存分页
  • [ ] 线程
  • [ ] 中断
  • [o] 一个打印(print)功能
  • [o] 在qemu上能够运行
  • [o] VGA驱动
  • 注意⚠️

  • 本人是在Mac OSX 上工作的,因此作者目前不会在其他平台上出教程,不过您有需要的话,请留言告知我
  • 在使用Rust的时候请安装每夜版(nightly),这样方便同步,使用稳定版或beta版时将无法编译!
  • 资料我将打包成zip,您可以自行下载固件编译运行。
  • 目前来说这个自制的系统还无法直接在裸机上运行,而编译固件时编译的是bin固件。
  • 如果您遇到了什么问题,可以下载源码查看:这里这里

编译环境安装

Rust安装是及其简单的,而且之前我的文章里也提到过安装Rust,如果您没有跟着那篇文章尝试过编译arm架构的最微型系统,那么建议您去try一下!

安装Rust

$ curl https://sh.rustup.rs -sSf | sh

如果您安装了Rust但没有nightly版,可以使用这个命令:

$ rustup install nightly

设置nightly为默认

$ rustup default nightly

安装拓展工具

$ cargo install bootimage

$ cargo install cargo-xbuild

$ rustup component add rust-src --toolchain=nightly

$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

$ brew install qemu

注意:qemu需要homebrew来安装,在中国安装homebrew可能是最麻烦的事,您可以去百度寻找解决方案或自行挂 梯子


开始书写代码

首先用cargo来创建项目

$ cargo new apps

打开apps文件,然后创建一个叫做apps.json的文件,在这个文件里写:

{
  "llvm-target": "x86_64-unknown-none",
  "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
  "arch": "x86_64",
  "target-endian": "little",
  "target-pointer-width": "64",
  "target-c-int-width": "32",
  "os": "apps",
  "linker": "rust-lld",
  "linker-flavor": "ld.lld",
  "executables": true,
  "features": "-mmx,-sse,+soft-float",
  "disable-redzone": true,
  "panic-strategy": "abort"
}

接下来就是修改Cargo.toml,就像这样:

[dependencies]
bootloader_precompiled = "0.3.0"
mars_vga = "0.0.1"

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

[package.metadata.bootimage]
default-target = "apps.json"

然后我们打开src/main.rs,改成这样:

#![feature(core_intrinsics)]
#![no_std]
#![no_main]

// 使用 #[macro_use] 来表明使用 vga crate 的宏命令:print! 和 println!
#[macro_use]
extern crate mars_vga;
extern crate bootloader_precompiled;

use core::intrinsics;
use core::panic::PanicInfo;

#[panic_handler]
#[no_mangle]
fn panic(_info: &PanicInfo) -> ! {
    unsafe { intrinsics::abort() }
}

// 系统入口处
#[no_mangle]
pub fn _start() -> ! {
    println!("hello world");
    loop {}
}

当然您可能会说我看不懂,你就这么让我这样做,我怎么能懂?
没问题的,让我们先把系统写好后再慢慢跟您讲。


运行

打开终端,然后跳转到apps文件夹里,执行这些命令:

$ bootimage build
$ bootimage run

经过长久(如果下载时间过长,建议更换dns,比如这个: 1.0.0.1或1.1.1.1)的编译后终于运行了!

未命名.png


解释原理

现在回过头看您的代码,是否有注意到这个crate吗:mars_vga?,这是我借鉴别人的资料写的一个crate(如果您不知道什么是crate,可以在https://kaisery.github.io/trpl-zh-cn/这个中文教程里找到,这是一个Rust教程)
这个crate里我添加了宏函数,即println!print!,这样您就可以直接打印出一串字了,但不支持中文。这是一个很好的方法,也是Rust独具一格的优点,即您可以将一些可以分开的方法打包成crate然后上传到crate.io里,当需要添加到项目里时直接在Cargo.toml这个文件里添加crate就可以了,如果您对这个mars_vga感兴趣,可以用Idea IDE工具打开这个项目,然后就可以查看这个crate的源码了

我们创建了一个apps.json文件,这个是bootimage工具编译时需要的东西,有了bootimage工具我们就可以实现交叉编译(这个平台编译另一个平台的东西)。

#![feature(core_intrinsics)]
#![no_std]
#![no_main]

// 使用 #[macro_use] 来表明使用 vga crate 的宏命令:print! 和 println!
#[macro_use]
extern crate mars_vga;
extern crate bootloader_precompiled;

use core::intrinsics;
use core::panic::PanicInfo;

#[panic_handler]
#[no_mangle]
fn panic(_info: &PanicInfo) -> ! {
    unsafe { intrinsics::abort() }
}

// 系统入口处
#[no_mangle]
pub fn _start() -> ! {
    println!("hello world");
    loop {}
}

![no_std]#用来告诉Rust编译器:我们不使用Rust标准库,在系统开发中,内存、线程、文件系统我们需要自己写,Rust标准库不适用,我们只使用Rust的核心库(core)就可以了
![no_main]用来告诉Rust:我们没有main方法,我们在做系统。因此Rust允许我们自己创建main方法。
#[macro_use]用来告诉Rust:我想使用我自己建的宏函数。这个参数让Rust允许使用我们自建的宏函数。
#[no_mangle]用来告诉Rust:我想定义一个方法,它的名字与标准库里一个叫做painc方法一样。

#[panic_handler]
#[no_mangle]
fn panic(_info: &PanicInfo) -> ! {
    unsafe { intrinsics::abort() }
}

这里是异常处理方法,因为这个系统还没有更高级的东西,因此这个方法只有终止的功能

// 系统入口处
#[no_mangle]
pub fn _start() -> ! {
    println!("hello world");
    loop {}
}

这是我们定义了_start()方法,为什么它不叫main呢?因为main仅仅是内核启动点,而最先启动的应该是_boot。那为什么会添加一个-> !?这是因为系统一旦启动,而且永远也不返回参数,系统也永远不会执行完就停止,所以我们在这个方法里添加了loop{}


还有吗???

做一个系统就这么点代码吗?当然不是,你看到的只是这几十行代码,而其他代码都是被封装成crate了。那些为计算机科学作出贡献的人,不断的、夜以继日的帮助着我们,我们可能只写了几十行,但在这几十行代码的背后,就有那么一群人写了几千行,尽了最大了努力来让我们写出高效美丽的代码!感谢这群人、这群“疯子”!

关于这件事

有人可能遇到过这种事情:好声好气告诉别人不要乱扔垃圾,结果被人骂“读书读傻了”,可能做错了一点点事情,也被骂“读书读傻了”
如果这个世上有很多的这样的人,想象一下这个世界会发生怎样的变化?世界很残酷,但是我们仍然关爱老人,以前肉弱强食,但是现在我们关爱残疾、关爱病人、帮助着在这个世界无法自足的人们。我们有着自己选择的权利,有着一颗炙热的心,每个人有不同的活法,但请做一个道德的人,如果这都无法做到的话,我也会不客气的。

注意:文章篇幅较长,如果想提前拿到代码,可以直接下载附件,大小仅为57k
附件在这里,点我下载
正如标题,这篇文章是关于如何用Rust开发一个船新的操作系统,而这个操作系统只会打印一句话: Hello World

在这之前,我们需要了解有关计算机底层的基础知识,包括IO、接口、网络底层等等,通过这篇文章您能清楚的了解如何制作一个微型的、有Terminal的操作系统


首先让我们了解一下Rust

*Rust是一门系统编程语言 ,专注于安全,尤其是并发安全,支持函数式和命令式以及泛型等编程范式的多范式语言。Rust在语法上和C++类似 ,但是设计者想要在保证性能的同时提供更好的内存安全。 Rust最初是由Mozilla研究院的Graydon Hoare设计创造,然后在Dave Herman, Brendan Eich以及很多其他人的贡献下逐步完善的。Rust的设计者们通过在研发Servo网站浏览器布局引擎过程中积累的经验优化了Rust语言和Rust编译器。Rust编译器是在MIT License 和 Apache License 2.0双重协议声明下的免费开源软件。 Rust已经连续三年(2016,2017,2018)在Stack Overflow开发者调查的“最受喜爱编程语言”评选项目中折取桂冠。(上面的内容采摘自百度百科:https://baike.baidu.com/item/Rust%E8%AF%AD%E8%A8%80/9502634?fromtitle=Rust&fromid=12624017&fr=aladdin)
(本人语言组织不行,请多多见谅)
Rust的官网是https://www.rust-lang.org/

关于自制操作系统

*Rust官网本来就有这个项目的,其文章是英文的,作者也打算计划制作X86_64位系统,因此我准备针对这个计划开发
*Rust官网开发单片机系统文章链接:https://rust-embedded.github.io/book
*这个系统是基于arm架构进行开发的,如果您想看基于x86_64架构开发的教程,请继续关注作者的博客:青藤木子

安装开发环境
由于作者目前只在Mac下工作,因此关于 Windows 和 Linux 的就只有等待以后更新!
-------------Mac下安装-------------
下面的命令一键安装Rust

$ curl https://sh.rustup.rs -sSf | sh

注意:必须安装beta或每夜版才行!!!
开发环境:推荐用微软的 Visual Studio code 或者 Idea,在插件一栏搜索关键词 rust即可
其他软件环境:

$ cargo install cargo-binutils

$ rustup target add thumbv6m-none-eabi thumbv7m-none-eabi thumbv7em-none-eabi thumbv7em-none-eabihf

$ rustup component add llvm-tools-preview

$ brew cask install gcc-arm-embedded

$ brew install openocd

$ brew install qemu

$ #如果该brew cask命令不起作用(例如error: unknown command: cask),则首先运行brew tap Caskroom/tap并再次尝试。

书写代码

到了开始锻炼手的灵活度了,评论区回复打字速度有机会获得奖品哦(其实没有奖品,而是撒子都没得!!!)

使用cargo来创造一个新项目(不瞒你说,其实也可以用IDE直接创建的)
命令:

$ cargo new app

接下来就是进入app文件夹

$ cd app

然后在 Cargo.toml 设置一下添加这些

[dependencies]
cortex-m = "0.5.8"
cortex-m-rt = "0.6.5"
cortex-m-semihosting = "0.3.2"
panic-halt = "0.2.0"

[[bin]]
name = "testos" # 注意!这个name的参数必须与[package]里的name一致
test = false
bench = false

[profile.release]
codegen-units = 1
debug = true
lto = true

就像下面这样

[package]
name = "testos"
version = "0.1.0"
authors = ["moyan"]
edition = "2018"

[dependencies]
cortex-m = "0.5.8"
cortex-m-rt = "0.6.5"
cortex-m-semihosting = "0.3.2"
panic-halt = "0.2.0"

[[bin]]
name = "testos"
test = false
bench = false

[profile.release]
codegen-units = 1 # 更好的优化
debug = true
lto = true # 更好的优化

接下来就是设置Rust的 .config文件夹下的 config 文件
注意:Mac下用访达是无法直接看到这种带 . 的文件夹,可以用IDE看到,也可以用下面的命令看

$ defaults write com.apple.finder AppleShowAllFiles -bool true;

$ KillAll Finder

在 config 文件里添加这些代码

[build]
#代表给 Cortex-M3 的CPU编译系统
target = "thumbv7m-none-eabi"    # Cortex-M3

[target.thumbv7m-none-eabi]
#添加这些命令可以直接使用 cargo run 来运行,如果无法理解这些命令,可以在自己通过本片文章成功运行系统后看Rust官方的文章
runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -semihosting-config enable=on,target=native -kernel"

rustflags = [
#链接
  "-C", "link-arg=-Tlink.x",
]

完成后就可以设置好内存和储存走向了
因为 Rust 官网为我们解决了很多的问题,因此我们只需要些一个文章,那就是 memory.x 文件。注意这个文件创建在src的外面。
在文件里面添加

MEMORY
{
    FLASH : ORIGIN = 0x00000000, LENGTH = 256K
    RAM : ORIGIN = 0x20000000, LENGTH = 64K
}

终于。。。。到了最后一步:修改 main.rs 文件!!!
就像下面这样:

//这个代码是不使用Rust的标准库
#![no_std]
//这个代码表示不使用默认main方法
#![no_main]

//使用panic_halt库
extern crate panic_halt;

use cortex_m_rt::entry;
use cortex_m_semihosting::{hprintln};

#[entry]
fn main() -> ! {
    loop {
        //无限打印 Hello World
        hprintln!("hello world").unwrap();
    }
}

保存之后等待最后一步操作


运行

使用命令:

$ cargo build

$ cargo run

附上运行:

未命名.png

结尾


成功运行,感觉良好,希望您们关注收藏此博客

渝ICP备17015729号-1