在MacOS中运行k3s

k3s https://github.com/caicloud/kube-ladder 安装ubuntu家的multipass虚拟机 brew install multipass 创建一个虚拟机并启动 multipass launch -n k3s01 -c 2 -m 2G -d 16G 查看虚拟机 multipass list multipass info k3s01 进入虚拟机终端 multipass shell k3s01 设置root密码,更新apt sudo passwd apt-get update 数据卷,数据传输 multipass mount host-path vm-name:vm-path multipass umount vm-name multipass transfer host-file vm-name:vm-path 虚拟机操作 multipass start/stop/delete/purge vm-name 指定虚拟机初始化时的配置、执行的命令等 multipass launch -n vm-name --cloud-init config.yaml # config.yaml runcmd: - apt-get update # 更新包 - curl -sfL https://get.k3s.io | sh - # 安装k3s - echo "alias k=kubectl" >> ~/.bash_aliases 指定k3s启动时config的访问权限,使得在非root用户下也能kubectl管理k3s ...

九月 1, 2024 · by NOSAE

jekyll chrispy主题的语法

Headings H1 — heading {: .mt-4 .mb-0 } H2 — heading {: data-toc-skip=’’ .mt-4 .mb-0 } H3 — heading {: data-toc-skip=’’ .mt-4 .mb-0 } H4 — heading {: data-toc-skip=’’ .mt-4 } Paragraph Quisque egestas convallis ipsum, ut sollicitudin risus tincidunt a. Maecenas interdum malesuada egestas. Duis consectetur porta risus, sit amet vulputate urna facilisis ac. Phasellus semper dui non purus ultrices sodales. Aliquam ante lorem, ornare a feugiat ac, finibus nec mauris. Vivamus ut tristique nisi. Sed vel leo vulputate, efficitur risus non, posuere mi. Nullam tincidunt bibendum rutrum. Proin commodo ornare sapien. Vivamus interdum diam sed sapien blandit, sit amet aliquam risus mattis. Nullam arcu turpis, mollis quis laoreet at, placerat id nibh. Suspendisse venenatis eros eros. ...

八月 31, 2024 · by NOSAE

nju pa3

穿越时空的旅行 异常响应机制及CTE 实现异常响应机制 我们要实现操作系统的自陷功能,虽然中断的大致原理和流程上课都讲过,但不同操作系统有着不同的具体设计,因此在这之前有必要结合文档与源码过一遍我们框架代码中“异常响应机制”的流程 riscv对于中断与异常提供了各种令人眼花缭乱的CSR控制状态寄存器,我们这里涉及到的有: mtvec寄存器 - 存放了发生异常时处理器需要跳转到的地址 mepc寄存器 - 存放发生异常的指令地址,用与异常处理返回时能回到原本程序执行的位置 mstatus寄存器 - 存放处理器的状态 mcause寄存器 - 存放异常的种类 另外根据文档中提到 首先当然是对R的扩充, 除了PC和通用寄存器之外, 还需要添加上文提到的一些特殊寄存器 所以我们先给处理器添加上述的几个CSR typedef struct { word_t mcause; vaddr_t mepc; word_t mstatus; word_t mtvec; } riscv64_CSRs; typedef struct { word_t gpr[32]; vaddr_t pc; riscv64_CSRs csr; } riscv64_CPU_state; 定义好了需要到的寄存器后,接下来我们就结合nanos-lite的运行来分析中断响应流程吧~在此之前需要再次明确一下模拟器的各层的关系:am是硬件层(确切地说是抽象硬件,对操作系统屏蔽了架构的差异),nanos-lite是操作系统层。我们从nanos-lite的入口,main函数看起,其中中断相关我们只需要关注init_irq以及yield,先回忆一下,还记得文档说的那句话吗? 我们刚才提到了程序的状态, 在操作系统中有一个等价的术语, 叫"上下文". 因此, 硬件提供的上述在操作系统和用户程序之间切换执行流的功能, 在操作系统看来, 都可以划入上下文管理的一部分. init_irq里调用的cte_init,其实就是操作系统向硬件注册事件发生(如中断)的回调函数do_event,这个回调函数就是真正把异常交给操作系统处理的地方(要与异常处理入口函数区分开来),其中的参数为事件和相关的程序上下文。那么这个回调函数什么时候被调用呢,显然是异常发生的时候。 我们接着查看cte_init的代码,其功能简单地说就是保存异常处理入口函数地址,以及保存用户回调函数即上述的do_event,以便异常处理过程中时调用这个用户回调函数。其中异常处理入口函数是__am_asm_trap,这个函数在trap.S这个文件中用汇编语言实现,暂时不管,先接着看流程。 接下来在main函数的最后调用了yield,如果说init_irq描述如何处理异常,那么yield就是真正触发了一个异常(自陷),并进入之前注册的异常处理函数进行异常处理。yield只有两句汇编指令 li a7, -1 ecall 将异常种类存放到a7寄存器中,以及发起自陷,其中ecall会使得程序流程转到之前注册的异常处理入口函数中去执行,即__am_asm_trap,这里就得分析一下这个函数都干了些什么了: __am_asm_trap: ... jal __am_irq_handle ... mret 目前只关注运行流程,多余的代码先去除,__am_asm_trap简单来说是提供了统一的异常入口地址,主要作用是将csr和gpr的内容作为参数调用__am_irq_handle并在其返回后把csr和gpr的新值再存回去(值得一提的是,csr和gpr作为cpu的寄存器,am将他们包装在上下文结构中传给了操作系统,而不是让操作系统直接访问cpu,体现了处处都是抽象和屏蔽的艺术)。__am_irq_handle这个函数也是定义在抽象硬件层(am)中的,通过判断程序上下文内容(比如在riscv-nemu中通过分支mcause的值)来构造事件,最终将事件和上下文一并通过回调函数传给操作系统,开始真正的异常处理….至此从异常注册到异常触发及响应的流程分析就结束了,如果说PA3之前的工作还没对这些抽象硬件、操作系统层等形成认知,或者到了PA3这个部分依然存疑,建议一定要好好做这一小节的内容并去认真体会它是如何设计的,因为确实值得。 若理解了流程,剩下的填代码环节就是顺便的事情了。首先实现几条指令,csr的读写指令和ecall指令 INSTPAT("??????? ????? ????? 001 ????? 11100 11", csrrw , I, R(dest) = CSR(imm); CSR(imm) = src1); INSTPAT("??????? ????? ????? 010 ????? 11100 11", csrrs , I, R(dest) = CSR(imm); CSR(imm) |= src1); INSTPAT("0000000 00000 00000 000 00000 11100 11", ecall , I, ECALL(s->dnpc)); 其中两个新宏CSR, ECALL如下: ...

三月 1, 2023 · by NOSAE

nju pa2

其他资料: https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.md http://riscvbook.com/chinese/RISC-V-Reader-Chinese-v2p1.pdf RTFM 运行第一个客户程序 第一个客户程序即文档所说的dummy.c,键入命令后,会将dummy.c编译成基于rv64指令的二进制格式文件(后缀名为 .bin),作为nemu模拟器的镜像文件(img_file) make ARCH=$ISA-nemu ALL=dummy run 实现指令 首先查看反汇编结果,看看需要实现哪些指令 0000000080000000 <_start>: 80000000: 00000413 li s0,0 80000004: 00009117 auipc sp,0x9 80000008: ffc10113 addi sp,sp,-4 # 80009000 <_end> 8000000c: 00c000ef jal ra,80000018 <_trm_init> 0000000080000010 <main>: 80000010: 00000513 li a0,0 80000014: 00008067 ret 0000000080000018 <_trm_init>: 80000018: ff010113 addi sp,sp,-16 8000001c: 00000517 auipc a0,0x0 80000020: 01c50513 addi a0,a0,28 # 80000038 <_etext> 80000024: 00113423 sd ra,8(sp) 80000028: fe9ff0ef jal ra,80000010 <main> 8000002c: 00050513 mv a0,a0 80000030: 00100073 ebreak 80000034: 0000006f j 80000034 <_trm_init+0x1c> 通过查询手册,可以知道li ret等指令都是伪指令,比如第一条指令 80000000: 00000413 li s0,0 其十六进制内容为0x00000413,对应二进制为0000 0000 0000 0000 0000 0100 0001 0011,查询手册可知其为addi指令,而当伪指令li中的立即数小于4096时,的确会被编译器展开为addi指令,因此目前可以确定,反汇编结果的右边的指令只是为了方便阅读(生成反汇编指令的代码在disasm.cc中),我们在实现指令功能时,只需要看左边的十六进制内容即可 按照框架和文档提示,以及根据手册查询每条指令干了什么,然后填写代码即可 enum { TYPE_I, TYPE_U, TYPE_S, TYPE_J, TYPE_N, // none }; #define immJ() do { *imm = SEXT(( \ (BITS(i, 31, 31) << 19) | \ BITS(i, 30, 21) | \ (BITS(i, 20, 20) << 10) | \ (BITS(i, 19, 12) << 11) \ ) << 1, 21); Log(ANSI_FG_CYAN "%#lx\n" ANSI_NONE, *imm); } while(0) static void decode_operand(Decode *s, int *dest, word_t *src1, word_t *src2, word_t *imm, int type) { // ... switch (type) { // ... case TYPE_J: immJ(); break; } } static int decode_exec(Decode *s) { // ... INSTPAT("??????? ????? ????? 000 ????? 00100 11", addi , I, R(dest) = src1 + imm); INSTPAT("??????? ????? ????? ??? ????? 11011 11", jal , J, s->dnpc = s->pc; s->dnpc += imm; R(dest) = s->pc + 4); INSTPAT("??????? ????? ????? 000 ????? 11001 11", jalr , I, s->dnpc = (src1 + imm) & ~(word_t)1; R(dest) = s->pc + 4); // ... return 0; } 程序,运行时环境与AM 实现字符串处理函数 根据前面的铺垫,这部分比较简单,就不贴代码了,只需要: ...

一月 24, 2023 · by NOSAE

nju pa1

note: 基于riscv64,不适配riscv32 RTFSC 优美地退出 make run启动nemu后直接输入q退出,得到如下最后一行的错误 Welcome to riscv32-NEMU! For help, type "help" (nemu) log Unknown command 'log' (nemu) q make: *** [/home/ubuntu/ics2022/nemu/scripts/native.mk:38: run] Error 1 是由于is_exit_status_bad函数返回了-1,main函数直接返回了此函数返回的结果,make检测到该可执行文件返回了-1,因此报错。通过分析该函数得到解决方案:在输入q中途退出nemu后,将nemu_state.state设成NEMU_QUIT即可 // nemu/src/monitor/sdb/sdb.c void sdb_mainloop() { ... int i; for (i = 0; i < NR_CMD; i ++) { if (strcmp(cmd, cmd_table[i].name) == 0) { if (cmd_table[i].handler(args) < 0) { if (strcmp(cmd, "q") == 0) { nemu_state.state = NEMU_QUIT; // set "QUIT" state when q } return; } break; } } if (i == NR_CMD) { printf("Unknown command '%s'\n", cmd); } } } 此时再通过make run运行后中途键入q命令退出模拟器将不会再报该错误 简易调试器 单步执行 si [N] 第一步,在cmd_table注册一条命令si static struct { const char *name; const char *description; int (*handler) (char *); } cmd_table [] = { { "help", "Display information about all supported commands", cmd_help }, { "c", "Continue the execution of the program", cmd_c }, { "q", "Exit NEMU", cmd_q }, { "si", "Continue the execution in N steps, default 1", cmd_si }, /* TODO: Add more commands */ }; 第二步,编写cmd_si,即si具体要执行的东西 ...

一月 12, 2023 · by NOSAE