diff --git a/core/modules/node/config/views.view.frontpage.yml b/core/modules/node/config/views.view.frontpage.yml
index 8ef5676..ca1516c 100644
--- a/core/modules/node/config/views.view.frontpage.yml
+++ b/core/modules/node/config/views.view.frontpage.yml
@@ -125,28 +125,6 @@ display:
     display_title: Master
     id: default
     position: {  }
-  feed:
-    display_options:
-      defaults:
-        sitename_title: '0'
-        title: '0'
-      display_description: 'Display the default content feed.'
-      displays:
-        default: default
-        page: page
-      pager:
-        type: some
-      path: rss.xml
-      row:
-        type: node_rss
-      sitename_title: '1'
-      style:
-        type: rss
-      title: ''
-    display_plugin: feed
-    display_title: Feed
-    id: feed
-    position: {  }
   page:
     display_options:
       path: node
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeRSSContentTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeRSSContentTest.php
index 4e40a2e..e82ebcd 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeRSSContentTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeRSSContentTest.php
@@ -21,7 +21,7 @@ class NodeRSSContentTest extends NodeTestBase {
    *
    * @var array
    */
-  public static $modules = array('node_test', 'views');
+  public static $modules = array('node_test');
 
   public static function getInfo() {
     return array(
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 0d9030b..860d334 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1955,6 +1955,15 @@ function node_menu() {
     'access callback' => '_node_add_access',
     'file' => 'node.pages.inc',
   );
+  $items['rss.xml'] = array(
+    'title' => 'RSS feed',
+    'page callback' => 'node_feed',
+    // Pass a FALSE and array argument to ensure that additional path components
+    // are not passed to node_feed().
+    'page arguments' => array(FALSE, array()),
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
   $items['node/add/%node_type'] = array(
     'title callback' => 'node_type_get_clean_name',
     'title arguments' => array(2),
@@ -2444,6 +2453,99 @@ function node_block_list_alter(&$blocks) {
 }
 
 /**
+ * Page callback: Generates and prints an RSS feed.
+ *
+ * Generates an RSS feed from an array of node IDs, and prints it with an HTTP
+ * header, with Content Type set to RSS/XML.
+ *
+ * @param $nids
+ *   (optional) An array of node IDs (nid). Defaults to FALSE so empty feeds can
+ *   be generated with passing an empty array, if no items are to be added
+ *   to the feed.
+ * @param $channel
+ *   (optional) An associative array containing 'title', 'link', 'description',
+ *   and other keys, to be parsed by format_rss_channel() and
+ *   format_xml_elements(). A list of channel elements can be found at the
+ *   @link http://cyber.law.harvard.edu/rss/rss.html RSS 2.0 Specification. @endlink
+ *   The link should be an absolute URL.
+ *
+ * @return Symfony\Component\HttpFoundation\Response
+ *   A response object.
+ *
+ * @see node_menu()
+ */
+function node_feed($nids = FALSE, $channel = array()) {
+  global $base_url;
+  $language_content = language(LANGUAGE_TYPE_CONTENT);
+  $rss_config = config('system.rss');
+
+  if ($nids === FALSE) {
+    $nids = db_select('node', 'n')
+      ->fields('n', array('nid', 'created'))
+      ->condition('n.promote', 1)
+      ->condition('n.status', 1)
+      ->orderBy('n.created', 'DESC')
+      ->range(0, $rss_config->get('items.limit'))
+      ->addTag('node_access')
+      ->execute()
+      ->fetchCol();
+  }
+
+  $item_length = $rss_config->get('items.view_mode');
+  $namespaces = array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/');
+  $teaser = ($item_length == 'teaser');
+
+  // Load all nodes to be rendered.
+  $nodes = node_load_multiple($nids);
+  $items = '';
+  foreach ($nodes as $node) {
+    $item_text = '';
+
+    $node->link = url("node/$node->nid", array('absolute' => TRUE));
+    $node->rss_namespaces = array();
+    $node->rss_elements = array(
+      array('key' => 'pubDate', 'value' => gmdate('r', $node->created)),
+      array('key' => 'dc:creator', 'value' => $node->name),
+      array('key' => 'guid', 'value' => $node->nid . ' at ' . $base_url, 'attributes' => array('isPermaLink' => 'false'))
+    );
+
+    // The node gets built and modules add to or modify $node->rss_elements
+    // and $node->rss_namespaces.
+    $build = node_view($node, 'rss');
+    unset($build['#theme']);
+
+    if (!empty($node->rss_namespaces)) {
+      $namespaces = array_merge($namespaces, $node->rss_namespaces);
+    }
+
+    if ($item_length != 'title') {
+      // We render node contents and force links to be last.
+      $build['links']['#weight'] = 1000;
+      $item_text .= drupal_render($build);
+    }
+
+    $items .= format_rss_item($node->label(), $node->link, $item_text, $node->rss_elements);
+  }
+
+  $channel_defaults = array(
+    'version'     => '2.0',
+    'title'       => config('system.site')->get('name'),
+    'link'        => $base_url,
+    'description' => $rss_config->get('channel.description'),
+    'language'    => $language_content->langcode
+  );
+  $channel_extras = array_diff_key($channel, $channel_defaults);
+  $channel = array_merge($channel_defaults, $channel);
+
+  $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
+  $output .= "<rss version=\"" . $channel["version"] . "\" xml:base=\"" . $base_url . "\" " . new Attribute($namespaces) . ">\n";
+  $output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language'], $channel_extras);
+  $output .= "</rss>\n";
+
+  return new Response($output, 200, array('Content-Type' =>  'application/rss+xml; charset=utf-8'));
+}
+
+/**
  * Constructs a drupal_render() style array from an array of loaded nodes.
  *
  * @param $nodes
