MacOS环境-手写操作系统-41-mem 第一个控制台程序

简介: MacOS环境-手写操作系统-41-mem 第一个控制台程序

mem 第一个控制台程序

1.简介

操作系统的一个重要功能是平台功能 也就是它能提供基础设施让其他程序运行在其自身之上


甚至不少应用程序发展到后期 它自身的代码量和复杂度比运行它的操作系统还要复杂


例如现在的chrome


有一类程序叫命令行程序 此类程序没有花哨的窗口特效


他们的运行方法是 用户在黑色的命令行窗口中 输入程序的名字


后面跟着提交给程序的参数 点击回车 然后程序开始运行 然后把计算后的结果展示在命令行窗口里


早期的DOS 以及现在Linux系统的Shell 都可以通过命令行来运行一系列程序


我们这一节的内容 就是实现一个命令行程序运行的功能


2.代码

我们首先要解决的是文字的滚屏问题 也就是当我们在控制台输入命令


按下回车后 文字能向上滚动一行 由于单个字体的高度是16个像素 那么滚动一行的实现方式


就是把一个窗体内的像素向上挪动16个像素单位


具体的实现代码如下

int cons_newline(int cursor_y, struct SHEET *sheet) {
    int x, y;

    if (cursor_y < 28 + 112) {
         cursor_y += 16;
    } else {
         for (y = 28; y < 28 + 112; y++) {
             for (x = 8; x < 8 + 240; x++) {
                 sheet->buf[x + y * sheet->bxsize] =
                 sheet->buf[x + (y + 16) * sheet->bxsize];
             }
         }

         for (y = 28 + 112; y < 28 + 128; y++) {
             for (x = 8; x < 8 + 240; x++) {
                 sheet->buf[x + y * sheet->bxsize] = COL8_000000;
             }
         }

         sheet_refresh(shtctl, sheet, 8, 28, 8+240, 28+128);
   }

    showString(shtctl, sheet, 8, cursor_y, COL8_FFFFFF, ">"); 
    return cursor_y;
}

cons_newline 用来实现控制台的文字向上滚动


它的做法很简单 就是把控制台的像素逐个向上移动16个单位即可


移动后最底部的一行用黑色填充


第一个输入参数cursor_y用来表示当前控制台输入所在的y坐标


第二个参数是控制台窗口的图层对象


代码中第一个for循环就是把像素依次上移16个单位


第二个循环 目的是把最后一行用黑色填充


最后程序在新的一行输出一个”>”符号


同时返回新一行的y坐标


当命令行控制台接收到的按键是回车时 调用该函数 实现换行功能

void console_task(struct SHEET *sheet, int memtotal) {
    ....
    for(;;) {
    ....
     else if (i == KEY_RETURN) {
                set_cursor(shtctl, sheet, cursor_x, cursor_y, COL8_000000);

                cursor_y = cons_newline(cursor_y, sheet);
     }
    ....
    }
}

每次回车换行时 我们先把光标的白色块给抹掉


然后执行换行逻辑 这样每次我们在控制台中点击回车时 我们的输入光标都会顺利的出现在新的一行


接下来 我们就可以实现mem命令功能了


它的逻辑简单 每当回车按下时


命令行进程看看输入的字符是否是字符串”mem”


如果是的话 那么调用内存管理接口 获取当前可用内存大小


然后以字符串的形式输出到控制台


我们看看具体实现

void console_task(struct SHEET *sheet, int memtotal) {

    ....
    char  cmdline[30];
    for(;;) {
    ....
    else if (i == KEY_RETURN) {
                set_cursor(shtctl, sheet, cursor_x, cursor_y, COL8_000000);
                cmdline[cursor_x / 8 - 2] = 0;
                cursor_y = cons_newline(cursor_y, sheet); 
                if (cmdline[0] == 'm' && cmdline[1]== 'e' && cmdline[2] == 'm'
                  && cmdline[3] == 0) {
                    char *s = intToHexStr(memtotal / (1024));
                    showString(shtctl,sheet,16,cursor_y,COL8_FFFFFF, "free ");
                    showString(shtctl,sheet,52,cursor_y, COL8_FFFFFF, s);
                    showString(shtctl, sheet, 126, cursor_y, COL8_FFFFFF, " KB");
                    cursor_y = cons_newline(cursor_y, sheet);
                }
                cursor_x = 16;
            }
    ....
    else {
                       char c = transferScanCode(i);
                       if (cursor_x < 240 && c!=0 ) {
                           set_cursor(shtctl, sheet, cursor_x, cursor_y,COL8_000000);
                           char s[2] = {c, 0};
                           cmdline[cursor_x/8 - 2] = c;
                           showString(shtctl, sheet, cursor_x, cursor_y, COL8_FFFFFF, s);
                           cursor_x += 8;
                       }
                }
    }

    ....
}

代码中 第二个else是处理处理普通输入字符的情况


此时我们把当前输入的字符全部放入到缓冲区cmdline中


当回车键按下时 我们判断cmdline中的字符形成的字符串是不是”mem”


如果是的话 我们把当前可用内存的大小转换成十六进制字符串


然后显示到控制台窗口中 当前可用内存大小是从函数入口处传进来的


是主进程启动命令行控制台进程时 传进来的一个参数


代码如下


struct SHEET*  launch_console() {
....
*((int*)(task_console->tss.esp + 4)) = (int)sht_cons;
*((int*)(task_console->tss.esp + 8)) = memman_total(memman);
....
}


主进程在启动命令行控制台前 把当前可用内存的大小放入到控制台进程的堆栈中


控制台进程启动它的主函数后 从他的输入参数中 获得主进程传进来的信息


完成系列代码后,我们就可以实现mem命令功能了


3.编译和运行

相关文章
|
1天前
|
存储 C语言 iOS开发
MacOS环境-手写操作系统-48-让内核从错误中恢复
MacOS环境-手写操作系统-48-让内核从错误中恢复
9 0
|
1天前
|
存储 API C语言
MacOS环境-手写操作系统-46,47-C语言开发应用程序
MacOS环境-手写操作系统-46,47-C语言开发应用程序
8 0
|
1天前
|
编译器 API C语言
MacOS环境-手写操作系统-45-C语言开发应用程序
MacOS环境-手写操作系统-45-C语言开发应用程序
10 0
|
1天前
|
小程序 iOS开发 MacOS
MacOS环境-手写操作系统-44-运行简单的程序
MacOS环境-手写操作系统-44-运行简单的程序
7 0
|
3月前
|
安全 Linux 网络安全
部署07--远程连接Linux系统,利用FinalShell可以远程连接到我们的操作系统上
部署07--远程连接Linux系统,利用FinalShell可以远程连接到我们的操作系统上
|
3月前
|
Linux 虚拟化 数据安全/隐私保护
部署05-VMwareWorkstation中安装CentOS7 Linux操作系统, VMware部署CentOS系统第一步,下载Linux系统,/不要忘, CentOS -7-x86_64-DVD
部署05-VMwareWorkstation中安装CentOS7 Linux操作系统, VMware部署CentOS系统第一步,下载Linux系统,/不要忘, CentOS -7-x86_64-DVD
|
2月前
|
编解码 安全 Linux
基于arm64架构国产操作系统|Linux下的RTMP|RTSP低延时直播播放器开发探究
这段内容讲述了国产操作系统背景下,大牛直播SDK针对国产操作系统与Linux平台发布的RTMP/RTSP直播播放SDK。此SDK支持arm64架构,基于X协议输出视频,采用PulseAudio和Alsa Lib处理音频,具备实时静音、快照、缓冲时间设定等功能,并支持H.265编码格式。此外,提供了示例代码展示如何实现多实例播放器的创建与管理,包括窗口布局调整、事件监听、视频分辨率变化和实时快照回调等关键功能。这一技术实现有助于提高直播服务的稳定性和响应速度,适应国产操作系统在各行业中的应用需求。
|
3月前
|
Linux 测试技术 数据安全/隐私保护
阿里云Linux os copilot 运维助手初体验
阿里云Linux os copilot 初体验
389 1
阿里云Linux os copilot 运维助手初体验
|
3月前
|
弹性计算 运维 自然语言处理
阿里云OS Copilot测评:重塑Linux运维与开发体验的智能革命
阿里云OS Copilot巧妙地将大语言模型的自然语言处理能力与操作系统团队的深厚经验相结合,支持自然语言问答、辅助命令执行等功能,为Linux用户带来了前所未有的智能运维与开发体验。
|
3月前
|
存储 缓存 安全
【Linux】冯诺依曼体系结构与操作系统及其进程
【Linux】冯诺依曼体系结构与操作系统及其进程
151 1