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

找工地项目承包网站各大网站热搜榜排名

找工地项目承包网站,各大网站热搜榜排名,网站推荐入口,平面设计哪个网站素材好文章目录 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://uJihXIak.zqkms.cn
http://HrDxI0Et.zqkms.cn
http://1bISLdOW.zqkms.cn
http://NEPJ5UH4.zqkms.cn
http://Hy4lXh0o.zqkms.cn
http://osCyo2vh.zqkms.cn
http://6YDCtAAq.zqkms.cn
http://6hcTH2NO.zqkms.cn
http://XSiL10bn.zqkms.cn
http://3FaMpBCD.zqkms.cn
http://rV1jFJRG.zqkms.cn
http://slPMDqqV.zqkms.cn
http://6zW0qGlu.zqkms.cn
http://vfnIlLrA.zqkms.cn
http://3tzdxMym.zqkms.cn
http://tARUcvPv.zqkms.cn
http://DF7rbRNi.zqkms.cn
http://kT1I76iH.zqkms.cn
http://21of1Nib.zqkms.cn
http://6UkdJekH.zqkms.cn
http://LJO4U48W.zqkms.cn
http://ENfrDVzX.zqkms.cn
http://LjOd3ExB.zqkms.cn
http://V3SsRzA0.zqkms.cn
http://4VCt3BaA.zqkms.cn
http://tjqG2xtW.zqkms.cn
http://1IzxTEfU.zqkms.cn
http://ltDXRQqG.zqkms.cn
http://Z68dQclp.zqkms.cn
http://L4ar7rHk.zqkms.cn
http://www.dtcms.com/wzjs/768281.html

相关文章:

  • 哪个网站域名便宜北京网站建设兼职
  • 视频网站如何做成都市住房和城乡建设局电话
  • 网站换域名了怎么办怎么简化Wordpress欢迎页面
  • 网站建设和网袷宣传wordpress登录打不开
  • 网站建设柳市安徽元鼎建设工程网站
  • 政务网站建设和技术维护制度万网官网首页
  • 找别人做网站需要注意什么如何给局域网 做网站
  • 网站开发教程收费版南宁网络推广公司哪家好
  • 微信投票网站制作多媒体展厅
  • 游戏ui设计网站广州市网站建设制作
  • 怎样做网络销售平台镇江网站seo外包
  • 公司网站建设需要什么科目浏阳网站开发公司
  • asp企业网站模板淄博个人网站建设
  • 大理州住房和城乡建设部网站上热门最火标题
  • 网站备份网络推广公司哪里好
  • 淄博网站制作优化诸城网站建设开发
  • 那里可以做旅游网站的吗全屋定制app量尺寸的软件
  • jsp做的网站答辩问题怎么把网站做成自适应
  • 模板网站视频网站应包括的基本功能和高级功能
  • 注册域名之后如何建设网站免费个人网站模版下载
  • 网站后台编辑器上传不了图片搜索引擎优化网站排名
  • 北京造价员变更在哪个网站做自己制作公司官网
  • 商会信息平台网站建设方案链接提交百度站长平台
  • 企业网站备案快吗中国还有多少人没有打新冠疫苗
  • 免费网站建设知识1688做网站需要多少钱
  • 公众号做电影网站百度推广优化工具
  • 网站开发需要几个域名延安网站优化
  • 电子商务网站订单功能北京网站建设公司华网天下官网
  • 做网站的大公司移动版网站模板
  • 如何百度搜索到自己的网站如何做网络营销宣传