diff --git a/internal/configs/config_vbios_dumper.go b/internal/configs/config_vbios_dumper.go
index afc4260..e8bc92c 100644
--- a/internal/configs/config_vbios_dumper.go
+++ b/internal/configs/config_vbios_dumper.go
@@ -63,7 +63,7 @@ func GenerateVBIOSDumper(vbios_path string) {
 	errorcheck.ErrorCheck(err, "Could not change permissions of \"utils/dump_vbios.sh\"")
 
 	// Write to logger
-	logger.Printf("Writing utils/dump_vbios.sh")
+	logger.Printf("Writing utils/dump_vbios.sh\n")
 
 	// Write the script
 	scriptfile.WriteString(vbios_script)
diff --git a/internal/configs/config_vfio_video.go b/internal/configs/config_vfio_video.go
index a438cba..63230b1 100644
--- a/internal/configs/config_vfio_video.go
+++ b/internal/configs/config_vfio_video.go
@@ -17,7 +17,7 @@ func DisableVFIOVideo(i int) {
 	config := GetConfig()
 
 	// Write to logger
-	logger.Printf("Adding vfio_pci.disable_vga=%v to %s", i, config.Path.CMDLINE)
+	logger.Printf("Adding vfio_pci.disable_vga=%v to %s\n", i, config.Path.CMDLINE)
 
 	// Get the current kernel arguments we have generated
 	kernel_args := fileio.ReadFile(config.Path.CMDLINE)
diff --git a/internal/configs/configs.go b/internal/configs/configs.go
index f2ed38d..0ff868f 100644
--- a/internal/configs/configs.go
+++ b/internal/configs/configs.go
@@ -28,6 +28,8 @@ type Config struct {
 	Bootloader string
 	Cpuvendor  string
 	Path       *Path
+	Gpu_Group  string
+	Gpu_IDs    []string
 }
 
 // Gets the path to all the config files
@@ -52,6 +54,8 @@ func GetConfig() *Config {
 		Bootloader: "unknown",
 		Cpuvendor:  cpuid.CPU.VendorString,
 		Path:       GetConfigPaths(),
+		Gpu_Group:  "",
+		Gpu_IDs:    []string{},
 	}
 
 	// Detect the bootloader we are using
diff --git a/internal/pages/01_welcome.go b/internal/pages/01_welcome.go
index d57d7d2..6bcb8d1 100644
--- a/internal/pages/01_welcome.go
+++ b/internal/pages/01_welcome.go
@@ -39,7 +39,8 @@ func Welcome() {
 	// If yes, go to next page
 	if choice == "y" {
 		configs.InitConfigs()
-		SelectGPU()
+		config := configs.GetConfig()
+		SelectGPU(config)
 	} else {
 		fmt.Println("")
 		os.Exit(0)
diff --git a/internal/pages/02_select_gpu.go b/internal/pages/02_select_gpu.go
index 4a1b8ed..99ca090 100644
--- a/internal/pages/02_select_gpu.go
+++ b/internal/pages/02_select_gpu.go
@@ -4,13 +4,16 @@ import (
 	"fmt"
 	"os"
 
+	"github.com/HikariKnight/ls-iommu/pkg/errorcheck"
+	"github.com/HikariKnight/quickpassthrough/internal/configs"
 	lsiommu "github.com/HikariKnight/quickpassthrough/internal/lsiommu"
 	"github.com/HikariKnight/quickpassthrough/pkg/command"
+	"github.com/HikariKnight/quickpassthrough/pkg/fileio"
 	"github.com/HikariKnight/quickpassthrough/pkg/menu"
 	"github.com/gookit/color"
 )
 
-func SelectGPU() {
+func SelectGPU(config *configs.Config) {
 	// Clear the screen
 	command.Clear()
 
@@ -29,11 +32,12 @@ func SelectGPU() {
 		fmt.Println("")
 		os.Exit(0)
 	default:
-		viewGPU(choice)
+		config.Gpu_Group = choice
+		viewGPU(config)
 	}
 }
 
-func viewGPU(id string, ext ...int) {
+func viewGPU(config *configs.Config, ext ...int) {
 	// Clear the screen
 	command.Clear()
 
@@ -46,10 +50,10 @@ func viewGPU(id string, ext ...int) {
 	}
 
 	// Get the IOMMU listings for GPUs
-	group := lsiommu.GetIOMMU("-g", mode, "-i", id, "-F", "vendor:,prod_name,optional_revision:,device_id")
+	group := lsiommu.GetIOMMU("-g", mode, "-i", config.Gpu_Group, "-F", "vendor:,prod_name,optional_revision:,device_id")
 
 	// Write a title
-	color.Bold.Println("This list should only show devices related to your GPU")
+	color.Bold.Println("This list should only show devices related to your GPU (usually 1 video, 1 audio device)")
 
 	// Print all the gpus
 	for _, v := range group {
@@ -64,7 +68,7 @@ func viewGPU(id string, ext ...int) {
 
 	// Change choices depending on if we have done an extended search or not
 	if len(ext) > 0 {
-		choice = menu.YesNo("Use this GPU (any extra devices listed may or may not be linked to it) for passthrough?")
+		choice = menu.YesNoManual("Use this GPU (any extra devices listed may or may not be linked to it) for passthrough?")
 	} else {
 		choice = menu.YesNoEXT("Use this GPU (and related devices) for passthrough?")
 	}
@@ -78,15 +82,47 @@ func viewGPU(id string, ext ...int) {
 
 	case "ext":
 		// Run an extended relative search
-		viewGPU(id, 1)
+		viewGPU(config, 1)
 
 	case "n":
 		// Go back to selecting a gpu
-		SelectGPU()
+		SelectGPU(config)
 
 	case "y":
-		// Go to the select a usb controller
-		//selectUSB()
-		genVBIOS_dumper(id)
+		// Get the device ids for the selected gpu using ls-iommu
+		config.Gpu_IDs = lsiommu.GetIOMMU("-g", mode, "-i", config.Gpu_Group, "--id")
+
+		// If the kernel_args file already exists
+		if fileio.FileExist(config.Path.CMDLINE) {
+			// Delete it as we will have to make a new one anyway
+			err := os.Remove(config.Path.CMDLINE)
+			errorcheck.ErrorCheck(err, fmt.Sprintf("Could not remove %s", config.Path.CMDLINE))
+		}
+
+		// Write initial kernel_arg file
+		configs.Set_Cmdline(config.Gpu_IDs)
+
+		// Go to the vbios dumper page
+		genVBIOS_dumper(config)
+
+	case "manual":
+		config.Gpu_IDs = menu.ManualInput(
+			"Please manually enter the vendorID:deviceID for every device to use except PCI Express Switches\n"+
+				"NOTE: All devices sharing the same IOMMU group will still get pulled into the VM!",
+			"xxxx:yyyy,xxxx:yyyy,xxxx:yyyy",
+		)
+
+		// If the kernel_args file already exists
+		if fileio.FileExist(config.Path.CMDLINE) {
+			// Delete it as we will have to make a new one anyway
+			err := os.Remove(config.Path.CMDLINE)
+			errorcheck.ErrorCheck(err, fmt.Sprintf("Could not remove %s", config.Path.CMDLINE))
+		}
+
+		// Write initial kernel_arg file
+		configs.Set_Cmdline(config.Gpu_IDs)
+
+		// Go to the vbios dumper page
+		genVBIOS_dumper(config)
 	}
 }
diff --git a/internal/pages/03_vbios_extract.go b/internal/pages/03_vbios_extract.go
index 0e5a3ba..76c653a 100644
--- a/internal/pages/03_vbios_extract.go
+++ b/internal/pages/03_vbios_extract.go
@@ -6,11 +6,13 @@ import (
 	"path/filepath"
 	"strings"
 
+	"github.com/HikariKnight/quickpassthrough/internal/configs"
+	lsiommu "github.com/HikariKnight/quickpassthrough/internal/lsiommu"
 	"github.com/HikariKnight/quickpassthrough/pkg/command"
 	"github.com/HikariKnight/quickpassthrough/pkg/menu"
 )
 
-func genVBIOS_dumper(id string) {
+func genVBIOS_dumper(config *configs.Config) {
 	// Clear the scren
 	command.Clear()
 
@@ -23,8 +25,9 @@ func genVBIOS_dumper(id string) {
 		scriptdir, _ = os.Getwd()
 	}
 
-	// Get the vbios path
-	//vbios_path := lsiommu.GetIOMMU("-g", "-i", id, "--rom")[0]
+	// Get the vbios path and generate the vbios dumping script
+	vbios_path := lsiommu.GetIOMMU("-g", "-i", config.Gpu_Group, "--rom")[0]
+	configs.GenerateVBIOSDumper(vbios_path)
 
 	// Tell users about the VBIOS dumper script
 	fmt.Print(
@@ -38,13 +41,17 @@ func genVBIOS_dumper(id string) {
 	)
 
 	// Get the OK press
-	choice := menu.Ok("Make sure you run the script with the display-manager stopped using ssh or tty!")
+	choice := menu.OkBack("Make sure you run the script with the display-manager stopped using ssh or tty!")
 
-	// If OK is pressed
-	if choice == "next" {
-		disableVideo()
-		selectUSB()
-	} else {
+	// Parse choice
+	switch choice {
+	case "next":
+		disableVideo(config)
+
+	case "back":
+		SelectGPU(config)
+
+	case "":
 		fmt.Println("")
 		os.Exit(0)
 	}
diff --git a/internal/pages/04_disable_video.go b/internal/pages/04_disable_video.go
index 23ae8fe..36aba95 100644
--- a/internal/pages/04_disable_video.go
+++ b/internal/pages/04_disable_video.go
@@ -2,13 +2,14 @@ package pages
 
 import (
 	"fmt"
+	"os"
 
 	"github.com/HikariKnight/quickpassthrough/internal/configs"
 	"github.com/HikariKnight/quickpassthrough/pkg/command"
 	"github.com/HikariKnight/quickpassthrough/pkg/menu"
 )
 
-func disableVideo() {
+func disableVideo(config *configs.Config) {
 	// Clear the screen
 	command.Clear()
 
@@ -22,14 +23,25 @@ func disableVideo() {
 	)
 
 	// Make the yesno menu
-	choice := menu.YesNo("Do you want to force disable video output in linux on this card?")
+	choice := menu.YesNoBack("Do you want to force disable video output in linux on this card?")
 
-	if choice == "Yes" {
+	switch choice {
+	case "y":
 		// Add disable VFIO video to the config
 		configs.DisableVFIOVideo(1)
-	} else {
+		selectUSB(config)
+
+	case "n":
 		// Do not disable VFIO Video
 		configs.DisableVFIOVideo(0)
-	}
+		selectUSB(config)
 
+	case "back":
+		genVBIOS_dumper(config)
+
+	case "":
+		// If ESC is pressed
+		fmt.Println("")
+		os.Exit(0)
+	}
 }
diff --git a/internal/pages/05_select_usbctrl.go b/internal/pages/05_select_usbctrl.go
index 01995ea..bc9a004 100644
--- a/internal/pages/05_select_usbctrl.go
+++ b/internal/pages/05_select_usbctrl.go
@@ -4,13 +4,14 @@ import (
 	"fmt"
 	"os"
 
+	"github.com/HikariKnight/quickpassthrough/internal/configs"
 	lsiommu "github.com/HikariKnight/quickpassthrough/internal/lsiommu"
 	"github.com/HikariKnight/quickpassthrough/pkg/command"
 	"github.com/HikariKnight/quickpassthrough/pkg/menu"
 	"github.com/gookit/color"
 )
 
-func selectUSB() {
+func selectUSB(config *configs.Config) {
 	// Clear the screen
 	command.Clear()
 
@@ -23,18 +24,20 @@ func selectUSB() {
 	// Parse the choice
 	switch choice {
 	case "back":
-		SelectGPU()
+		disableVideo(config)
+
 	case "":
 		// If ESC is pressed
 		fmt.Println("")
 		os.Exit(0)
+
 	default:
 		// View the selected GPU
-		viewUSB(choice)
+		viewUSB(choice, config)
 	}
 }
 
-func viewUSB(id string, ext ...int) {
+func viewUSB(id string, config *configs.Config, ext ...int) {
 	// Clear the screen
 	command.Clear()
 
@@ -76,9 +79,10 @@ func viewUSB(id string, ext ...int) {
 		// If ESC is pressed
 		fmt.Println("")
 		os.Exit(0)
+
 	case "n":
 		// Go back to selecting a gpu
-		selectUSB()
+		selectUSB(config)
 
 	case "y":
 		// Go to the select a usb controller
diff --git a/internal/pages/06_finalize.go b/internal/pages/06_finalize.go
new file mode 100644
index 0000000..7389da0
--- /dev/null
+++ b/internal/pages/06_finalize.go
@@ -0,0 +1,5 @@
+package pages
+
+func finalize() {
+
+}
diff --git a/pkg/menu/manual.go b/pkg/menu/manual.go
new file mode 100644
index 0000000..5e0b06c
--- /dev/null
+++ b/pkg/menu/manual.go
@@ -0,0 +1,27 @@
+package menu
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/HikariKnight/ls-iommu/pkg/errorcheck"
+	"github.com/gookit/color"
+)
+
+func ManualInput(msg string, format string) []string {
+	// Print the title
+	color.Bold.Println(msg)
+
+	// Tell user the format to use
+	color.Bold.Printf("The format is %s\n", format)
+
+	// Get the user input
+	var input string
+	_, err := fmt.Scan(&input)
+	errorcheck.ErrorCheck(err)
+
+	input_list := strings.Split(input, ",")
+
+	// Return the input
+	return input_list
+}
diff --git a/pkg/menu/yesno.go b/pkg/menu/yesno.go
index 03008ce..292bbe8 100644
--- a/pkg/menu/yesno.go
+++ b/pkg/menu/yesno.go
@@ -16,6 +16,20 @@ func YesNo(msg string) string {
 	return choice
 }
 
+func YesNoBack(msg string) string {
+	// Make the menu
+	menu := gocliselect.NewMenu(msg)
+	menu.AddItem("Yes", "y")
+	menu.AddItem("No", "n")
+	menu.AddItem("Go Back", "back")
+
+	// Display the menu
+	choice := menu.Display()
+
+	// Return the value selected
+	return choice
+}
+
 func YesNoEXT(msg string) string {
 	// Make the menu
 	menu := gocliselect.NewMenu(msg)
@@ -29,3 +43,18 @@ func YesNoEXT(msg string) string {
 	// Return the value selected
 	return choice
 }
+
+// Make a YesNo menu
+func YesNoManual(msg string) string {
+	// Make the menu
+	menu := gocliselect.NewMenu(msg)
+	menu.AddItem("Yes", "y")
+	menu.AddItem("No", "n")
+	menu.AddItem("Manual Entry", "manual")
+
+	// Display the menu
+	choice := menu.Display()
+
+	// Return the value selected
+	return choice
+}