diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index e1c15fe..732f296 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -727,7 +727,7 @@ function drupal_settings_initialize() {
   global $base_url, $base_path, $base_root, $script_path;
 
   // Export these settings.php variables to the global namespace.
-  global $databases, $cookie_domain, $conf, $installed_profile, $db_prefix, $drupal_hash_salt, $is_https, $base_secure_url, $base_insecure_url, $config_directories;
+  global $cookie_domain, $conf, $installed_profile, $drupal_hash_salt, $is_https, $base_secure_url, $base_insecure_url, $config_directories;
   $conf = array();
 
   // Make conf_path() available as local variable in settings.php.
@@ -735,6 +735,11 @@ function drupal_settings_initialize() {
   if (is_readable(DRUPAL_ROOT . '/' . $conf_path . '/settings.php')) {
     include_once DRUPAL_ROOT . '/' . $conf_path . '/settings.php';
   }
+  // In order to migrate Drupal 7's database settings we need to store them for
+  // later use in the Settings singleton.
+  if (isset($databases)) {
+    $settings['d7databases'] = $databases;
+  }
   require_once DRUPAL_ROOT . '/core/lib/Drupal/Component/Utility/Settings.php';
   new Settings(isset($settings) ? $settings : array());
   $is_https = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on';
@@ -2302,9 +2307,15 @@ function _drupal_bootstrap_configuration() {
   // Redirect the user to the installation script if Drupal has not been
   // installed yet (i.e., if no $databases array has been defined in the
   // settings.php file) and we are not already installing.
-  if (empty($GLOBALS['databases']) && !drupal_installation_attempted()) {
-    include_once DRUPAL_ROOT . '/core/includes/install.inc';
-    install_goto('core/install.php');
+  $databases = settings()->get('databases');
+  if (empty($databases) && !drupal_installation_attempted()) {
+    // If the database connection is defined in the Drupal 7 format in settings
+    // then need to a major update not install.
+    $d7databases = settings()->get('d7databases');
+    if (empty($d7databases)) {
+      include_once DRUPAL_ROOT . '/core/includes/install.inc';
+      install_goto('core/install.php');
+    }
   }
 }
 
@@ -2379,7 +2390,8 @@ function _drupal_initialize_db_test_prefix() {
     $test_info['test_run_id'] = $test_prefix;
     $test_info['in_child_site'] = TRUE;
 
-    foreach ($GLOBALS['databases']['default'] as &$value) {
+    $settings = settings()->getAll();
+    foreach ($settings['databases']['default'] as &$value) {
       // Extract the current default database prefix.
       if (!isset($value['prefix'])) {
         $current_prefix = '';
@@ -2396,6 +2408,7 @@ function _drupal_initialize_db_test_prefix() {
         'default' => $current_prefix . $test_prefix,
       );
     }
+    new Settings($settings);
   }
 }
 
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 86fc44a..9707db7 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -4803,7 +4803,8 @@ function drupal_json_decode($var) {
  *   A salt based on information in settings.php, not in the database.
  */
 function drupal_get_hash_salt() {
-  global $drupal_hash_salt, $databases;
+  global $drupal_hash_salt;
+  $databases = settings()->get('databases');
   // If the $drupal_hash_salt variable is empty, a hash of the serialized
   // database credentials is used as a fallback salt.
   return empty($drupal_hash_salt) ? hash('sha256', serialize($databases)) : $drupal_hash_salt;
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index bb8f247..9c6574c 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1,5 +1,6 @@
 <?php
 
+use Drupal\Component\Utility\Settings;
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\CoreBundle;
 use Drupal\Core\Database\Database;
@@ -427,7 +428,8 @@ function install_begin_request(&$install_state) {
     $task = NULL;
 
     // Do not install over a configured settings.php.
-    if (!empty($GLOBALS['databases'])) {
+    $databases = settings()->get('databases');
+    if (!empty($databases)) {
       throw new Exception(install_already_done_error());
     }
   }
@@ -959,7 +961,7 @@ function install_verify_completed_task() {
  * Verifies that settings.php specifies a valid database connection.
  */
 function install_verify_database_settings() {
-  global $databases;
+  $databases = settings()->get('databases');
   if (!empty($databases)) {
     $database = $databases['default']['default'];
     drupal_static_reset('conf_path');
@@ -983,7 +985,7 @@ function install_verify_database_settings() {
  * @ingroup forms
  */
 function install_settings_form($form, &$form_state, &$install_state) {
-  global $databases;
+  $databases = settings()->get('databases');
   $profile = $install_state['parameters']['profile'];
 
   drupal_static_reset('conf_path');
@@ -1072,7 +1074,6 @@ function install_settings_form_validate($form, &$form_state) {
  * Checks a database connection and returns any errors.
  */
 function install_database_errors($database, $settings_file) {
-  global $databases;
   $errors = array();
 
   // Check database type.
@@ -1087,7 +1088,9 @@ function install_database_errors($database, $settings_file) {
 
     // Run tasks associated with the database type. Any errors are caught in the
     // calling function.
-    $databases['default']['default'] = $database;
+    $settings = settings()->getAll();
+    $settings['databases']['default']['default'] = $database;;
+    new Settings($settings);
     // Just changing the global doesn't get the new information processed.
     // We need to close any active connections and tell the Database class to
     // re-parse $databases.
@@ -1118,7 +1121,7 @@ function install_settings_form_submit($form, &$form_state) {
   global $install_state;
 
   // Update global settings array and save.
-  $settings['databases'] = (object) array(
+  $settings['settings']['databases'] = (object) array(
     'value'    => array('default' => array('default' => $form_state['storage']['database'])),
     'required' => TRUE,
   );
diff --git a/core/includes/install.inc b/core/includes/install.inc
index 4fc640f..829d48a 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -307,7 +307,8 @@ function drupal_rewrite_settings($settings = array(), $settings_file = NULL) {
     }
 
     // Write the new settings file.
-    if (file_put_contents(DRUPAL_ROOT . '/' . $settings_file, $buffer) === FALSE) {
+    $status = @file_put_contents(DRUPAL_ROOT . '/' . $settings_file, $buffer);
+    if ($status === FALSE) {
       throw new Exception(st('Failed to modify %settings. Verify the file permissions.', array('%settings' => $settings_file)));
     }
   }
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 6aea70f..ac26c8e 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -92,52 +92,56 @@ function update_check_incompatibility($name, $type = 'module') {
 function update_prepare_d8_bootstrap() {
   include_once DRUPAL_ROOT . '/core/includes/install.inc';
   include_once DRUPAL_ROOT . '/core/includes/schema.inc';
+
   // Bootstrap to configuration.
   drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
 
+  // Use special error handlers because at this point we can not be sure if:
+  //   - Settings.php is writable.
+  //   - Configuration directories exist.
+  set_exception_handler('_update_low_level_exception_handler');
+  set_error_handler('_update_low_level_error_handler');
+
+  $settings = settings()->getAll();
+
+  $d7databases = settings()->get('d7databases');
+  $databases = settings()->get('databases');
+  // If we have Drupal 7 database settings an no Drupal 8 settings then convert
+  // and use the Drupal 7 settings.
+  if (!empty($d7databases) && empty($databases)) {
+    $db_settings['settings']['databases'] = (object) array(
+      'value'    => $d7databases,
+      'required' => TRUE,
+    );
+    drupal_rewrite_settings($db_settings);
+
+    // Make it possible for this request to connect to the database.
+    $settings['databases'] = $d7databases;
+  }
+
   // During the bootstrap to DRUPAL_BOOTSTRAP_PAGE_CACHE, code will try to read
   // the cache but the cache tables are not compatible yet. Use the Null backend
   // by default to avoid exceptions.
-  $settings = settings()->getAll();
   $settings['cache']['default'] = 'cache.backend.memory';
   new Settings($settings);
 
   // Enable UpdateBundle service overrides.
   $GLOBALS['conf']['container_bundles'][] = 'Drupal\Core\DependencyInjection\UpdateBundle';
 
-  // Check whether settings.php needs to be rewritten.
-  $settings_exist = !empty($GLOBALS['config_directories']);
-
-  if (!$settings_exist || !is_dir(config_get_config_directory('active')) || !is_dir(config_get_config_directory('staging'))) {
+  // Ensure config directories are in settings.php and exist.
+  if (!empty($GLOBALS['config_directories']) || !is_dir(config_get_config_directory('active')) || !is_dir(config_get_config_directory('staging'))) {
     drupal_install_config_directories();
   }
 
+  // Restore the previous error handlers.
+  restore_error_handler();
+  restore_exception_handler();
+
   // Bootstrap the kernel.
   // Do not attempt to dump and write it.
   $kernel = new DrupalKernel('update', FALSE, drupal_classloader(), FALSE);
   $kernel->boot();
 
-  // If any of the required settings needs to be written, then settings.php
-  // needs to be writable.
-  if (!$settings_exist) {
-    $settings_file = conf_path() . '/settings.php';
-    $writable = drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_WRITABLE);
-    $requirements['settings file']['title'] = 'Settings file';
-    if ($writable) {
-      $requirements['settings file'] += array(
-        'value' => 'settings.php is writable.',
-      );
-    }
-    else {
-      $requirements['settings file'] += array(
-        'value' => 'settings.php is not writable.',
-        'severity' => REQUIREMENT_ERROR,
-        'description' => 'Drupal requires write permissions to <em>' . $settings_file . '</em> during the update process. If you are unsure how to grant file permissions, consult the <a href="http://drupal.org/server-permissions">online handbook</a>.',
-      );
-    }
-    update_extra_requirements($requirements);
-  }
-
   // Bootstrap the database.
   drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
 
@@ -1564,3 +1568,35 @@ function update_add_cache_columns($table) {
     ));
   }
 }
+
+/**
+ * Provides custom PHP error handling for very early Drupal 7 to Drupal 8.
+ *
+ * @param $error_level
+ *   The level of the error raised.
+ * @param $message
+ *   The error message.
+ * @param $filename
+ *   The filename that the error was raised in.
+ * @param $line
+ *   The line number the error was raised at.
+ * @param $context
+ *   An array that points to the active symbol table at the point the error
+ *   occurred.
+ */
+function _update_low_level_error_handler($error_level, $message, $filename, $line, $context) {
+  if ($error_level & error_reporting()) {
+    $e = new ErrorException($message, $error_level, 0, $filename, $line);
+    _update_low_level_exception_handler($e);
+  }
+}
+
+/**
+ * Provides custom PHP exception handling for very early Drupal 7 to Drupal 8.
+ *
+ * @param $exception
+ *   The exception object that was thrown.
+ */
+function _update_low_level_exception_handler(Exception $exception) {
+  exit('A problem has occurred: ' . $exception);
+}
diff --git a/core/lib/Drupal/Core/Database/Database.php b/core/lib/Drupal/Core/Database/Database.php
index a54c9cb..63f0044 100644
--- a/core/lib/Drupal/Core/Database/Database.php
+++ b/core/lib/Drupal/Core/Database/Database.php
@@ -209,7 +209,7 @@
    * Process the configuration file for database information.
    */
   final public static function parseConnectionInfo() {
-    global $databases;
+    $databases = settings()->get('databases');
 
     $database_info = is_array($databases) ? $databases : array();
     foreach ($database_info as $index => $info) {
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index 35af531..6c10ecc 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -812,14 +812,14 @@ protected function changeDatabasePrefix() {
     }
     Database::addConnectionInfo('default', 'default', $connection_info['default']);
 
-    // Additionally override global $databases, since the installer does not use
-    // the Database connection info.
+    // Additionally override the databases in the Settings singleton, since the
+    // installer does not use the Database connection info.
     // @see install_verify_database_settings()
     // @see install_database_errors()
     // @todo Fix installer to use Database connection info.
-    global $databases;
-    $databases['default']['default'] = $connection_info['default'];
-
+    $settings = settings()->getAll();
+    $settings['databases']['default']['default'] = $connection_info['default'];
+    new Settings($settings);
     // Indicate the database prefix was set up correctly.
     $this->setupDatabasePrefix = TRUE;
   }
@@ -1026,9 +1026,10 @@ protected function tearDown() {
     Database::removeConnection('default');
     Database::renameConnection('simpletest_original_default', 'default');
     // @see TestBase::changeDatabasePrefix()
-    global $databases;
+    $settings = settings()->getAll();
     $connection_info = Database::getConnectionInfo('default');
-    $databases['default']['default'] = $connection_info['default'];
+    $settings['databases']['default']['default'] = $connection_info['default'];
+    new Settings($settings);
 
     // Restore original globals.
     if (isset($this->originalThemeKey)) {
diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/ConnectionUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/ConnectionUnitTest.php
index 3bba870..1a673bc 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Database/ConnectionUnitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Database/ConnectionUnitTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\system\Tests\Database;
 
+use Drupal\Component\Utility\Settings;
 use Drupal\Core\Database\Database;
 use Drupal\simpletest\UnitTestBase;
 
@@ -52,8 +53,9 @@ function setUp() {
     // and closed in this test.
     // @see TestBase::changeDatabasePrefix()
     Database::addConnectionInfo('default', 'monitor', $connection_info['default']);
-    global $databases;
-    $databases['default']['monitor'] = $connection_info['default'];
+    $settings = settings()->getAll();
+    $settings['databases']['default']['monitor'] = $connection_info['default'];
+    new Settings($settings);
     $this->monitor = Database::getConnection('monitor');
   }
 
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 7fcda31..b059384 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -55,7 +55,7 @@
 /**
  * Database settings:
  *
- * The $databases array specifies the database connection or
+ * The $settings['databases'] array specifies the database connection or
  * connections that Drupal may use.  Drupal is able to connect
  * to multiple databases, including multiple types of databases,
  * during the same request.
@@ -98,12 +98,12 @@
  * to a slave server when appropriate and if one is not available will simply
  * fall back to the single master server.
  *
- * The general format for the $databases array is as follows:
+ * The general format for the $settings['databases'] array is as follows:
  * @code
- * $databases['default']['default'] = $info_array;
- * $databases['default']['slave'][] = $info_array;
- * $databases['default']['slave'][] = $info_array;
- * $databases['extra']['default'] = $info_array;
+ * $settings['databases']['default']['default'] = $info_array;
+ * $settings['databases']['default']['slave'][] = $info_array;
+ * $settings['databases']['default']['slave'][] = $info_array;
+ * $settings['databases']['extra']['default'] = $info_array;
  * @endcode
  *
  * In the above example, $info_array is an array of settings described above.
@@ -115,7 +115,7 @@
  *
  * For a single database configuration, the following is sufficient:
  * @code
- * $databases['default']['default'] = array(
+ * $settings['databases']['default']['default'] = array(
  *   'driver' => 'mysql',
  *   'database' => 'databasename',
  *   'username' => 'username',
@@ -171,7 +171,7 @@
  * variable, and to reduce the database connection timeout to 5 seconds:
  *
  * @code
- * $databases['default']['default'] = array(
+ * $settings['databases']['default']['default'] = array(
  *   'init_commands' => array(
  *     'big_selects' => 'SET SQL_BIG_SELECTS=1',
  *   ),
@@ -190,7 +190,7 @@
  *
  * Database configuration format:
  * @code
- *   $databases['default']['default'] = array(
+ *   $settings['databases']['default']['default'] = array(
  *     'driver' => 'mysql',
  *     'database' => 'databasename',
  *     'username' => 'username',
@@ -198,7 +198,7 @@
  *     'host' => 'localhost',
  *     'prefix' => '',
  *   );
- *   $databases['default']['default'] = array(
+ *   $settings['databases']['default']['default'] = array(
  *     'driver' => 'pgsql',
  *     'database' => 'databasename',
  *     'username' => 'username',
@@ -206,13 +206,13 @@
  *     'host' => 'localhost',
  *     'prefix' => '',
  *   );
- *   $databases['default']['default'] = array(
+ *   $settings['databases']['default']['default'] = array(
  *     'driver' => 'sqlite',
  *     'database' => '/path/to/databasefilename',
  *   );
  * @endcode
  */
-$databases = array();
+$settings['databases'] = array();
 
 /**
  * Salt for one-time login links and cancel links, form tokens, etc.
