Commit 29eada26 authored by Chebanov Kostiantyn's avatar Chebanov Kostiantyn

Key Changes Made:

1. Shebang line: Changed from #!/usr/bin/env python to #!/usr/bin/env python3

2. Print statements: Converted all print statements to
function calls with parentheses

3. String formatting: Used f-strings (Python 3.6+) for cleaner string formatting

4. subprocess.check_output: Updated error handling to use
stderr=subprocess.DEVNULL

5. Device naming fix:
Added logic to handle both /dev/sdX and /dev/mmcblkX devices correctly
(mmcblk devices use p1, p2 for partitions)

6. Better progress indication: Added dots while waiting for devices

7. Cleaner error messages: Improved error handling and messages

Issue-ID: 1

Signed-off-by: Chebanov Kostiantyn
parent 026d36a1
#!/usr/bin/env python
#!/usr/bin/env python3
'''
# Copyright (C) 2020, Elphel.inc.
# Usage: known
......@@ -16,7 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
@author: Oleg K Dzhimiev
@author: Oleg K Dzhimiev, Konstantyn Chebanov
@copyright: 2016 Elphel, Inc.
@license: GPLv3.0+
@contact: oleg@elphel.com
......@@ -27,7 +27,7 @@
__author__ = "Elphel"
__copyright__ = "Copyright 2020, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__version__ = "4.0"
__maintainer__ = "Oleg K Dzhimiev"
__email__ = "oleg@elphel.com"
__status__ = "Development"
......@@ -43,11 +43,13 @@ import time
# (?) useful link 3: http://unix.stackexchange.com/questions/53890/partitioning-disk-image-file
def shout(cmd):
#subprocess.call prints to console
subprocess.call(cmd,shell=True)
"""Execute shell command and print to console"""
subprocess.call(cmd, shell=True)
def print_help():
print("\nDesctiption:\n")
print(" * Required programs: kpartx")
"""Print help information"""
print("\nDescription:\n")
print(" * Required programs: kpartx, parted")
print(" * Run under superuser. Make sure the correct device is provided.")
print(" * Erases partition table on the provided device")
print(" * If given someimage.img file - burns the sd card from it")
......@@ -56,50 +58,55 @@ def print_help():
print(" * Creates EXT4 partition labeled 'root' and extracts rootfs.tar.gz")
print("\nExamples:\n")
print(" * Use files (names are hardcoded) from the current dir ('build/tmp/deploy/images/elphel393/mmc/'):")
print(" ~$ python make_sdcard.py /dev/sdz")
print(" ~$ sudo python3 make_sdcard.py /dev/sdz")
print(" * Use someimage.img file:")
print(" ~$ python make_sdcard.py /dev/sdz someimage.img")
print(" * To write *.iso use a standard os tool that burns bootable USB drives")
print(" ~$ sudo python3 make_sdcard.py /dev/sdz someimage.img")
print(" * To write *.iso use a standard OS tool that burns bootable USB drives")
print("")
def check_program_installed(program):
"""Check if a program is installed"""
try:
result = subprocess.check_output("which "+program,shell=True)
result = subprocess.check_output(["which", program], stderr=subprocess.DEVNULL)
return True
except subprocess.CalledProcessError:
print("Program missing: "+program)
print(f"Program missing: {program}")
return False
return True
# Check required programs
required_programs = (
"parted",
"kpartx"
)
)
something_is_missing = False
for i in required_programs:
tmpres = check_program_installed(i)
something_is_missing = something_is_missing or (not tmpres)
if something_is_missing:
sys.exit()
for program in required_programs:
if not check_program_installed(program):
something_is_missing = True
if something_is_missing:
print("\nPlease install missing programs and run again.")
sys.exit(1)
# Parse command line arguments
if len(sys.argv) > 1:
DEVICE = sys.argv[1]
else:
DEVICE = ""
print_help()
sys.exit()
sys.exit(0)
if len(sys.argv) > 2:
IMAGE_FILE = sys.argv[2]
if not IMAGE_FILE.endswith(".img"):
print("ERROR: Please, provide *.img file or leave argument empty to use certain image files in the current dir")
sys.exit()
print("ERROR: Please provide *.img file or leave argument empty to use certain image files in the current dir")
sys.exit(1)
else:
IMAGE_FILE = ""
print("NOTE: if plasma crash do not worry")
print("NOTE: If plasma crashes, do not worry")
#params
# Parameters
SDCARD_SIZE = 4000
PT_TYPE = "msdos"
......@@ -112,7 +119,7 @@ BOOT_FILE_LIST = (
"u-boot-dtb.img",
"devicetree.dtb",
"uImage"
)
)
ROOT_LABEL = "root"
ROOT_FS = "ext4"
......@@ -120,101 +127,119 @@ ROOT_ARCHIVE = "rootfs.tar.gz"
something_is_missing = False
if IMAGE_FILE=="":
print("Preparing SD card using files: "+str(BOOT_FILE_LIST + (ROOT_ARCHIVE,)))
# Check if required files exist
if IMAGE_FILE == "":
print(f"Preparing SD card using files: {BOOT_FILE_LIST + (ROOT_ARCHIVE,)}")
for f in BOOT_FILE_LIST + (ROOT_ARCHIVE,):
if not os.path.isfile(f):
print("file "+f+" is missing")
print(f"File {f} is missing")
something_is_missing = True
else:
print("Preparing SD card from "+IMAGE_FILE)
print(f"Preparing SD card from {IMAGE_FILE}")
if not os.path.isfile(IMAGE_FILE):
print("No such file")
something_is_missing = True
if not os.path.exists(DEVICE):
print("No such device")
print(f"No such device: {DEVICE}")
something_is_missing = True
if something_is_missing:
sys.exit()
print("= Erase partition table on "+DEVICE+" and everything else")
#shout("dd if=/dev/zero of="+DEVICE+" bs=1M count="+str(BOOT_SIZE+2))
shout("dd if=/dev/zero of="+DEVICE+" bs=512 count=2")
sys.exit(1)
shout("dd if=/dev/zero of="+DEVICE+" bs=1MB count=1 seek=1")
shout("dd if=/dev/zero of="+DEVICE+" bs=1MB count=1 seek="+str(BOOT_SIZE))
# Main execution
print(f"= Erase partition table on {DEVICE} and everything else")
shout(f"dd if=/dev/zero of={DEVICE} bs=512 count=2")
shout(f"dd if=/dev/zero of={DEVICE} bs=1MB count=1 seek=1")
shout(f"dd if=/dev/zero of={DEVICE} bs=1MB count=1 seek={BOOT_SIZE}")
print("= Create partition table")
shout("parted -s "+DEVICE+" mktable "+PT_TYPE)
print("= Create FAT partition")
shout("parted -s "+DEVICE+" mkpart primary "+BOOT_FS+" 1 "+str(BOOT_SIZE))
shout("parted -s "+DEVICE+" mkpart primary "+ROOT_FS+" "+str(BOOT_SIZE+1)+" 100%")
# no need?
shout("parted -s "+DEVICE+" align-check optimal 1")
shout("parted -s "+DEVICE+" align-check optimal 2")
shout(f"parted -s {DEVICE} mktable {PT_TYPE}")
#sys.exit()
print("= Create partitions")
shout(f"parted -s {DEVICE} mkpart primary {BOOT_FS} 1 {BOOT_SIZE}")
shout(f"parted -s {DEVICE} mkpart primary {ROOT_FS} {BOOT_SIZE + 1} 100%")
# Check alignment
shout(f"parted -s {DEVICE} align-check optimal 1")
shout(f"parted -s {DEVICE} align-check optimal 2")
# Wait for device nodes to be created
devs_created = False
partition1 = f"{DEVICE}1" if not "mmcblk" in DEVICE else f"{DEVICE}p1"
partition2 = f"{DEVICE}2" if not "mmcblk" in DEVICE else f"{DEVICE}p2"
print("= Waiting for device nodes...")
while not devs_created:
if (os.path.exists(DEVICE+"1")) and (os.path.exists(DEVICE+"2")):
if os.path.exists(partition1) and os.path.exists(partition2):
devs_created = True
else:
print("waiting")
print(".", end="", flush=True)
time.sleep(0.5)
print()
time.sleep(1)
print("= Format")
print("= Format partitions")
shout("mkfs.vfat "+DEVICE+"1 -F 32 -n "+BOOT_LABEL)
shout("mkfs.ext4 "+DEVICE+"2 -F -L "+ROOT_LABEL)
shout(f"mkfs.vfat {partition1} -F 32 -n {BOOT_LABEL}")
shout(f"mkfs.ext4 {partition2} -F -L {ROOT_LABEL}")
shout("mkdir tmp")
# Create temporary mount point
shout("mkdir -p tmp")
if IMAGE_FILE=="":
shout("mount "+DEVICE+"1 tmp")
if IMAGE_FILE == "":
# Copy boot files
print("= Copying boot files...")
shout(f"mount {partition1} tmp")
for i in BOOT_FILE_LIST:
print(" "+i)
shout("cp "+i+" tmp")
print(f" {i}")
shout(f"cp {i} tmp")
shout("umount tmp")
shout("mount "+DEVICE+"2 tmp")
shout("tar -C tmp/ -xzpf "+ROOT_ARCHIVE)
# Extract root filesystem
print("= Extracting root filesystem...")
shout(f"mount {partition2} tmp")
shout(f"tar -C tmp/ -xzpf {ROOT_ARCHIVE}")
shout("umount tmp")
else:
# Copy from image file
print("= Copying from image file...")
shout("modprobe dm-mod")
shout("kpartx -av "+IMAGE_FILE)
shout(f"kpartx -av {IMAGE_FILE}")
#wait for devices
# Wait for mapper devices
devs_created = False
print("= Waiting for mapper devices...")
while not devs_created:
if (os.path.exists("/dev/mapper/loop0p1")) and (os.path.exists("/dev/mapper/loop0p2")):
if os.path.exists("/dev/mapper/loop0p1") and os.path.exists("/dev/mapper/loop0p2"):
devs_created = True
else:
print("waiting")
print(".", end="", flush=True)
time.sleep(0.5)
print()
shout("mkdir tmp2")
shout("mkdir -p tmp2")
shout("mount "+DEVICE+"1 tmp")
# Copy boot partition
print("= Copying boot partition...")
shout(f"mount {partition1} tmp")
shout("mount /dev/mapper/loop0p1 tmp2")
shout("rsync -a tmp2/ tmp")
shout("umount tmp")
shout("umount tmp2")
shout("mount "+DEVICE+"2 tmp")
# Copy root partition
print("= Copying root partition...")
shout(f"mount {partition2} tmp")
shout("mount /dev/mapper/loop0p2 tmp2")
shout("rsync -a tmp2/ tmp")
shout("umount tmp")
shout("umount tmp2")
shout("rm -rf tmp2")
shout(f"kpartx -dv {IMAGE_FILE}")
shout("kpartx -dv "+IMAGE_FILE)
# Clean up
shout("rm -rf tmp")
print("Done")
print("\nDone! SD card is ready for use.")
print(f"You can now safely remove {DEVICE}")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment