此处将为大家介绍关于LinuxLab项目启动6年后,终于发布了v1.0正式版的详细内容,并且为您解答有关linux-lab的相关问题,此外,我们还将为您介绍关于01、开源游戏-“胡子”项目启动、Che
此处将为大家介绍关于Linux Lab 项目启动 6 年后,终于发布了 v1.0 正式版的详细内容,并且为您解答有关linux-lab的相关问题,此外,我们还将为您介绍关于01、开源游戏-“胡子”项目启动、Cherokee 终于发布了 1.0 版本、CSAPP Lab:Bomb Lab——从拆弹到爆炸。。。、CSAPP Lab:Shell Lab——理解进程控制的秘密的有用信息。
本文目录一览:- Linux Lab 项目启动 6 年后,终于发布了 v1.0 正式版(linux-lab)
- 01、开源游戏-“胡子”项目启动
- Cherokee 终于发布了 1.0 版本
- CSAPP Lab:Bomb Lab——从拆弹到爆炸。。。
- CSAPP Lab:Shell Lab——理解进程控制的秘密
Linux Lab 项目启动 6 年后,终于发布了 v1.0 正式版(linux-lab)
简介
自 Linux Lab v0.9 发布以后,又经过了 5 个月的漫长迭代,Linux Lab 终于迎来了 v1.0 正式版,同时也迎来了 Cloud Lab v0.80-rc1 版本,两者需同步升级配合使用。
-
发布仓库
-
Gitee: https://gitee.com/tinylab/linux-lab
-
Github: https://github.com/tinyclub/linux-lab
-
-
用户手册
-
Linux Lab v1.0 中文手册
-
Linux Lab v1.0 英文手册
-
更新情况
Linux Lab v1.0 升级了部分内核版本到 v5.17,修复了多处内存编译 Bug,优化了 make 命令自动补全功能,并重点完善和新增了 examples,同时更新文档对齐到最新的功能。
-
v1.0 rc3
-
全面整理 Assembly 实验案例
-
删除多余的 do target,由其他更简洁的用法替代
-
允许更简单编译内核目标文件,例如:
make kernel arch/riscv/kernel/sbi.o
-
修复 make 自动命令补全,允许通过 tab 按键快速补全常用命令
-
完善 make patch 命令
-
更新文档和 License 信息
-
-
v1.0 rc2
-
升级 RISC-V 支持,qemu 升级到 v6.0.0,内核升级到 v5.17
-
升级 arm/vexpress-a9 的默认内核到 v5.17
-
规范 build 输出路径,跟
boards/
下的路径保持一致,方便更快找到目标文件 -
完善 docker 文件系统运行和导出支持
-
新增 Python 实验案例
-
完善 Assembly 和 Shell 实验案例
-
-
v1.0 rc1
-
增强 test 功能,允许在 testcase 中执行多个命令
-
修复 test 中的内核参数传递问题,确保兼容 uboot 和 kernel
-
允许灵活增加 app 的子 make 目标,例如
make root busybox-menuconfig
-
修复两笔内存编译的问题
-
项目感想
历史回顾
Linux Lab v1.0 是一个很重要的里程碑,不仅意味着其核心功能已经非常稳定和完善,也意味着我们的工作重心将发生调整。在 v1.0 之后,我们将把重点调整到 examples 的开发上,将通过 examples 帮助更多的同学更高效地学习、研究和开发操作系统以及周边的技术。
刚刚查看了第一笔提交记录:
Author: Wu Zhangjin wuzhangjin@gmail.com
Date: Mon Jul 11 09:06:04 2016 +0800Init linux-lab
Aims to build a Qemu-based Linux Lab to easier the Linux Learning and new features development.
Signed-off-by: Wu Zhangjin wuzhangjin@gmail.com
非常令人感慨,六年前肯定想不到,今天的 Linux Lab v1.0 已经支持了市面上所有的主流处理器架构,支持了 20 多款开发板,支持了从 v0.11 到 v5.x 的几乎所有 Linux 内核版本,加 Cloud Lab 在内,一共有 3294 笔变更,每一笔背后都是煞费苦心的设计和思考以及大量繁琐的验证和测试。
$ cd cloud-lab/labs/linux-lab
$ git log --oneline --root | wc -l
2152
$ cd ../../
$ git log --oneline --root | wc -l
1142
我想说,这份努力是值得的,作为计算机软件中偏底层最接近硬件最复杂的操作系统,向来是相对比较难上手的,最大的门槛是重复又依赖繁多的环境构建,但是有了 Linux Lab,继而有了 Linux Lab Disk,我们可以在 1 分钟内进入实验环境,在 10 分钟内编译并启动 Linux 内核,Linux 内核与嵌入式 Linux 开发从未像今天这般简单。
期待我们的工作对操作系统的人才培养、技术孵化、开发效率等方面都有所助力!
感谢致谢
感谢六年来,所有参与、支持和鼓励过这个项目的同学们!没有你们的支持,这个项目也许早就夭折了;没有你们的支持,我们不会有动力不厌其烦地去完善和迭代,那些 Bug Report,Patch,赞誉背后的支持让所有的开发不再孤立无援,而是温暖充盈。
也要特别感谢这个项目用到的所有开源项目,包括但是不限于:Ubuntu, Linux, Docker, Qemu, Buildroot, U-Boot, Busybox, Make, webvnc 等等,没有这些工作,就不可能有 Linux Lab。
同时感谢项目的托管平台:Github 和 Gitee,也要感谢曾经赞助过这个项目的企业、研究所和个人,包括购买过 Linux Lab Disk 以及社区所有其他付费服务的所有同学们!
另外,这六年来,家里的夫人和小伙伴也给了莫大的支持,这个项目牺牲了很多本应该陪伴他们的时间。随着 v1.0 版本的发布,希望后面能够有更多的时间陪伴他们。
商业化尝试
过去数年来,包括社区和项目在内,所有的开发和答疑都是公益性质的,是个人投入资金和时间在运营,虽然有获得了一些赞助,但是杯水车薪。
为了项目的持续健康发展,在经过艰难的考虑后,我们做了一些商业化尝试,希望大家能够多多支持。
-
Cloud Lab 和 Linux Lab 项目都采用双 Licenses,非商业用户采用 GPL v2 协议,商业用户需要获得商业授权。
-
之前维护的开发板和内核版本数量巨大,答疑和维护已经令人精疲力尽,所以开发板部分,后续仅默认开放
arm/vexpress-a9
,其他开发板将暂停开放并可根据需要付费购买服务。也欢迎其他企业、机构或个人联系赞助某个开发板或处理器架构,获得相应的资源后,社区将考虑重新开放对应的开发板或处理器架构。 -
社区也研发了免安装即插即跑的 Linux Lab Disk,也叫泰晓 Linux 实验盘,插上即可开展 Linux 内核与嵌入式 Linux 开发,容量覆盖 32G-2T,支持智能启动、透明压缩、时区兼容、出厂恢复等新创特性,用户可根据需要选购。欢迎高校、企业和机构联系团购,泰晓 Linux 实验盘可用于高校计算机实验室、企业内部培训等。
更多资料
-
使用 Linux Lab 的好处
-
Linux Lab:难以抗拒的十大理由 V1.0
-
Linux Lab:难以抗拒的十大理由 V2.0
-
-
Linux Lab 视频公开课:含用法介绍、使用案例分享、发布会视频回放、Linux Lab Disk功能演示等
-
CCTALK
-
B 站
-
知乎
-
-
采用 Linux Lab 作为实验环境的视频课程
-
《360° 剖析 Linux ELF》
-
《Rust 语言快速上手》
-
《软件逆向工程初探》
-
《Linux内核热补丁技术介绍与实战》
-
-
采用 Linux Lab 或者 Linux Lab 正在支持的图书、课程等
-
成功适配过 Linux Lab 的国内外图书、线上课程列表
-
-
采用 Linux Lab 或者 Linux Lab 正在支持的真实硬件开发板
-
ARM IMX6ULL,野火电子
-
RISCV-64 D1, 平头哥
-
-
Linux Lab 社区正在开发的周边硬件
- Linux Lab Disk,免安装、即插即用 Linux Lab 开发环境
-
支持 Ubuntu 18.04-21.04, Deepin 20.2+, Fedora 34+, Mint 20.2+, Ezgo 14.04+, Kali, Manjaro
-
- Pocket Linux Disk,免安装、即插即用 Linux 发行版
-
支持 Ubuntu 18.04-21.04, Deepin 20.2+, Fedora 34+, Mint 20.2+, Ezgo 14.04+, Kali, Manjaro
-
- Linux Lab Disk,免安装、即插即用 Linux Lab 开发环境
01、开源游戏-“胡子”项目启动
如果你看过之前的文章,你就会明白我们什么这么写,如果你没看,也没必要解释了。
开源游戏“胡子”,今天正式开始设计。
“胡子”是一款以html5开发的一款即时战略游戏,即大家说的RTS,可以单人游戏和多人对战。
单人游戏时,故事情节为东北土匪的事。具体故事还在构思中。为什么叫“胡子”那,很简单,东北人把土匪叫“胡子”。我就是东北人。
下一次我们写写怎么设计这个游戏。
Cherokee 终于发布了 1.0 版本
Cherokee 号称是目前最快的 Web 服务器软件,在性能上,甚至比 Nginx 还略胜一筹。与 Apache、Lighttpd、Nginx 等其他同类软件的对比,大家不妨看看这个测试页面。其易用性做得也很不错。
该版本是 Cherokee 这个项目自创建以来的第一个完整的版本,完成了管理的接口和所有服务器的功能、音频视频流媒体模块、反向代理、FastCGI, SCGI, uWSGI 和 CGI 接口,兼容 Apache 的 htpasswd 和 htdigeest 的插件、日志文件、gzip 和 deflate 压缩支持、通过 MySQL 和 LDAP 的认证支持、DBSlayer 兼容数据库桥等等。
强烈建议升级。
下载 Cherokee 1.0
CSAPP Lab:Bomb Lab——从拆弹到爆炸。。。
这个实验的要做的是用gdb逆向一段code,通过查看汇编代码以及单步调试找出这段code需要你填入的字符串,好像每个人都不一样,所以每个人都需要找到自己的拆弹密码,很有意思。
实验一共有6关,我们一关关来看一下:
phase_1
打开bomb.c看些c源码(这里的核心方法已经被删除了,只能看到最外层的代码,但能得到一些线索)。
很容易就发现这个phase_1方法是第一题的核心方法,直接逆向它,看下它的汇编。
第一句话是在为函数栈开辟空间,第二句话是关键,将一个立即数赋值给%esi,然后就调用strings not equal方法,推测很用可能这个寄存器中就存着我们拆弹的字符串,于是打断点,单步执行,查看%esi的里的内容:
没错,这就是我们拆弹的钥匙了,输入,第一个炸弹成功拆除!可以将答案放在一个文本文件中,方便之后的解题。
phase_2
直接逆向phase_2函数观察下
观察read_six_numbers发现这次是要我们输入6个数字,通过观察后发现输入的6个数字会依次3存在%rsp,%rsp+4,%rsp+8,%rsp+12...%rsp+24这些位置,那么cmpl $0x1,(%rsp)这句话就很明显可以得出第一个数字是1,再接下去看跳转到52,将%rsp+4也就是第二个数字放进%rbx中,将%rbp设置成%rsp+24(可以猜到%rbp使用来判断循环是否退出的寄存器),之后跳转到27,这里将第一个数赋值给%eax,将%eax*2去和第一个数对比,如果相等就继续,以此类推,可以发现这个循环就是用来判断输入的数字是否依次增大一倍的,所以第二题的拆弹密码就是:1 2 4 8 16 32
phase_3
我首先随意输入一个字符串,调试发现%esi中的字符串内容为"%d %d",由此得知此题需要我们输入两个数字,%eax是scanf的返回值,如果=1则代表非法输入,炸弹爆炸。我们输入两个数字,这里跳转就能通过了。然后发现第一个数字不能大于7,我们随意填了个0,重新调试再试试,然后发现jmp到了57,走下去会发现%eax就是第二个数的答案,所以此题答案为0 0xcf。
其实这道题最简单的解法就是输入两个数,跟着单步调试走,你很容易就能确定两个数字的内容,但是其实你再多看两眼,就会发现其实这里是一个switch结构,答案是不唯一的,跳转表存在*0x402470中,我们打印出这张跳转表,就能得知这道题的所有答案:第一个数字是index,第二个数字就是对应分支赋值给%eax的值。
phase_4
这道题是个递归,花了点时间,但是复杂度还行,只要一步步跟下来就能得出结果。
拆弹关键在func4函数中,发现func4返回的参数eax必须为0才能不爆炸,我们倒退进func4
发现只有当%ecx和%edi的值相等的时候才会将%eax赋值为0,而%edi就是我们的第一个参数,那么我们只需要知道%ecx的值即可,通过推导得出ecx的值可以为7 3 0。
返回phase_4继续走下去发现第二个数为0就能拆弹了。
phase_5
通过这段我们可以知道这一题是要我们输入一串长度为6的字符串。
这一段是核心代码,跳转至112后将%eax赋值为0后跳转到41,然后讲%rbx+%rax的值赋值给%ecx,%rbx是我们输入内容的基地址,%rax是索引,然后做的事情其实就是将当前字符截取底4位。55行这里有个奇怪的地址,将这个地址输出看下得到:,那么这里就是以当前字符低4位的值为索引去读取这个字符串,然后得到的字符放进以$rsp+16为起始地址的内存区域。
解下来可以跳出循环看76-91行了,查看81行的字符串为"flyers",%rdi就是我们循环得到的字符串,然后调用string_not _equal方法,得知只要我们循环得出的字符串等于“flyers”即可拆弹。
分别找到“flyers”在上述字符串中的索引,然后对照ASCII码表,可得到本题答案,答案不唯一,只要低4位符合条件的字符都能拆弹。
phase_6
这题在借助谷歌的力量后才不太顺利的完成了。。
先看第一部分
这部分没有什么难度,但也有一定复杂度,稍微花点时间理一下逻辑,就能发现它是要我们输入6个数字,然后这6个数字要求互不相等,并且都不大于6。
接下来就比较困难了,没想到是用到了链表,而且还涉及到数据对齐的知识。
链表存储在0x6032d0中,链表得到后再进行排序,最后我们可以得到排序后的链表其实是单调递减了,然后反推就能得出我们的答案啦~
CSAPP Lab:Shell Lab——理解进程控制的秘密
本次实验目的是完成一个简单的shell程序,解析命令行参数,理解并使用(fork,execve,waitpid)常见的多进程函数,了解linux进程组,以及前台进程和后台进程的相关概念,理解linux的信号机制(包括发送信号,接受信号,阻塞信号等)。实验提示以及详情请阅读CMU的实验指导:http://csapp.cs.cmu.edu/public/labs.html 。
我们要完成的shell并不是从0开始,实验本身已经帮你完成了一部分内容,并且提供一些工具函数,我们要做的是实现一下这几个核心函数:
eval: Main routine that parses and interprets the command line. [70 lines]
builtin_cmd: Recognizes and interprets the built-in commands: quit,fg,bg,and jobs. [25 lines]
dobgfg: Implements the bg and fg built-in commands. [50 lines]
waitfg: Waits for a foreground job to complete. [20 lines]
sigchld handler: Catches SIGCHILD signals. [80 lines]
sigint handler: Catches SIGINT (ctrl-c) signals. [15 lines]
sigtstp handler: Catches SIGTSTP (ctrl-z) signals. [15 lines]
eval
这是shell程序的核心函数,我们需要在这里完成以下几个事情:
1.调用parseline,生成argv以及判断是否是后台进程。
2.调用builtin_cmd判断是否是内建命令,如果是则已经在该方法中执行,shell直接返回,否则创建进程执行。
3.fork之前要注意屏蔽SIGHLD信号,否则有可能在addjob之前就调用deletejob造成竞争。
4.需要在fork后解锁SIGHLD的信号。
/* * eval - Evaluate the command line that the user has just typed in * * If the user has requested a built-in command (quit,jobs,bg or fg) * then execute it immediately. Otherwise,fork a child process and * run the job in the context of the child. If the job is running in * the foreground,wait for it to terminate and then return. Note: * each child process must have a unique process group ID so that our * background children don‘t receive SIGINT (SIGTSTP) from the kernel * when we type ctrl-c (ctrl-z) at the keyboard. */ void eval(char *cmdline) { char *argv[MAXARGS]; char buf[MAXLINE]; int isBg; pid_t pid; sigset_t mask; strcpy(buf,cmdline); isBg=parseline(buf,argv); if(argv[0]==NULL){ return; } if(!builtin_cmd(argv)){ //init mask sigemptyset(&mask); sigaddset(&mask,SIGCHLD); sigprocmask(SIG_BLOCK,&mask,NULL); //block SIGCHLD if((pid=fork())==0){ sigprocmask(SIG_UNBLOCK,NULL); //unblock SIGCHLD if(execve(argv[0],argv,environ)<0){ printf("%s:Command not found.\n",argv[0]); exit(0); } //set own pid as group pid setpgid(0,0); } if(!isBg){ addjob(jobs,pid,FG,cmdline); waitfg(pid); } else{ addjob(jobs,BG,cmdline); printf("%d %s",cmdline); } sigprocmask(SIG_UNBLOCK,NULL); //unblock SIGCHLD } return; }
builtin_cmd
builtin_cmd做的事情比较简单,判断是否是内建命令,如果是,则直接执行并返回true,否则返回false。
/* * builtin_cmd - If the user has typed a built-in command then execute * it immediately. */ int builtin_cmd(char **argv) { if(!strcmp(argv[0],"quit")||!strcmp(argv[0],"q")){ exit(0); } if(!strcmp(argv[0],"jobs")){ listjobs(jobs); return 1; } if(!strcmp(argv[0],"bg")||!strcmp(argv[0],"fg")){ do_bgfg(argv); return 1; } return 0; }
dobgfg
这个方法还是比较复杂的,主要完成了bg和fg命令的操作,需要注意如下几点:
1.需要区分输入的是pid还是jid来调用不同函数。
2.通过发送SIGCONT来重启进程,发送对象需要为进程组。
3.不要忘记将后台进程改为前台进程后需要等待前台进程完成(调用waitfg)。
/* * do_bgfg - Execute the builtin bg and fg commands */ void do_bgfg(char **argv) { struct job_t *job; char *id=argv[1]; pid_t pid; if(id==NULL){ printf("%s command requireds pid or %%jobid argument\n",argv[0]); return; } //process by jobid if(id[0]==‘%‘) { int jid = atoi(&id[1]); job=getjobjid(jobs,jid); if(job==NULL) { printf("%s:No such job\n",id); return; } } //process by pid else if(isdigit(id[0])){ int pid = atoi(&id[1]); job = getjobpid(jobs,pid); if(job==NULL) { printf("%s:No such job\n",id); return; } } else{ printf("%s: argument must be a PID or %%jobid\n",argv[0]); return; } //send SIGCONT to restart kill(-(job->pid),SIGCONT); //set job status if(!strcmp(argv[0],"bg")){ job->state = BG; printf("[%d] (%d) %s",job->jid,job->pid,job->cmdline); }else{ job->state = FG; waitfg(job->pid); } return; }
waitfg
没什么好说的,根据实验指导,这里直接使用忙等待来实现。
/* * waitfg - Block until process pid is no longer the foreground process */ void waitfg(pid_t pid) { while(pid == fgpid(jobs)){ sleep(0); } }
sigchld handler
回收僵尸进程的关键函数,需要注意如下几点:
1.理解waitpid的用法,这里使用WNOHANG|WUNTRACED的组合会更合适,表示立即返回,如果等待集合中没有进程被中止或停止返回0,否则返回进程的pid。
2.检验status的值来执行不同操作,status的含义有如下枚举:
- WIFEXITED(status):
如果进程是正常返回即为true,什么是正常返回呢?就是通过调用exit()或者return返回的 - WIFSIGNALED(status):
如果进程因为捕获一个信号而终止的,则返回true - WIFSTOPPED(status):
如果返回的进程当前是被停止,则为true
所以三种情况都是需要delete job的,当进程为停止状态同时需要设置job的status。
void sigchld_handler(int sig) { pid_t pid; int status; while((pid = waitpid(-1,&status,WNOHANG|WUNTRACED))>0){ if(WIFEXITED(status)){ deletejob(jobs,pid); } if(WIFSIGNALED(status)){ deletejob(jobs,pid); } if(WIFSTOPPED(status)){ struct job_t *job = getjobpid(jobs,pid); if(job !=NULL ){ job->state = ST; } } } if(errno != ECHILD) unix_error("waitpid error"); return; }
sigint handler
ctrl-c的响应函数,直接调用kill函数给相关进程。
void sigint_handler(int sig) { pid_t pid = fgpid(jobs); if(pid!=0){ kill(-pid,sig); } return; }
sigtstp handler
ctrl-z的响应函数,直接调用kill函数给相关进程,需要注意kill前判断状态,不要重复发送信号。
/* * sigtstp_handler - The kernel sends a SIGTSTP to the shell whenever * the user types ctrl-z at the keyboard. Catch it and suspend the * foreground job by sending it a SIGTSTP. */ void sigtstp_handler(int sig) { pid_t pid = fgpid(jobs); if(pid!=0 ){ struct job_t *job = getjobpid(jobs,pid); if(job->state == ST){ return; }else{ Kill(-pid,SIGTSTP); } } return; }
今天的关于Linux Lab 项目启动 6 年后,终于发布了 v1.0 正式版和linux-lab的分享已经结束,谢谢您的关注,如果想了解更多关于01、开源游戏-“胡子”项目启动、Cherokee 终于发布了 1.0 版本、CSAPP Lab:Bomb Lab——从拆弹到爆炸。。。、CSAPP Lab:Shell Lab——理解进程控制的秘密的相关知识,请在本站进行查询。
本文标签: