关于操作系统:从零开始写-OS-内核-运行-shell

49次阅读

共计 1640 个字符,预计需要花费 5 分钟才能阅读完成。

系列目录

  • 序篇
  • 筹备工作
  • BIOS 启动到实模式
  • GDT 与保护模式
  • 虚拟内存初探
  • 加载并进入 kernel
  • 显示与打印
  • 全局描述符表 GDT
  • 中断解决
  • 虚拟内存欠缺
  • 实现堆和 malloc
  • 第一个内核线程
  • 多线程运行与切换
  • 锁与多线程同步
  • 进入用户态
  • 过程的实现
  • 零碎调用
  • 简略的文件系统
  • 加载可执行程序
  • 键盘驱动
  • 运行 shell

shell 命令行

这是本系列最初一篇了,为这个 OS 加一个用户界面 shell,这算是 Linux 编程中最入门的经典教科书我的项目了,网上也能够找到很多小教程。这里也不多浪费时间,仅展现一下它的外围局部:

void print_shell() {printf("bash>");
}
while (1) {print_shell();
  while (1) {int32 c = read_char();
    if (c == '\n') {run_program();
      break;
    } else if (c < 128) {printf(c);
    }
}

shell 实质上只是一个壳,正如它的名字,它提供一个和用户交互的命令行界面,不停地期待用户输出字符并反馈打印进去;一旦用户按下了回车键,那么示意须要运行之前输出的命令行,这在 run_program 函数里实现:

void run_program() {
  // Parse cmd and get program and args.
  // ..
  
  // (fork + exec) new prgoram.
  int32 pid = fork();
  if (pid < 0) {printf("fork failed");
  } else if (pid > 0) {
    // parent
    int32 status;
    wait(pid, &status);
  } else {
    // child
    int32 ret = exec(program, args_index, (char**)args);
    exit(ret);
  }
}

这里首先 parse 用户方才敲回车之前输出的命令行字符串,解析出可执行程序名,以及参数。而后就是经典的 fork + exec 组合,运行这个程序。程序名和参数都会被传递到 exec 零碎调用的处理函数 process_exec,那里会从磁盘上读取该用户可执行文件并执行。这里命令行输出的程序名都很简略,也没有什么门路的概念,因为咱们应用的 naive_fs 只有一层构造,所有文件全在顶层,所以间接用文件名就能够了。

fork 后的 parent 过程会调用 wait 零碎调用阻塞期待 child 完结。对于 wait 和 exit 这组零碎调用,我没有在这个系列里具体开展,读者能够自行浏览源码。

kernel 启动工作

咱们来看一下这个 kernel 启动的过程,后盾开启了哪些工作,以及如何最终进入 shell 界面。本节代码在 src/task/scheduler.c 中。

首先启动 kernel main 过程 / 线程,它是最原始的先人过程,会做这几件事件:

  • 创立 kernel 资源清理线程 kernel_clean_thread,这是一个后盾线程,我用它专门做 process/thread 的资源最终回收工作,平时它是睡眠的,只有当有 process/thread 沦亡须要清理时会唤醒;
  • 创立 init 过程以及线程 kernel_init_thread,它会成为第一个用户过程,运行用户程序 init;在 init 程序里,我创立了 shell 过程,而后 init 过程就进入阻塞;在理论的 Linux 零碎中,实在的 init 过程应该还须要作为一个后台任务,专门负责期待接管回收所有的孤儿过程(Orphan Process),我这里就不实现了,感兴趣的同学能够查资料学习一下;
  • 上述两项工作实现后,这个原始线程就变成了 cpu_idle 线程,所谓 cpu idle 就是一条指令 hlt,它是在零碎真的没有任何工作须要运行的状况才会被运行,它会使 CPU 进入一个低功耗运行的状态;

当然以上只是我集体启动 kernel 工作的实现形式,和 Linux 有点像但并不完全一致;这其实很随便的,这毕竟只是咱们本人写的一个玩具 OS 而已,Linux 的形式也并非标准答案,只须要达到让零碎各个重要的工作胜利运行并调度起来就能够了。

正文完
 0