'''
ВНИМАНИЕ!!! ПРОЧИТАЙТЕ ПЕРЕД ЗАПУСКОМ!!!
Запуск операционной системы QubicOS в браузере с помощью wokwi.com
Для запуска операционной системы QubicOS в браузере, необходимо выполнить следующие шаги:
1. Перейдите на сайт wokwi.com и откройте новый проект.
2. Перейдите в репозиторий QubicOS на GitHub по адресу https://hub.mos.ru/qubicos/rubik/-/tree/main/builds/wokwi и найдите файл distro.csv. Этот файл содержит сборку операционной системы, предназначенную для запуска в симуляторе wokwi.
3. Скачайте файл distro.csv на свой компьютер.
4. Вернитесь к проекту на wokwi.com и найдите кнопку "Upload files" (Загрузить файлы). Нажмите на нее и выберите загрузку скачанного файла distro.csv.
5. После загрузки файла, нажмите кнопку "Запустить симуляцию" (Start Simulation). Начнется процесс распаковки и загрузки операционной системы в симулятор.
6. По завершению распаковки файлов, симуляция запустит операционную систему QubicOS в браузере.
7. Теперь вы можете взаимодействовать с операционной системой QubicOS через интерфейс симулятора wokwi.com, вводить команды, запускать программы и выполнять другие действия, как если бы вы работали непосредственно на устройстве с установленной QubicOS.
Обратите внимание, что для корректной работы симулятора и запуска операционной системы необходимо наличие стабильного интернет-соединения. Также важно загружать актуальные сборки distro.csv из репозитория QubicOS, чтобы использовать последнюю версию операционной системы.
'''
import uctypes, os
# http://www.gnu.org/software/tar/manual/html_node/Standard.html
TAR_HEADER = {
"name": (uctypes.ARRAY | 0, uctypes.UINT8 | 100),
"size": (uctypes.ARRAY | 124, uctypes.UINT8 | 11),
}
DIRTYPE = "dir"
REGTYPE = "file"
def roundup(val, align):
return (val + align - 1) & ~(align - 1)
class FileSection:
def __init__(self, f, content_len, aligned_len):
self.f = f
self.content_len = content_len
self.align = aligned_len - content_len
def read(self, sz=65536):
if self.content_len == 0:
return b""
if sz > self.content_len:
sz = self.content_len
data = self.f.read(sz)
sz = len(data)
self.content_len -= sz
return data
def readinto(self, buf):
if self.content_len == 0:
return 0
if len(buf) > self.content_len:
buf = memoryview(buf)[: self.content_len]
sz = self.f.readinto(buf)
self.content_len -= sz
return sz
def skip(self):
sz = self.content_len + self.align
if sz:
buf = bytearray(16)
while sz:
s = min(sz, 16)
self.f.readinto(buf, s)
sz -= s
class TarInfo:
def __str__(self):
return "TarInfo(%r, %s, %d)" % (self.name, self.type, self.size)
class TarFile:
def __init__(self, name=None, fileobj=None):
if fileobj:
self.f = fileobj
else:
self.f = open(name, "rb")
self.subf = None
def next(self):
if self.subf:
self.subf.skip()
buf = self.f.read(512)
if not buf:
return None
h = uctypes.struct(uctypes.addressof(buf), TAR_HEADER, uctypes.LITTLE_ENDIAN)
# Empty block means end of archive
if h.name[0] == 0:
return None
d = TarInfo()
d.name = str(h.name, "utf-8").rstrip("\0")
d.size = int(bytes(h.size), 8)
d.type = [REGTYPE, DIRTYPE][d.name[-1] == "/"]
self.subf = d.subf = FileSection(self.f, d.size, roundup(d.size, 512))
return d
def __iter__(self):
return self
def __next__(self):
try:
v = self.next()
if v is None:
raise StopIteration
return v
except: pass
def extractfile(self, tarinfo):
return tarinfo.subf
def rmtree(top):
for path, dirs, files in os.walk(top, False):
for f in files:
os.unlink(path + "/" + f)
os.rmdir(path)
def copyfileobj(src, dest, length=512):
if hasattr(src, "readinto"):
buf = bytearray(length)
while True:
sz = src.readinto(buf)
if not sz:
break
if sz == length:
dest.write(buf)
else:
b = memoryview(buf)[:sz]
dest.write(b)
else:
while True:
buf = src.read(length)
if not buf:
break
dest.write(buf)
def copyfile(src, dst, follow_symlinks=True):
assert follow_symlinks
with open(src, "rb") as srcf, open(dst, "wb") as dstf:
copyfileobj(srcf, dstf)
def log(txt):
print(txt)
print('\033[2JWelcome to GearBox, QubicOS installer solution.\n\nQubicOS will be extracted in root and automatic launched.\n( 1/3 ) Please wait analyzing distro.csv...')
f = 'distro.csv'
t = TarFile(f)
total_items = 0
for i in t:
if i == None: break
else: total_items += 1
print("( 2/3 ) Preparing to extraction...")
t = TarFile(f)
print("( 3/3 ) Extraction started")
for idx, i in enumerate(t):
try:
if i == None: break
percent = (idx + 1) / total_items * 100
print(f"( {round(percent)}% ) Extracting: {i.name}")
if i.name in ["main.py", "apps/rdm.py"]: continue
if i.type == DIRTYPE:
os.mkdir(i.name[:-1])
else:
if '/' in i.name:
old = os.getcwd()
for directory in i.name.split('/')[:-1]:
try:
os.mkdir(directory)
except: pass
os.chdir(directory)
os.chdir(old)
f = t.extractfile(i)
copyfileobj(f, open(i.name, "wb"))
except: continue
log(f'Succesfuly installed!')
execfile('/kernel/kernel.py')