Hacking Ubuntu 18.04 on a Switch

  • Thread starter Thread starter cmsj
  • Start date Start date
  • Views Views 96,423
  • Replies Replies 192
  • Likes Likes 54
It's common in other areas (raspberry pi etc) to supply ready to use SD images as .img files. You can make a small one (2GB/4GB) that contains all important partitions. After that the user can expand the root partition on the switch itself to match the actual SD size, in case of the raspberry pi raspi-config has an option to do that.

Yep, that's something I'd like to get working too. Lots to be done, not so much free time ;)
 
So I rebooted it then redid the exploit but i still don't have WiFi....any tips?

Edit: Also does terminal not work?
 
Last edited by Orthopox1,
Yep, that's something I'd like to get working too. Lots to be done, not so much free time ;)

I could do it, using your bionic.tgz release, and contribute the img file. I can make an img every time you make a new release on Github.
 
I could do it, using your bionic.tgz release, and contribute the img file. I can make an img every time you make a new release on Github.

That sounds like a very painful process - it would be much better if we integrate image building into the script so it can happen automatically every time.
Making a disk image shouldn't be too hard, but I haven't picked apart a Pi image to see how they do the auto-resizing on first boot. That would be the most valuable thing to know, I think.

If you fancy working up the list of things that need to be done, I can integrate it into the build script, or we can work together to do that. Up to you :)
 
That sounds like a very painful process - it would be much better if we integrate image building into the script so it can happen automatically every time.
Making a disk image shouldn't be too hard, but I haven't picked apart a Pi image to see how they do the auto-resizing on first boot. That would be the most valuable thing to know, I think.

If you fancy working up the list of things that need to be done, I can integrate it into the build script, or we can work together to do that. Up to you :)

I'd say this script could be of use.

Code:
#!/bin/bash

function cleanup() {
  if losetup $loopback &>/dev/null; then
	losetup -d "$loopback"
  fi
}

usage() { echo "Usage: $0 [-s] imagefile.img [newimagefile.img]"; exit -1; }

should_skip_autoexpand=false

while getopts ":s" opt; do
  case "${opt}" in
    s) should_skip_autoexpand=true ;;
    *) usage ;;
  esac
done
shift $((OPTIND-1))

#Args
img="$1"

#Usage checks
if [[ -z "$img" ]]; then
  usage
fi
if [[ ! -f "$img" ]]; then
  echo "ERROR: $img is not a file..."
  exit -2
fi
if (( EUID != 0 )); then
  echo "ERROR: You need to be running as root."
  exit -3
fi

#Check that what we need is installed
for command in parted losetup tune2fs md5sum e2fsck resize2fs; do
  which $command 2>&1 >/dev/null
  if (( $? != 0 )); then
    echo "ERROR: $command is not installed."
    exit -4
  fi
done

#Copy to new file if requested
if [ -n "$2" ]; then
  echo "Copying $1 to $2..."
  cp --reflink=auto --sparse=always "$1" "$2"
  if (( $? != 0 )); then
    echo "ERROR: Could not copy file..."
    exit -5
  fi
  old_owner=$(stat -c %u:%g "$1")
  chown $old_owner "$2"
  img="$2"
fi

# cleanup at script exit
trap cleanup ERR EXIT

#Gather info
beforesize=$(ls -lh "$img" | cut -d ' ' -f 5)
parted_output=$(parted -ms "$img" unit B print | tail -n 1)
partnum=$(echo "$parted_output" | cut -d ':' -f 1)
partstart=$(echo "$parted_output" | cut -d ':' -f 2 | tr -d 'B')
loopback=$(losetup -f --show -o $partstart "$img")
tune2fs_output=$(tune2fs -l "$loopback")
currentsize=$(echo "$tune2fs_output" | grep '^Block count:' | tr -d ' ' | cut -d ':' -f 2)
blocksize=$(echo "$tune2fs_output" | grep '^Block size:' | tr -d ' ' | cut -d ':' -f 2)

#Check if we should make pi expand rootfs on next boot
if [ "$should_skip_autoexpand" = false ]; then
  #Make pi expand rootfs on next boot
  mountdir=$(mktemp -d)
  mount "$loopback" "$mountdir"

  if [ $(md5sum "$mountdir/etc/rc.local" | cut -d ' ' -f 1) != "0542054e9ff2d2e0507ea1ffe7d4fc87" ]; then
    echo "Creating new /etc/rc.local"
    mv "$mountdir/etc/rc.local" "$mountdir/etc/rc.local.bak"
    #####Do not touch the following lines#####
cat <<\EOF1 > "$mountdir/etc/rc.local"
#!/bin/bash
do_expand_rootfs() {
  ROOT_PART=$(mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p')
  PART_NUM=${ROOT_PART#mmcblk0p}
  if [ "$PART_NUM" = "$ROOT_PART" ]; then
    echo "$ROOT_PART is not an SD card. Don't know how to expand"
    return 0
  fi
  # Get the starting offset of the root partition
  PART_START=$(parted /dev/mmcblk0 -ms unit s p | grep "^${PART_NUM}" | cut -f 2 -d: | sed 's/[^0-9]//g')
  [ "$PART_START" ] || return 1
  # Return value will likely be error for fdisk as it fails to reload the
  # partition table because the root fs is mounted
  fdisk /dev/mmcblk0 <<EOF
p
d
$PART_NUM
n
p
$PART_NUM
$PART_START
p
w
EOF
cat <<EOF > /etc/rc.local &&
#!/bin/sh
echo "Expanding /dev/$ROOT_PART"
resize2fs /dev/$ROOT_PART
rm -f /etc/rc.local; cp -f /etc/rc.local.bak /etc/rc.local; /etc/rc.local
EOF
reboot
exit
}
raspi_config_expand() {
/usr/bin/env raspi-config --expand-rootfs
if [[ $? != 0 ]]; then
  return -1
else
  rm -f /etc/rc.local; cp -f /etc/rc.local.bak /etc/rc.local; /etc/rc.local
  reboot
  exit
fi
}
raspi_config_expand
echo "WARNING: Using backup expand..."
sleep 5
do_expand_rootfs
echo "ERROR: Expanding failed..."
sleep 5
rm -f /etc/rc.local; cp -f /etc/rc.local.bak /etc/rc.local; /etc/rc.local
exit 0
EOF1
    #####End no touch zone#####
    chmod +x "$mountdir/etc/rc.local"
  fi
  umount "$mountdir"
else
  echo "Skipping autoexpanding process..."
fi

#Make sure filesystem is ok
e2fsck -p -f "$loopback"
minsize=$(resize2fs -P "$loopback" | cut -d ':' -f 2 | tr -d ' ')
if [[ $currentsize -eq $minsize ]]; then
  echo "ERROR: Image already shrunk to smallest size"
  exit -6
fi

#Add some free space to the end of the filesystem
extra_space=$(($currentsize - $minsize))
for space in 5000 1000 100; do
  if [[ $extra_space -gt $space ]]; then
    minsize=$(($minsize + $space))
    break
  fi
done

#Shrink filesystem
resize2fs -p "$loopback" $minsize
if [[ $? != 0 ]]; then
  echo "ERROR: resize2fs failed..."
  mount "$loopback" "$mountdir"
  mv "$mountdir/etc/rc.local.bak" "$mountdir/etc/rc.local"
  umount "$mountdir"
  losetup -d "$loopback"
  exit -7
fi
sleep 1

#Shrink partition
partnewsize=$(($minsize * $blocksize))
newpartend=$(($partstart + $partnewsize))
parted -s -a minimal "$img" rm $partnum >/dev/null
parted -s "$img" unit B mkpart primary $partstart $newpartend >/dev/null

#Truncate the file
endresult=$(parted -ms "$img" unit B print free | tail -1 | cut -d ':' -f 2 | tr -d 'B')
truncate -s $endresult "$img"
aftersize=$(ls -lh "$img" | cut -d ' ' -f 5)

echo "Shrunk $img from $beforesize to $aftersize"
 
  • Like
Reactions: Centergaming
Should have done this a lot sooner, but I've updated the first post to contain more information and a download link for a pre-built image.

@Baoulettes and anyone else that's running this - any interest in helping me fix things up and generally reducing the friction of getting this going? I'd like to get to a point where people download a single tarball with the f0f stuff and the Ubuntu rootfs all pre-built and easy to run, as well as to a point where building all the things from scratch is super easy. And obviously also getting any improvements to hardware support as they are possible :)

File issues and pull requests on github :D
thanks for all your work, but can you make the OP *noob proof? Like... what does "small fat32 partition" mean? 4MB? 100MB? I just plugged in a new 32GB microSD card into an Ubuntu VM, but I'm not quite sure how to partition it. Something I could simply copy and paste from here would be extremely useful.
 
thanks for all your work, but can you make the OP *noob proof? Like... what does "small fat32 partition" mean? 4MB? 100MB? I just plugged in a new 32GB microSD card into an Ubuntu VM, but I'm not quite sure how to partition it. Something I could simply copy and paste from here would be extremely useful.

what.... you.... dont know?...... Use an application called Gparted in Ubuntu to partition the sd card

Edit: Always read the first post..... Google is your friend..... This is not a guide for end-users anyway, must be patient.......
 
Last edited by Centergaming,
what.... you.... dont know?...... Use an application called Gparted in Ubuntu to partition the sd card

Edit: Always read the first post..... Google is your friend..... This is not a guide for end-users anyway, must be patient.......
I know HOW to make partitions. I don't know what SIZE it's meant to be. I've spent most of my life in the military, so I'm a stickler for following directions. I don't break my things that way, so it works out for the best. The number of people who post here just because they bricked a 3DS (or think they did, considering hard mods and b9s) is astonishing... and this Linux stuff can seriously damage hardware, and already has while being developed. I want to get it right the first time.
 
Last edited by urherenow,
  • Like
Reactions: Centergaming
I know HOW to make partitions. I don't know what SIZE it's meant to be. I've spent most of my life in the military, so I'm a stickler for following directions. I don't break my things that way, so it works out for the best...
here my setup :
SD card 64gb

Partition 0 - Fat32 (readable by both Switch and Linux and Switch will use that partition to install stuff)
55gb

Partition 1 - ext4 (that will hold our linux system and not seen by switch.)
8gb (approx but in short that the rest of available space on my sd.)

This way when I boot to linux I have quite huge space shared by switch and personal data.
While having my ubuntu partition as 1.
I made it a bit much more larger than needed but that in case I install package :)
If you plan to use with ton of package a good 15/20gb for partition 1 should be enough to start with :)

Do you need more details or you're fine :)?

can somebody upload me the ubuntu .bin or img

i cant use it on mac as tgz
I have no idea how to make proper one but couldn't you just vmware player + free image of ubuntu to make that for you ?
(That what I do on windows)
 
Last edited by Baoulettes,
here my setup :
SD card 64gb

Partition 0 - Ntfs (readable by both Switch and Linux and Switch will use that partition to install stuff)
55gb

Partition 1 - ext4 (that will hold our linux system and not seen by switch.)
8gb (approx but in short that the rest of available space on my sd.)

This way when I boot to linux I have quite huge space shared by switch and personal data.
While having my ubuntu partition as 1.
I made it a bit much more larger than needed but that in case I install package :)
If you plan to use with ton of package a good 15/20gb for partition 1 should be enough to start with :)

Do you need more details or you're fine :)?


I have no idea how to make proper one but couldn't you just vmware player + free image of ubuntu to make that for you ?
(That what I do on windows)

NTFS ? it needs to be fat32
 
NTFS ? it needs to be fat32
it is readable that way Oo
I never checked how and why just as it work I just trimmed it to add that linux partition ^^'
Maybe that a fat32 and never noticed let me check !

Edit:True I had wrong sorry I will edit that post above that is Fat32
 
Last edited by Baoulettes,
here my setup :
SD card 64gb

Partition 0 - Ntfs (readable by both Switch and Linux and Switch will use that partition to install stuff)
55gb

Partition 1 - ext4 (that will hold our linux system and not seen by switch.)
8gb (approx but in short that the rest of available space on my sd.)

This way when I boot to linux I have quite huge space shared by switch and personal data.
While having my ubuntu partition as 1.
I made it a bit much more larger than needed but that in case I install package :)
If you plan to use with ton of package a good 15/20gb for partition 1 should be enough to start with :)

Do you need more details or you're fine :)?
I never thought to use the same card for both Linux and the switch. I was considering switching cards, so what exactly is the fat32 partition for? I don't need partition 0 to be any bigger than it needs to be.

And... NTFS? that's rather odd. Doesn't seem like something required at all by Linux then. Most 64GB cards are exFat.

EDIT: :ninja:
 
I never thought to use the same card for both Linux and the switch. I was considering switching cards, so what exactly is the fat32 partition for? I don't need partition 0 to be any bigger than it needs to be.

And... NTFS? that's rather odd. Doesn't seem like something required at all by Linux then. Most 64GB cards are exFat.


Linux seem to read fine that type of partition.
Also I just own one SD that is why I use that kind of ''trick''
and Switch since read partition 0 and linux partition 1 that quite userful ^^
 
Well, I got both my answer and the WHY as well by not being lazy and following links in the OP that I skipped over before. Basically, nothing is needed to be in the fat32 partition at all; the Switch exploit/loader just happens to look for Linux in the second partition (so there needs to be 2). Someone feel free to correct me if I misunderstood...
  • remove every existing partition to only have unallocated space on it (do I need to tell you that you're going to loose everything on the card ?)
  • create a tiny FAT32 partition (I chose 200mb but it doesn't matter) - that'll be mmcbkl0p1, you can label it "garbage"
  • create an ext4 partition on the remaining part of the card - that'll be mmcblk0p2, you can label it "rootfs"
  • it's important that the FAT32 partition comes first and the ext4 one comes after - on the Switch, Linux will look for mmcblk0p2, the second partition, if you have scrolling boot logs and then back to RCM it means you did it wrong
 
Last edited by urherenow,
locales are missing so impossible to launch terminal, i suggest you to install MATE Terminal then do this command :
sudo dpkg-reconfigure locales
search for en-US.UTF-8 (or you locale) press spacebar to get a [*]
select just installed local then press enter.
then reboot
 
Last edited by GGLinnk,

Site & Scene News

Popular threads in this forum