当前位置: 首页 > wzjs >正文

网站建设技术实现企查查免费查询入口

网站建设技术实现,企查查免费查询入口,网页版qq可以聊天吗,郑州十大平面设计公司排名文章目录 1. 前言2. qemu-user-static 的工作原理 1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. qemu-user-static 的工作原理 我们通常使用交叉编译的方式来构建 ARM 程序,譬如有…

文章目录

  • 1. 前言
  • 2. qemu-user-static 的工作原理

1. 前言

限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。

2. qemu-user-static 的工作原理

我们通常使用交叉编译的方式来构建 ARM 程序,譬如有一个 hello.c 程序,其代码如下:

// hello.c#include <stdio.h>int main(void)
{printf("Hello, World!\n");return 0;
}

x86 系统下将其交叉编译为 aarch64 程序:

$ aarch64-linux-gnu-gcc -o hello hello.c
$ file hello
hello: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=c4367fc3135655c88a487baf4a4ac0f04bcff318, for GNU/Linux 3.7.0, not stripped

试着运行:

$ ./hello
bash: ./hello: 无法执行二进制文件: 可执行文件格式错误

安装 qemu-user-static 后再运行:

$ sudo apt-get install qemu-user-static
$ ./hello
aarch64-binfmt-P: Could not open '/lib/ld-linux-aarch64.so.1': No such file or directory

看到变化了吗?虽然仍然不能运行,但是错误提示不一样了:安装 qemu-user-static 之前,提示的是 可执行文件格式错误,即系统不支持 aarch64 格式的二进制文件执行;安装 qemu-user-static 之后,系统已经支持aarch64 格式的二进制文件执行,只是提示在 x86 系统中找不到动态链接库 /lib/ld-linux-aarch64.so.1 。这是显然的,ld-linux-aarch64.so.1aarch64 架构的动态链接解释器程序,默认 x86 系统下是不存在 /lib/ld-linux-aarch64.so.1 文件的。既然是找不到这个动态链接库,有两个办法解决,第一个是放置一个这个文件,第二个是静态链接,我们采用第二种:

$ aarch64-linux-gnu-gcc -static -o hello hello.c
$ file hello
hello: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=7bb03bb527641bda2d2ee1f0a1a5e9e02d932c5f, for GNU/Linux 3.7.0, not stripped
$ ./hello
Hello, World!

程序居然能执行了!这是什么情况?是不是有点颠覆认知?原来一切的秘密,来自于 Linux 内核的 binfmt_misc 模块功能,也就是允许用户自定义可执行二进制文件格式和其翻译执行程序(如 qemu-user-static),然后通过翻译执行。如我们的例子中,就是这样一个工作过程:

                          qemu-user-static
hello (aarch64 程序) ---------------------------> 在 x86 上执行翻译 aarch64 指令为 x86 指令 

Linux 内核 binfmt_misc 模块提供了一个用户空间接口:

$ sudo mount | grep "binfmt"
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=29,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=18043)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,nosuid,nodev,noexec,relatime)

目录 /proc/sys/fs/binfmt_misc 在安装 qemu-user-static 之前,如下:

$ ls /proc/sys/fs/binfmt_misc/ -l
total 0
--w------- 1 root root 0 318 13:40 register
-rw-r--r-- 1 root root 0 318 13:40 status

在安装 qemu-user-static 之后,如下:

$ ls /proc/sys/fs/binfmt_misc
llvm-14-runtime.binfmt  qemu-aarch64  qemu-cris     qemu-microblaze  qemu-mipsel     qemu-ppc64    qemu-s390x  qemu-sparc32plus  register
llvm-18-runtime.binfmt  qemu-alpha    qemu-hexagon  qemu-mips        qemu-mipsn32    qemu-ppc64le  qemu-sh4    qemu-sparc64      status
python2.7               qemu-arm      qemu-hppa     qemu-mips64      qemu-mipsn32el  qemu-riscv32  qemu-sh4eb  qemu-xtensa
python3.10              qemu-armeb    qemu-m68k     qemu-mips64el    qemu-ppc        qemu-riscv64  qemu-sparc  qemu-xtensaeb

可以看到,除了之前的 registerstatus 文件外,多了很多其它程序。但即使还不理解这里的细节,我想读者也能猜测到,安装 qemu-user-static 后,可以支持在 x86 系统下通过 qemu-user-static 运行 alpha,arm,riscv,...... 等等平台的程序了。

那这一切是怎么做到的呢?我们来看下 binfmt_misc 的内核源码。首先,模块注册了 binfmt_misc 类型的文件系统:

/* fs/binfmt_misc.c */static struct file_system_type bm_fs_type = {.owner		= THIS_MODULE,.name		= "binfmt_misc",.mount		= bm_mount,.kill_sb	= kill_litter_super,
};
MODULE_ALIAS_FS("binfmt_misc");static int __init init_misc_binfmt(void)
{int err = register_filesystem(&bm_fs_type);...return err;
}

然后在将 binfmt_misc 文件系统挂载到 /proc/sys/fs 下时,建立了文件节点 registerstatus

/* fs/binfmt_misc.c */// bm_mount() -> ... -> bm_fill_super()static const struct file_operations bm_status_operations = {.read		= bm_status_read,.write		= bm_status_write,.llseek		= default_llseek,
};/* Superblock handling */static const struct super_operations s_ops = {.statfs		= simple_statfs,.evict_inode	= bm_evict_inode,
};static int bm_fill_super(struct super_block *sb, void *data, int silent)
{int err;static const struct tree_descr bm_files[] = {[2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},[3] = {"register", &bm_register_operations, S_IWUSR},/* last one */ {""}};err = simple_fill_super(sb, BINFMTFS_MAGIC, bm_files);if (!err)sb->s_op = &s_ops;return err;
}static struct dentry *bm_mount(struct file_system_type *fs_type,int flags, const char *dev_name, void *data)
{return mount_single(fs_type, flags, data, bm_fill_super);
}

于是用户空间看到了 /proc/sys/fs/binfmt_misc/{register,status} 两个节点。status可读写的,用来控制开启和关闭 binfmt_misc 模块功能;register 是只写的,用来注册用户自定义的可执行二进制格式和翻译执行程序,如:

echo ':qemu-aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-aarch64-static:OC' | sudo tee /proc/sys/fs/binfmt_misc/register

这里是注册 aarch64 的解释执行程序为 /usr/bin/qemu-aarch64-static 。这个细节在函数 bm_register_write() 中:

/* fs/binfmt_misc.c */static LIST_HEAD(entries); /* 自定义可执行二进制文件格式处理接口信息列表 *//* /register */static ssize_t bm_register_write(struct file *file, const char __user *buffer,size_t count, loff_t *ppos)
{Node *e;struct inode *inode;.../** 设定翻译解释器程序等信息,如:* /usr/libexec/qemu-binfmt/aarch64-binfmt-P*/e = create_entry(buffer, count);...inode = bm_get_inode(sb, S_IFREG | 0644);.../* 一种新的格式对应一个文件节点,如 /proc/sys/fs/binfmt_misc/qemu-aarch64 */e->dentry = dget(dentry);inode->i_private = e;inode->i_fop = &bm_entry_operations;d_instantiate(dentry, inode);write_lock(&entries_lock);list_add(&e->list, &entries);write_unlock(&entries_lock);...
}

看一下注册的 qemu-aarch64 类型注册信息:

$ cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/libexec/qemu-binfmt/aarch64-binfmt-P
flags: POCF
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff

好了,现在注册了自定义可执行二进制格式的翻译解释程序,那是怎么被触发的呢?看一下代码细节。首先向系统注册 misc_format 二进制格式:

/* fs/binfmt_misc.c */static struct linux_binfmt misc_format = {.module = THIS_MODULE,.load_binary = load_misc_binary,
};static int __init init_misc_binfmt(void)
{int err = register_filesystem(&bm_fs_type);if (!err)insert_binfmt(&misc_format); /* 注册 misc_format */return err;
}
/* include/linux/binfmts.h *//* Same as above, but adds a new binfmt at the top of the list */
static inline void insert_binfmt(struct linux_binfmt *fmt)
{__register_binfmt(fmt, 1);
}
/* fs/exec.c */static LIST_HEAD(formats);
static DEFINE_RWLOCK(binfmt_lock);void __register_binfmt(struct linux_binfmt * fmt, int insert)
{BUG_ON(!fmt);if (WARN_ON(!fmt->load_binary))return;write_lock(&binfmt_lock);insert ? list_add(&fmt->lh, &formats) :list_add_tail(&fmt->lh, &formats);write_unlock(&binfmt_lock);
}

然后在执行二进制格式时,如果不匹配到任何其它已指格式和架构的时候,在执行 misc_format 中注册的、匹配的某种自定义格式的翻译执行程序:

do_execveat_common()exec_binprm()search_binary_handler()int search_binary_handler(struct linux_binprm *bprm)
{...retry:read_lock(&binfmt_lock);list_for_each_entry(fmt, &formats, lh) {...retval = fmt->load_binary(bprm); /* load_misc_binary() */...}...
}
/* fs/binfmt_misc.c */static int load_misc_binary(struct linux_binprm *bprm)
{Node *fmt;struct file *interp_file = NULL;int retval;int fd_binary = -1;.../* to keep locking time low, we copy the interpreter string */read_lock(&entries_lock);fmt = check_file(bprm); /* 找到匹配的格式 */if (fmt)dget(fmt->dentry);read_unlock(&entries_lock);...if (fmt->flags & MISC_FMT_OPEN_FILE) {interp_file = filp_clone_open(fmt->interp_file);if (!IS_ERR(interp_file))deny_write_access(interp_file);} else {interp_file = open_exec(fmt->interpreter);}/* 重置解释器程序,如更新为 /usr/libexec/qemu-binfmt/aarch64-binfmt-P */bprm->file = interp_file;.../* 用新的解释器程序 (如 /usr/libexec/qemu-binfmt/aarch64-binfmt-P) 来执行程序 */retval = search_binary_handler(bprm);...
}

到此,整个 qemu-user-static 的主干工作流程已经分析完毕。


文章转载自:

http://s6IJhkl8.qrdhz.cn
http://JGfr3edT.qrdhz.cn
http://JsZwMYMm.qrdhz.cn
http://CSZ7ADIN.qrdhz.cn
http://zp2mB1Qu.qrdhz.cn
http://en7Ca3yF.qrdhz.cn
http://DJgv8a6L.qrdhz.cn
http://6BfVolg6.qrdhz.cn
http://QjIOkGpE.qrdhz.cn
http://W6arrRGc.qrdhz.cn
http://oW1Jwkwz.qrdhz.cn
http://aXdlbT98.qrdhz.cn
http://I0HdzN1w.qrdhz.cn
http://etvAnBrU.qrdhz.cn
http://tFuunnVM.qrdhz.cn
http://zsfcsq6G.qrdhz.cn
http://7chgdFP0.qrdhz.cn
http://gbQQQKJD.qrdhz.cn
http://4E2gL0vu.qrdhz.cn
http://baaFffGw.qrdhz.cn
http://3vBe8yep.qrdhz.cn
http://HUYH9jOY.qrdhz.cn
http://VGQa9BTn.qrdhz.cn
http://lQrJBM8T.qrdhz.cn
http://PuQ9tcHF.qrdhz.cn
http://Z4FLOGCJ.qrdhz.cn
http://got6NrjJ.qrdhz.cn
http://5CcrqBfJ.qrdhz.cn
http://tBsfgtQr.qrdhz.cn
http://xlbc8Uce.qrdhz.cn
http://www.dtcms.com/wzjs/713064.html

相关文章:

  • 网站建设程序开发过程中学生在哪里学编程最好
  • 网站做百度推广河北网站建设公司排名
  • 建设英文网站的请示静态网站规范
  • 上海网站备案流程什么网站做推广效果好
  • 受欢迎的购物网站建设discuz导入wordpress
  • 分站式二手车网站源码it外包合同
  • 做电子商务网站价格画册设计免费模板
  • 简约 网站深圳做网站建设
  • 功能型网站seo服务外包费用
  • 上海网站建设系统上海团购网站建设
  • 网站建设兼职网wordpress修改下载主题介绍
  • 手机网站seo优化google手机官网
  • 网站建设 中企动力南昌0792樱桃小丸子网页设计代码
  • 网站分享链接怎么做本地的营销网站建设
  • 温州网站设计服务网站建设公司专业网站企业开发
  • 大连企业网站建设模板wordpress 连载
  • 网站建设与管理实践心得网站规划设计的一般流程
  • 网站建设合同包含go语言网站开发
  • 城乡建设部网站房产查询手机上怎么创建wordpress
  • 建设网站要用什么软件建设银行内部网站
  • 深圳珠宝品牌网站设计建站视频教程网
  • 投资公司网站建设意义代理服务器在线
  • 使用亚马逊云做网站双减之下托管班合法吗
  • 律师微网站制作定制网站制作费用
  • 有做网站的吗 优帮云广西网站开发
  • 怎么用云校建设学校网站每天免费2小时外网加速
  • 免费图表制作网站网站安全建设进展情况汇报
  • 我不需要做网站wordpress设置不被搜索
  • 高密做网站哪家好代理软文媒体发稿平台
  • 建设网站需要哪些流程图如何做网站的搜索栏