Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- import os
- import sys
- import subprocess
- # 参数表,内核参数和全局变量
- opts = {
- "root" : "",
- "init" : "/sbin/init",
- "rootdelay" : 10
- }
- # 输出普通信息
- def msg (s):
- if opts.get("quiet") == False:
- print(s)
- # 输出错误信息
- def err (s):
- print("ERROR: %s" % s)
- # 检查设备是否存在
- def poll_device (c1, c2):
- device=c1
- seconds=c2 if c2>=0 else 10
- if opts["udevd_running"]:
- import time
- import stat
- msg("Waiting %d seconds for device %s ..." % (seconds, device))
- while seconds>0:
- try:
- if stat.S_ISBLK(os.stat(device)[stat.ST_MODE]):
- break
- except OSError:
- seconds-=1
- return os.path.lexists(device)
- # 交互式命令行界面
- def launch_interactive_shell ():
- import code
- class FileCacher:
- def __init__(self): self.reset()
- def reset(self): self.out = []
- def write(self,line): self.out.append(line)
- def flush(self):
- output = '\n'.join(self.out)
- self.reset()
- return output
- class Shell(code.InteractiveConsole):
- def __init__(self):
- self.stdout = sys.stdout
- self.cache = FileCacher()
- code.InteractiveConsole.__init__(self)
- return
- def get_output(self): sys.stdout = self.cache
- def return_output(self): sys.stdout = self.stdout
- def push(self,line):
- self.get_output()
- code.InteractiveConsole.push(self,line)
- self.return_output()
- output = self.cache.flush()
- print(output, end='')
- #print(output)
- sh = Shell()
- sh.interact()
- # 处理内核参数
- def parse_cmdline ():
- cmds = open("/proc/cmdline", "r").read().split()
- for item in cmds:
- try:
- (name, value) = item.split('=')
- except ValueError:
- name = item
- value = False
- try:
- opts[name] = int(value)
- except ValueError:
- opts[name] = value.strip()
- # 从文件获取变量
- def get_env_from (path):
- for line in open(path, "r"):
- exp = line.split("#")[0]
- if len(exp)>0:
- name = exp.split('=')[0].strip()
- try:
- opts[name] = exp.split('=')[1].strip()
- except IndexError:
- opts[name] = ""
- # 挂载根目录
- def default_mount_handler (dest):
- if not poll_device(opts["root"], opts["rootdelay"]):
- err("Root device '%s' doesn't exist." % opts["root"])
- print("You are now being dropped into an emergency shell.")
- launch_interactive_shell()
- try:
- fstype=opts["rootfstype"]
- except:
- fstype=subprocess.check_output( \
- ["/sbin/blkid","-u","filesystem","-o","value","-s","TYPE","-p",opts["root"]]) \
- .decode("ascii").strip()
- if len(fstype) == 0:
- err("Unable to determine the file system type of %s:" % opts["root"])
- print("Either it contains no filesystem, an unknown filesystem,")
- print("or more than one valid file system signature was found.")
- print()
- print("Try adding")
- print(" rootfstype=your_filesystem_type")
- print("to the kernel command line.")
- print()
- print("You are now being dropped into an emergency shell.")
- launch_interactive_shell()
- msg("Trying to continue (this will most likely fail) ...")
- flags=''
- if opts.get("rootflags"):
- if opts.get("rw")!=None:
- flags=opts.get("rootflags")+",rw"
- elif opts.get("ro")!=None:
- flags=opts.get("rootflags")+",ro"
- else:
- if opts.get("rw")!=None:
- flags="rw"
- elif opts.get("ro")!=None:
- flags="ro"
- if flags=='':
- flags="ro"
- subprocess.call(["/bin/mount", "-t", fstype, "-o", flags, opts["root"], dest])
- # 主程序
- if __name__ == "__main__":
- subprocess.call(["/bin/busybox", "--install", "-s"])
- subprocess.call(["/bin/mount", "-t", "proc", "proc", "/proc", "-o", "nosuid,noexec,nodev"])
- subprocess.call(["/bin/mount", "-t", "sysfs", "sys", "/sys", "-o", "nosuid,noexec,nodev"])
- subprocess.call(["/bin/mount", "-t", "tmpfs", "run", "/run", "-o", "nosuid,noexec,nodev,mode=755,size=10M"])
- if open("/proc/filesystems").read().find("devtmpfs") >= 0:
- subprocess.call(["/bin/mount", "-n", "-t", "devtmpfs", "udev", "/dev", "-o", "mode=0755,size=10M,nosuid"])
- else:
- subprocess.call(["/bin/mount", "-n", "-t", "tmpfs", "udev", "/dev", "-o", "mode=0755,size=10M,nosuid"])
- subprocess.call(["/bin/mknod", "/dev/null", "c", "1", "3"])
- subprocess.call(["/bin/mknod", "/dev/zero", "c", "1", "5"])
- subprocess.call(["/bin/mknod", "/dev/console", "c", "5", "1"])
- subprocess.call(["/bin/mknod", "/dev/mem", "c", "1", "1"])
- parse_cmdline()
- print("/sbin/modprobe", file=open("/proc/sys/kernel/modprobe", "w"))
- if os.path.lexists("/sbin/udevd"):
- msg(":: Starting udevd...")
- subprocess.call(["/sbin/udevd", "--daemon", "--resolve-names=never"])
- opts["udevd_running"]=True
- msg("done.")
- else:
- opts["udevd_running"]=False
- if opts.get("disablehooks"):
- for d in opts.get("disablehooks").split(","):
- opts["dishook_"+d]=True
- if opts.get("disablemodules"):
- for d in opts.get("disablemodules").split(","):
- opts["dismod_"+d]=True
- if opts.get("earlymodules"):
- for m in opts.get("disablehooks").split(","):
- subprocess.call(["/sbin/modprobe", "-q", m])
- get_env_from("/config")
- if opts.get("MODULES"):
- for m in opts.get("MODULES")[1:-1].split():
- if not opts.get("dismod_"+m):
- subprocess.call(["/sbin/modprobe", "-q", m])
- if os.path.isdir("/hooks") and opts.get("HOOKS"):
- # 还没完全实现,只能处理udev
- if opts.get("HOOKS").find("udev")>0:
- subprocess.call(["/sbin/udevadm", "trigger", "--action=add", "--type=subsystems"])
- subprocess.call(["/sbin/udevadm", "trigger", "--action=add", "--type=devices"])
- subprocess.call(["/sbin/udevadm", "settle"])
- if opts.get("break"):
- print(":: Break requested, type 'exit' to resume operation")
- launch_interactive_shell()
- if os.path.isfile("/message"):
- msg(file(message, "r").read())
- os.mkdir("/new_root")
- default_mount_handler("/new_root")
- if not os.path.isfile("/new_root"+opts["init"]):
- err(opts["init"]+" does not exist.")
- print("Bailing out, you are on your own. Good luck.")
- print()
- launch_interactive_shell()
- if opts["udevd_running"]:
- subprocess.call(["/sbin/udevadm", "control", "--exit"])
- subprocess.call(["/sbin/udevadm", "info", "--cleanup-db"])
- for d in ("/proc", "/sys", "/dev", "/run"):
- if os.path.isdir("/new_root"+d):
- subprocess.call(["/bin/mount", "--move", d, "/new_root"+d])
- else:
- subprocess.call(["/bin/umount", d])
- os.execv("/sbin/switch_root", \
- ["/sbin/switch_root", "-c", "/dev/console", "/new_root", opts["init"]])
Advertisement
Add Comment
Please, Sign In to add comment