百度搜索seo优化技巧/seo外链优化策略

百度搜索seo优化技巧,seo外链优化策略,外贸b2b独立站,丽江网站建设目录 建立抽象 实现加载 实现sys_execv !!!提示:因为实现问题没有测试。所以更像是笔记! exec 函数的作用是用新的可执行文件替换当前进程的程序体。具体来说,exec 会将当前正在运行的用户进程的进程体&…

目录

建立抽象

实现加载

实现sys_execv


!!!提示:因为实现问题没有测试。所以更像是笔记!

exec 函数的作用是用新的可执行文件替换当前进程的程序体。具体来说,exec 会将当前正在运行的用户进程的进程体(包括代码段、数据段、堆、栈等)替换为一个新的可执行文件的进程体。这样,新的程序会接管当前进程的地址空间,继续执行新程序的代码,但该进程的 PID(进程ID)保持不变。也就是说,执行 exec 后,原来进程的地址空间被清除,并且新程序的内容会加载到同样的进程中,继续执行。

为什么需要实现 exec 呢?这个问题的答案与 shell 的工作方式密切相关。在实现一些简单的命令时,我们使用了类似 if-else if 的结构来判断并执行不同的命令。然而,这种方法存在很大的局限性。首先,它无法处理用户输入的新命令,因为我们不能预见到用户会输入什么命令,且每添加一个新命令就需要修改代码并重新编译。这种方式不仅繁琐,而且无法应对外部程序的运行。

exec 的实现解决了这个问题。当 exec 被调用时,它允许用户运行外部程序,而不需要修改 shell 本身的代码。用户输入的命令会被解析,且通过 exec 函数加载并执行对应的外部程序,从而提供了更灵活的命令执行方式。

exec 是一个函数簇,包含多个相关的函数,区别主要在于如何表示程序对象以及是否传入环境变量。例如,execv 函数就不需要传入环境变量,但其他 exec 函数可能会接受额外的环境变量。

当调用 execv 时,如果执行成功,进程将直接跳转到新程序,并不会返回,因此它没有返回值。调用 execv 失败时,它会返回 -1,并设置错误码。这是因为 exec 执行新程序时,原进程的执行流被完全替换,进程不会再回到原来的位置,因而不需要像传统函数那样返回值。

建立抽象

我们先对exe文件做抽象:

extern void intr_exit(void);
typedef uint32_t Elf32_Word, Elf32_Addr, Elf32_Off;
typedef uint16_t Elf32_Half;
​
/* 32-bit ELF header */
struct Elf32_Ehdr {unsigned char e_ident[16]; // ELF identification bytesElf32_Half e_type;         // Type of file (e.g., executable)Elf32_Half e_machine;      // Machine architectureElf32_Word e_version;      // ELF versionElf32_Addr e_entry;        // Entry point addressElf32_Off e_phoff;         // Program header offsetElf32_Off e_shoff;         // Section header offsetElf32_Word e_flags;        // Processor-specific flagsElf32_Half e_ehsize;       // ELF header sizeElf32_Half e_phentsize;    // Program header entry sizeElf32_Half e_phnum;        // Number of program headersElf32_Half e_shentsize;    // Section header entry sizeElf32_Half e_shnum;        // Number of section headersElf32_Half e_shstrndx;     // Section header string table index
};
​
/* Program header (segment descriptor) */
struct Elf32_Phdr {Elf32_Word p_type;   // Segment type (e.g., PT_LOAD)Elf32_Off p_offset;  // Offset in fileElf32_Addr p_vaddr;  // Virtual address in memoryElf32_Addr p_paddr;  // Physical address (unused)Elf32_Word p_filesz; // Size of segment in fileElf32_Word p_memsz;  // Size of segment in memoryElf32_Word p_flags;  // Segment flagsElf32_Word p_align;  // Segment alignment
};
​
/* Segment types */
enum segment_type {PT_NULL,    // Ignore segmentPT_LOAD,    // Loadable segmentPT_DYNAMIC, // Dynamic loading informationPT_INTERP,  // Name of dynamic loaderPT_NOTE,    // Auxiliary informationPT_SHLIB,   // ReservedPT_PHDR     // Program header
};

这段代码定义了32位ELF(Executable and Linkable Format)格式的结构体以及相关的常量,用于描述ELF文件的头部和程序段的描述。具体来说,主要包括以下内容:

  1. Elf32_Ehdr: 该结构体表示ELF文件的头部,包含了ELF文件的基本信息,如文件标识、类型、机器架构、入口地址、程序头的偏移量等。具体字段的含义如下:

    • e_ident:ELF文件标识字节,用于标识文件类型和版本。

    • e_type:文件类型,表明ELF文件是可执行文件、共享库文件还是其他类型。

    • e_machine:表示机器架构的字段,如x86、ARM等。

    • e_version:ELF版本,通常为1。

    • e_entry:程序入口点的地址。

    • e_phoff:程序头部的偏移量,指向包含程序段信息的位置。

    • e_shoff:节头部的偏移量,指向包含节信息的位置。

    • e_flags:处理器特定的标志。

    • e_ehsize:ELF头部的大小。

    • e_phentsize:程序头项的大小。

    • e_phnum:程序头的数量。

    • e_shentsize:节头项的大小。

    • e_shnum:节头的数量。

    • e_shstrndx:节头字符串表的索引。

  2. Elf32_Phdr: 该结构体表示ELF文件中的程序头(segment descriptor),用于描述文件中的每个段。字段的含义如下:

    • p_type:段的类型,如可加载段、动态段等。

    • p_offset:段在文件中的偏移。

    • p_vaddr:段在内存中的虚拟地址。

    • p_paddr:段在物理内存中的地址(通常不使用)。

    • p_filesz:段在文件中的大小。

    • p_memsz:段在内存中的大小。

    • p_flags:段的标志,如可读、可写、可执行等。

    • p_align:段的对齐方式。

  3. segment_type:该枚举定义了常见的段类型,如:

    • PT_NULL:表示忽略该段。

    • PT_LOAD:表示可加载的段(常见的代码和数据段)。

    • PT_DYNAMIC:动态加载信息。

    • PT_INTERP:动态加载器的名称。

    • PT_NOTE:辅助信息。

    • PT_SHLIB:保留段。

    • PT_PHDR:程序头。

实现加载

/* Load a segment from a file into virtual memory at the specified address */
static bool segment_load(int32_t fd, uint32_t offset, uint32_t filesz,uint32_t vaddr) {uint32_t vaddr_first_page =vaddr & 0xfffff000; // First page of the virtual addressuint32_t size_in_first_page =PG_SIZE - (vaddr & 0x00000fff); // Size of the segment in the first pageuint32_t occupy_pages = 0;
​// If the segment doesn't fit in a single pageif (filesz > size_in_first_page) {uint32_t left_size = filesz - size_in_first_page;occupy_pages = ROUNDUP(left_size, PG_SIZE) + 1; // +1 for the first page} else {occupy_pages = 1;}
​// Allocate memory for the segment in the process's address spaceuint32_t page_idx = 0;uint32_t vaddr_page = vaddr_first_page;while (page_idx < occupy_pages) {uint32_t *pde = pde_ptr(vaddr_page); // Page directory entryuint32_t *pte = pte_ptr(vaddr_page); // Page table entry
​// Allocate memory if PDE or PTE doesn't existif (!(*pde & PG_P_1) || !(*pte & PG_P_1)) {if (!get_a_page(PF_USER, vaddr_page)) {return false;}}vaddr_page += PG_SIZE;page_idx++;}
​// Read the segment data from the file and load it into memorysys_lseek(fd, offset, SEEK_SET);sys_read(fd, (void *)vaddr, filesz);return true;
}
​

函数 segment_load 负责将一个可执行文件中的特定段加载到进程的虚拟内存中,它接收四个参数:文件描述符 fd,段在文件中的偏移量 offset,段大小 filesz,以及段应加载到的虚拟地址 vaddr。其中 filesz 命名虽然让人容易联想到整个文件大小,但它其实是 ELF 格式中段头部的字段名 p_filesz,表示当前这个段在文件中的实际大小,因此用作参数名是为了与 ELF 中的结构保持一致。

段的加载实质上就是内核为新进程分配内存的过程。由于程序通常由多个段组成,内核需要对每个段逐一加载。加载时以页为单位进行内存管理,因此即使一个段不满一页,也必须以页为粒度分配内存。变量 vaddr_first_page 是将段的虚拟地址 vaddr 向下对齐到页起始地址,用于确定从哪里开始分配页框。而变量 size_in_first_page 则表示该段在第一页中所占用的字节数,如果 filesz 大于这个值,说明段会跨页,因此接下来计算还需多少页框,最终由 occupy_pages 给出总的页框数。

接下来是页框分配逻辑,考虑到这是 exec 执行新程序的场景,当前进程的页表结构还在用,若某虚拟地址已经存在对应的物理页,则无需重新分配,只需直接复用原页框覆盖其内容即可;否则就通过 get_a_page 分配一个新页框。分配时逐页判断并处理,直到整段的地址空间都被准备好。

页框分配完成后,便可以真正加载段的数据了。首先使用 sys_lseek 将文件读指针移动到段的起始偏移位置 offset,再用 sys_read 将长度为 filesz 的数据读入到从 vaddr 开始的虚拟地址中。至此,这个段被完整加载进内存。整个过程体现了分段加载、按页管理、懒分配页框的设计思路,也保证了内存使用的灵活性与效率。

/* Load a user program from the filesystem by pathname, return entry point* address or -1 on failure */
static int32_t load(const char *pathname) {int32_t ret = -1;struct Elf32_Ehdr elf_header;struct Elf32_Phdr prog_header;k_memset(&elf_header, 0, sizeof(struct Elf32_Ehdr));
​int32_t fd = sys_open(pathname, O_RDONLY); // Open the program fileif (fd == -1) {return -1;}
​// Read the ELF header from the fileif (sys_read(fd, &elf_header, sizeof(struct Elf32_Ehdr)) !=sizeof(struct Elf32_Ehdr)) {ret = -1;goto done;}
​// Verify the ELF headerif (k_memcmp(elf_header.e_ident, "\177ELF\1\1\1", 7) ||elf_header.e_type != 2 || elf_header.e_machine != 3 ||elf_header.e_version != 1 || elf_header.e_phnum > 1024 ||elf_header.e_phentsize != sizeof(struct Elf32_Phdr)) {ret = -1;goto done;}
​Elf32_Off prog_header_offset = elf_header.e_phoff;Elf32_Half prog_header_size = elf_header.e_phentsize;
​// Iterate over all program headersuint32_t prog_idx = 0;while (prog_idx < elf_header.e_phnum) {k_memset(&prog_header, 0, prog_header_size);
​// Seek to the program header location in the filesys_lseek(fd, prog_header_offset, SEEK_SET);
​// Read the program header from the fileif (sys_read(fd, &prog_header, prog_header_size) != prog_header_size) {ret = -1;goto done;}
​// If the segment is loadable, load it into memoryif (PT_LOAD == prog_header.p_type) {if (!segment_load(fd, prog_header.p_offset, prog_header.p_filesz,prog_header.p_vaddr)) {ret = -1;goto done;}}
​// Move to the next program headerprog_header_offset += elf_header.e_phentsize;prog_idx++;}
​ret = elf_header.e_entry; // Return the entry point of the program
done:sys_close(fd); // Close the filereturn ret;
}
 

函数 load 的核心功能是加载一个 ELF 格式的用户程序文件,并将其段映射到当前进程的虚拟地址空间中。如果加载成功,返回值是该程序的入口地址(即进程执行的起点);如果失败,返回 −1。

函数开始先声明两个结构体变量:elf_headerprog_header,分别用于保存 ELF 文件头和程序段头。在读取 ELF 文件头后(第 102 行),程序紧接着从第 108 行开始验证 ELF 文件是否合法。

首先检查的是 ELF 文件的魔数 e_ident[0-6],这 7 个字节应依次为:

  • 0x7F(用八进制 \177 表示)

  • 'E'(0x45)

  • 'L'(0x4C)

  • 'F'(0x46)

  • 1:32 位格式

  • 1:小端格式

  • 1:版本号

这几项是 ELF 文件的标准标志,如果不匹配,说明该文件不是合法的 ELF 可执行文件。接下来还会检查以下几个字段:

  • e_type 是否为 ET_EXEC(值为 2,代表可执行文件)

  • e_machine 是否为 EM_386(值为 3,表示 x86 架构)

  • e_version 是否为 1(当前 ELF 版本)

  • e_phnum(程序头数量)是否小于等于 1024

  • e_phentsize(每个程序头条目的大小)是否等于 sizeof(Elf32_Phdr)

这些检查都通过后,才认为这是一个有效的 ELF 可执行文件。

接下来,从 ELF 头中读取段头信息的起始偏移地址 e_phoff,读取到变量 prog_header_offset。段头条目的字节大小 e_phentsize 赋给 prog_header_size,条目总数 e_phnum 用于控制接下来的循环。

然后从第 122 行进入循环,逐个读取每个段头。每次循环会先通过 sys_lseek 将文件指针跳到对应段头位置,然后通过 sys_read 读取一条段头到 prog_header。第 136 行判断该段是否是 PT_LOAD 类型,也就是是否是可加载段。如果是,就调用 segment_load,将该段的内容从文件加载到内存对应的虚拟地址。

所有段处理完毕后,从 ELF 头中提取程序入口地址 e_entry 赋给返回值 ret,这表示程序开始执行的地址。

最后,无论是否加载成功,都会通过 sys_close 关闭打开的 ELF 文件,返回值为加载成功的入口地址或失败的 −1。

总体来说,load 函数的实现非常典型地体现了 ELF 格式的标准解析流程、段式加载方式、虚拟内存分配控制等关键内核概念,是内核启动用户进程的核心部分之一。

实现sys_execv

/* Replace the current process with the program at the specified path */
int32_t sys_execv(const char *path, const char *argv[]) {uint32_t argc = 0;while (argv[argc]) {argc++; // Count the number of arguments}
​// Load the program and get its entry pointint32_t entry_point = load(path);if (entry_point == -1) { // If loading failed, return -1return -1;}
​TaskStruct *cur = current_thread(); // Get the current running thread (process)k_memcpy(cur->name, path, TASK_NAME_ARRAY_SZ); // Update the process name
​// Update the stack with the argumentsInterrupt_Stack *intr_0_stack =(Interrupt_Stack *)((uint32_t)cur + PG_SIZE - sizeof(Interrupt_Stack));intr_0_stack->ebx = (int32_t)argv;intr_0_stack->ecx = argc;intr_0_stack->eip = (void *)entry_point;intr_0_stack->esp = (void *)KERNEL_V_START; // Set stack pointer to the highest// user space address
​// Jump to the entry point of the new processasm volatile("movl %0, %%esp; jmp intr_exit":: "g"(intr_0_stack): "memory");return 0;
}

sys_execv 函数的作用是将当前正在运行的进程替换为另一个可执行文件 path 所指定的程序,同时把参数数组 argv 一并传给新程序。这个过程不会返回,一旦成功,当前进程就“变成”了另一个程序。

首先,函数会遍历 argv,统计参数个数并存入变量 argc。接着调用 load(path) 试图加载用户程序,如果加载失败(返回 -1),函数立即返回 -1。若加载成功,程序的入口地址会被保存下来,作为后续执行的跳转目标。

之后,函数更新当前进程控制块中的 name 字段,使其反映正在执行的新程序名,这样在通过 ps 等工具查看时会显示为新程序的名字。

然后获取当前线程的内核栈顶地址。此时栈中存储的是旧进程的中断现场,但很快要把这些内容替换掉,准备启动新进程。函数将参数个数 argc 写入栈中保存的 ecx 寄存器位置,将参数数组 argv 的地址写入 ebx 寄存器位置。因为 ebx 通常用于保存基地址,而 ecx 常用于计数,这是一种传统习惯,也便于未来从运行库中取参数。接着将程序入口地址写入 eip,用于后续跳转执行;再将用户栈指针 esp 初始化为 0xc0000000,即用户空间最高地址,以便新程序使用。

设置完成后,通过内联汇编将 esp 寄存器修改为新的内核栈地址,并跳转到 intr_exit。这个跳转操作会恢复栈中保存的所有寄存器状态,包括 eip、esp 和参数寄存器等,相当于“伪装”从中断中返回,从而进入新程序的执行流程。

因为这个过程是不可逆的,调用成功后不会返回到原来的函数中,所以 return 0 这一行永远不会执行,它的存在只是为了避免编译器报错。整段代码实现的是典型的 exec 功能,用一个新的程序完全替换当前进程的执行内容。

下一篇

从0开始的操作系统手搓教程46——实现wait和exit-CSDN博客文章浏览阅读522次,点赞7次,收藏8次。实现exit和wait(笔记,因为实现问题没有测试) https://blog.csdn.net/charlie114514191/article/details/146144946

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/71947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【python爬虫】酷狗音乐爬取练习

注意&#xff1a;本次爬取的音乐仅有1分钟试听&#xff0c;仅作学习爬虫的原理&#xff0c;完整音乐需要自行下载客户端。 一、 初步分析 登陆酷狗音乐后随机选取一首歌&#xff0c;在请求里发现一段mp3文件&#xff0c;复制网址&#xff0c;确实是我们需要的url。 复制音频的…

Linux开发工具----vim

目录 Linux编辑器-vim使用 1. vim的基本概念 正常/普通/命令模式(Normal mode) 插入模式(Insert mode) 底行模式(last line mode) 2. vim的基本操作 3. vim正常模式命令集 4. vim底行模式命令集 5. vim操作总结 (本篇文章相当于vim常用命令字典) Linux编辑器-vim使用 我们先来看…

基于云函数的自习室预约微信小程序+LW示例参考

全阶段全种类学习资源&#xff0c;内涵少儿、小学、初中、高中、大学、专升本、考研、四六级、建造师、法考、网赚技巧、毕业设计等&#xff0c;持续更新~ 文章目录 [TOC](文章目录) 1.项目介绍2.项目部署3.项目部分截图4.获取方式 1.项目介绍 技术栈工具&#xff1a;云数据库…

卷积神经网络与计算机视觉:从数学基础到实战应用

卷积神经网络与计算机视觉&#xff1a;从数学基础到实战应用 摘要 本文深入解析卷积神经网络&#xff08;CNN&#xff09;的核心原理及其在计算机视觉中的应用。首先介绍卷积与互相关的数学定义及在神经网络中的实际应用差异&#xff0c;接着从系统设计视角分析卷积的线性代数…

从Manus到OpenManus:多智能体协作框架如何重构AI生产力?

文章目录 Manus&#xff1a;封闭生态下的通用AI智能体OpenManus&#xff1a;开源社区的闪速复刻挑战与未来&#xff1a;框架落地的现实边界当前局限性未来演进方向 OpenManus使用指南1. 环境配置2. 参数配置3. 替换搜索引擎4. 运行效果 协作框架开启AI生产力革命 Manus&#xf…

js 使用 Web Workers 来实现一个精确的倒计时,即使ios手机锁屏或页面进入后台,倒计时也不会暂停。

## 效果如上 <!-- 将 main.js 和 worker.js 放在同一个目录下&#xff0c;然后在 HTML 文件中引入 main.js --><!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content&q…

Docker Compose国内镜像一键部署dify

克隆代码 git clone https://github.com/langgenius/dify.git进入docker目录 cd docker修改.env部分 # 将环境模版文件变量重命名 cp .env.example .env # 修改 .env,修改nginx的host和端口,避免端口冲突 NGINX_SERVER_NAME192.168.1.223 NGINX_PORT1880 NGINX_SSL_PORT1443…

NO.29十六届蓝桥杯备战|string九道练习|reverse|翻转|回文(C++)

P5015 [NOIP 2018 普及组] 标题统计 - 洛谷 #include <bits/stdc.h> using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(nullptr);string s;getline(cin, s);int sz s.size();int cnt 0;for (int i 0; i < sz; i){if (isspace(s[i]))continue…

嵌入式音视频通话SDK组件EasyRTC:全平台设备兼容,智能硬件里的WebRTC调用实践

在万物互联时代&#xff0c;智能硬件设备对实时音视频通信的需求呈现爆发式增长。传统基于PC或移动端的WebRTC方案难以满足嵌入式设备在资源占用、低延迟传输和硬件适配等方面的特殊需求。本文将深入探讨如何通过EasyRTC嵌入式音视频通信SDK在嵌入式设备中实现高效的WebRTC视频…

Aim Robotics电动胶枪:机器人涂胶点胶的高效解决方案

在自动化和智能制造领域&#xff0c;机器人技术的应用越来越广泛&#xff0c;而涂胶和点胶作为生产过程中的重要环节&#xff0c;也逐渐实现了自动化和智能化。Aim Robotics作为一家专注于机器人技术的公司&#xff0c;其推出的电动胶枪为这一领域带来了高效、灵活且易于操作的…

c语言笔记 数组进阶题目的理解

题目&#xff1a;声明一个二维 int 型数组 a&#xff0c;再声明另一个一维数组指针数组 b&#xff0c;使该数组 b 的每一个指针分别指向二维数组 a 中的每一个元素(即每一个一维数组)&#xff0c;然后利用数组 b 计算数组 a 的和。 图解&#xff1a;画图帮助理解 我们要清楚什…

Photo Works在线图片编辑器:一键修复老照片,轻松焕新记忆

★【概况介绍】 今天突然收到我的朋友电脑出故障了,截图给我,我一看就知道这个是缺少必要的组件引起的故障。结合这个问题,我来谈谈自己的解决思路和方法,希望能够帮助到大家。帮助大家是我最开心的事情。以前只是帮朋友解决问题,没有记录下来,刚刚接触到这个平台,刚好可…

FANformer:融合傅里叶分析网络的大语言模型基础架构

近期大语言模型(LLM)的基准测试结果引发了对现有架构扩展性的思考。尽管OpenAI推出的GPT-4.5被定位为其最强大的聊天模型&#xff0c;但在多项关键基准测试上的表现却不及某些规模较小的模型。DeepSeek-V3在AIME 2024评测中达到了39.2%的Pass1准确率&#xff0c;在SWE-bench Ve…

【 IEEE出版 | 快速稳定EI检索 | 往届已EI检索】2025年储能及能源转换国际学术会议(ESEC 2025)

重要信息 主会官网&#xff1a;www.net-lc.net 【论文【】投稿】 会议时间&#xff1a;2025年5月9-11日 会议地点&#xff1a;中国-杭州 截稿时间&#xff1a;见官网 提交检索&#xff1a;IEEE Xplore, EI Compendex, Scopus 主会NET-LC 2025已进入IEEE 会议官方列表!&am…

react基础语法视图层类组件

react基础语法视图层&类组件 MVVM *区别mvc&mvvm 两者的区别&#xff1a; 数据模型去渲染视图。数据层改了&#xff0c;vue自己会监听到帮我们拿最新的数据去渲染视图&#xff1b;构建数据构建视图&#xff0c;数据驱动的思想。这一套是非常相似的。 视图中的内容改变&…

开发、科研、日常办公工具汇总(自用,持续更新)

主要记录汇总一下自己平常会用到的网站工具&#xff0c;方便查阅。 update&#xff1a;2025/2/11&#xff08;开发网站补一下&#xff09; update&#xff1a;2025/2/21&#xff08;补充一些AI工具&#xff0c;刚好在做AI视频相关工作&#xff09; update&#xff1a;2025/3/7…

51c大模型~合集10

我自己的原文哦~ https://blog.51cto.com/whaosoft/11547799 #Llama 3.1 美国太平洋时间 7 月 23 日&#xff0c;Meta 公司发布了其最新的 AI 模型 Llama 3.1&#xff0c;这是一个里程碑时刻。Llama 3.1 的发布让我们看到了开源 LLM 有与闭源 LLM 一较高下的能力。 Meta …

如何使用postman来测试接口

一、postman的介绍与下载 可参考&#xff1a; https://blog.csdn.net/freeking101/article/details/80774271 二、api获取网站 阿里云API应用市场 地址&#xff1a;云市场_镜像市场_软件商店_建站软件_服务器软件_API接口_应用市场 - 阿里云 三、具体测试过程 可模拟浏览…

数据库系统概论(二)数据模型

数据库系统概论&#xff08;二&#xff09;数据模型 数据库系统概论&#xff08;二&#xff09;数据模型前言一、数据建模二、概念模型三、数据模型的三要素四、层次模型五、网状模型六、关系模型 总结&#xff08;核心概念速记&#xff09;&#xff1a; 数据库系统概论&#x…

清华同方国产电脑能改windows吗_清华同方国产系统改win7教程

清华同方国产电脑能改windows吗&#xff1f;清华同方国产电脑如果采用的是兆芯kx-6000系列或kx-7000系列以及海光c86 3250 3350 X86架构处理器可以安装windows。在安装win7时bios中要关闭“安全启动”和开启legacy传统模式支持&#xff0c;如果是NVME接口的固态硬盘&#xff0c…